Qual è l'idea alla base della definizione dei rettangoli con due punti? [chiuso]

14

Non è che questo non abbia senso, ma funziona solo per il 99% delle volte.

Spesso i rettangoli grafici 2D sono inizializzati, memorizzati e manipolati come una coppia di punti. In nessuna lingua particolare,

class Rect:
   p1, p2: point

Ha più senso definire un rettangolo come due valori x e due valori y, come questo:

class Rect
   xleft, xright: int
   ytop, ybottom: int

Con due punti, se in qualche punto del codice sorgente vuoi usare il valore y del top, dovresti dire rect.p1.y (hmmm, fermati e pensa, è p1 o p2) ma con i quattro valori come semplici membri di dati, è chiaro e diretto: rect.ytop (nessun pensiero richiesto!) L'uso di due punti significa che nel trattare con la verticale, devi aggrovigliare l'orizzontale; c'è una relazione estranea tra elementi indipendenti.

Come è nata questa idea in due punti e perché persiste? Ha qualche vantaggio rispetto alle coordinate xey y?

NOTA AGGIUNTIVA: questa domanda è nel contesto dei rettangoli allineati X-Y, come nei gestori di finestre e nei toolkit della GUI, non nel contesto di forme arbitrarie nell'app di disegno e pittura.

    
posta DarenW 30.11.2010 - 21:47
fonte

16 risposte

8

Hai considerato che è meno incline agli errori?

Se usi (Punto1, Punto2), allora molto cancella ciò che stai specificando. Se fornisci 2 punti, l'unico errore possibile è che l'utente ha mescolato i suoi x e y quando costruisce i punti in quanto l'ordine dei punti non ha importanza.

Se fornisci 4 numeri interi, se qualcuno non presta attenzione, può fornire (x1, x2, y1, y2) quando vuoi (x1, y1, x2, y2) o viceversa. Inoltre, alcune API come la struttura Rect di WCF definiscono un rettangolo come (x, y, larghezza, altezza) che potrebbero quindi causare confusione su cosa (1, 2, 3, 4) significa. È quello (x, y, w, h) o (x1, y1, x2, y2) o (x1, x2, y1, y2)?

Tutto sommato, (Punto1, Punto2) sembra un po 'più sicuro per me.

    
risposta data 01.12.2010 - 02:43
fonte
9

Mi è sempre piaciuto definire un rettangolo come un punto + larghezza e altezza, dove il punto è l'angolo superiore sinistro del rettangolo.

class Rect {
  float x, y;
  float width, height;
}

Quindi aggiungi tutti i metodi necessari per recuperare le altre metriche. Come la versione di Java

    
risposta data 30.11.2010 - 23:56
fonte
7

In realtà, un rettangolo non è definito da 2 punti. Un rettangolo può essere definito solo da due punti se è parallelo agli assi.

Esistono diversi modi per rappresentare rettangoli paralleli agli assi:

  1. Due punti diagonalmente opposti
  2. Un punto d'angolo, altezza e larghezza
  3. Punto centrale, metà altezza e larghezza (non comune, ma a volte utile).
  4. Come due coordinate X e due coordinate Y

Per (1), molte librerie usano una convenzione per determinare quali due punti sono usati - topLeft e bottomRight, per esempio.

La scelta della rappresentazione può essere guidata dallo scopo originale della definizione del rettangolo, ma immagino che sia spesso arbitrario . Le rappresentazioni sono equivalenti nelle informazioni che portano. Tuttavia, differiscono nella facilità con cui possono essere calcolate le proprietà del rettangolo e nella praticità con cui è possibile eseguire le operazioni sul reectangle.

I vantaggi della definizione (1) rispetto ad altri includono:

  • Coerenza dell'API con altri poligoni, linee ecc.
  • topLeft, bottomRight può essere passato a qualsiasi metodo che accetti punti
  • I metodi della classe Point possono essere richiamati in cimaLeft, bottomRight
  • La maggior parte delle proprietà può essere derivata facilmente, ad es. bottomLeft, topRight, width, height, center, diagonal length, ecc.
risposta data 01.12.2010 - 00:39
fonte
6

Bene p1: Point e p2: Point avranno ciascuna due int coordinate in loro comunque, quindi la tua classe non equivale alla stessa cosa?

E se si memorizzano questi due punti come oggetti di prima classe Point , non si ottiene un po 'più di utilità da essi? Nella maggior parte dei sistemi di coordinate grafiche che conosco, i punti sono sottoclassi in questo modo per creare una gerarchia di oggetti: point -> circle -> ellipse e così via.

Quindi, se crei un oggetto che non usa la classe Point , hai separato l'oggetto dal resto della gerarchia di classi.

    
risposta data 30.11.2010 - 21:52
fonte
5

Questo è il motivo per cui mi piace TRect di Delphi. È definito come un record variante (struttura unione in linguaggio C) che può essere interpretato come un punto TopLeft e un punto BottomRight, o numeri interi Top, Left, Bottom e Right, a seconda di quale sia più conveniente al momento.

    
risposta data 30.11.2010 - 22:33
fonte
4

Sicuramente se definisci il tuo rettangolo come:

class Rect
{
    Point bottomLeft;
    Point topRight;
}

allora sai subito quale punto è.

Ancora meglio sarebbe aggiungere proprietà extra che ti permettano di manipolare il rettangolo in cui hai sempre avuto bisogno della tua applicazione. Questi semplicemente aggiornerebbero la struttura dati sottostante.

Aggiungendo una trasformazione alla forma puoi orientare il tuo rettangolo in qualsiasi modo desideri. Avresti ancora bisogno di un riquadro di delimitazione allineato all'asse per controlli rapidi di accettazione / rifiuto:)

Tuttavia, se il tuo modello consente rettangoli con qualsiasi orientamento senza applicare una trasformazione, "in basso a sinistra" e "in alto a destra" non hanno alcun significato, il che riconduce a "p1" e "p2" (o qualcosa di equivalente).

    
risposta data 01.12.2010 - 00:07
fonte
2

Penso che abbia più senso che un rettangolo sia rappresentato da un'estensione e un punto xey; potresti perfino fare in modo che la posizione punti al centro del rettangolo in modo che sia indipendente dalla rotazione

ma probabilmente era più semplice codificarlo come due punti!

    
risposta data 30.11.2010 - 21:56
fonte
2

Non mi piace perché abbiamo eliminato un potenziale grado di libertà, che essenzialmente consente una rotazione arbitraria. Un rettangolo 2D generale ha cinque incognite (gradi di libertà). Potremmo specificarli come le coordinate di un punto, le lunghezze dei due lati che formano un vertice con questo punto e l'angolo dall'orizzontale della prima linea (l'altro è assunto con un angolo di 90 gradi maggiore). Potrebbe anche essere usato un numero infinito di altre possibilità, ma ci sono cinque quantità indipendenti che devono essere specificate. Alcune scelte porteranno ad un'algebra più semplice di altre, a seconda di ciò che viene fatto con loro.

    
risposta data 01.12.2010 - 01:21
fonte
1

Non è esattamente la stessa cosa di 2 punti? Com'è difficile ... la maggior parte delle routine di disegno richiedono punti, non componenti x / y separati.

    
risposta data 30.11.2010 - 21:54
fonte
1

La definizione di rettangoli come coppie di punti consente di riutilizzare il punto come vertice per un'altra forma. Solo un pensiero ...

    
risposta data 30.11.2010 - 22:53
fonte
1

Credo che sia principalmente per stabilire l'uniformità tra tutti i primitivi di forma.

Certo, puoi definire il rettangolo in molti modi diversi, ma come puoi definire un triangolo, una stella o un cerchio in un modo che possa utilizzare strutture di dati simili?

Tutti i poligoni possono essere definiti dai loro punti, con una piccola quantità di logica per determinare cosa fare con i punti.

Le librerie grafiche operano principalmente su questi poligoni in termini di vertici e spigoli, quindi i punti e le linee tra di loro, tutti i calcoli funzionano su queste due funzioni, bene e sfaccettature, ma è di per sé solo una funzione dei bordi.

    
risposta data 30.11.2010 - 22:56
fonte
1

Nelle due dimensioni, la memorizzazione di un rettangolo come due punti è più chiara della definizione di un particolare angolo e di una larghezza e altezza - considera la larghezza o l'altezza negativa o i calcoli richiesti per determinare ciascuna opzione dall'altra.

L'esecuzione di rotazioni su un rettangolo definito da punti è anche molto più semplice di una definita con un punto più larghezza e altezza.

Mi aspetto che l'incapsulamento non renda importante questa differenziazione come utente della classe.

Un rettangolo dovrebbe essere definito come tre punti per essere ben definito in 3 dimensioni. Non sono completamente sicuro del requisito per la definizione di un rettangolo in 4 o più dimensioni.

    
risposta data 01.12.2010 - 00:49
fonte
1

È completamente arbitrario. Hai bisogno di quattro informazioni per disegnare un rettangolo. Il progettista della biblioteca ha deciso di rappresentarlo con due punti (ognuno con una coordinata x-y), ma potrebbe facilmente averlo fatto con x / y / w / h o sopra / sotto / sinistra / destra.

Suppongo che la vera domanda dell'OP sia: perché è stata fatta questa particolare scelta?

    
risposta data 01.12.2010 - 03:38
fonte
1

La scelta dei parametri è importante solo per i designer / programmatori di basso livello.

Gli utenti di alto livello devono solo riflettere:

  • IsPointInRect
  • Area
  • Intersezione (o ritaglio)
  • HasOverlap (uguale a Intersection.Area > 0)
  • Unione (diventa un elenco di rettangoli)
  • Sottrazione (un elenco di rettangoli che rappresentano lo stesso set di punti che si trova in rect A ma non in rect B)
  • Trasforma
    • Cambia in X e Y
    • Rotazione (0, 90, 180, 270)
    • Ridimensionamento in X e Y (vedi nota)
  • Sintassi semplice per le proprietà Xmin, Xmax, Ymin, Ymax, Width, Height in modo che l'utente non abbia bisogno di conoscere la scelta esatta dei parametri.

Nota: al fine di minimizzare la perdita di precisione durante la trasformazione di ridimensionamento, a volte è opportuno implementare una seconda classe Rect che utilizza le coordinate a virgola mobile, in modo che i risultati intermedi possano essere archiviati accuratamente in una sequenza di trasformazioni e solo arrotondato al numero intero nell'ultimo passaggio.

    
risposta data 01.12.2010 - 07:35
fonte
0

Come dice @Steven, penso che dovrebbe essere in termini di un punto (x, y) e un vettore di dimensioni (w, h). Questo perché è facile cadere in un'ambiguità. Supponiamo di avere il seguente rettangolo compilato che inizia al punto (0,0).

  012
0 XXX
1 XXX
2 XXX

Chiaramente è larghezza, l'altezza è (3,3), ma qual è il secondo punto? È (2,2) o (3,3)?

Questa ambiguità può causare tutti i tipi di problemi.

Ho imparato a mio agio anni fa che è meglio pensare alle coordinate grafiche come le linee tra i pixel, non come le linee dei pixel su . In questo modo non c'è ambiguità.

    
risposta data 30.11.2010 - 22:29
fonte
0
Pa(x,y)*-----------------------------------*Pb(x,y)
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
Pc(x,y)*-----------------------------------*Pd(x,y)

Possiamo definire sia Pb che amp; Pc quindi:

Pb(Pd(x),Pa(y))

e

Pc(Pa(x),Pd(y))

Quindi non è necessario definire tutti e quattro i punti a causa della simmetria

    
risposta data 01.12.2010 - 01:32
fonte

Leggi altre domande sui tag