Domanda

Non è che questo non ha senso, ma semplicemente funziona imbarazzante il 99% del tempo.

Spesso in 2D rettangoli di grafica vengono inizializzati, immagazzinato e manipolato come un paio di punti. In nessun particolare linguaggio,

class Rect:
   p1, p2: point

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

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

Con due punti, se a un certo posto nel codice sorgente che si desidera utilizzare il valore y della parte superiore, che avrebbe dovuto dire rect.p1.y (hmmm, fermarsi a riflettere, è P1 o p2), ma con i quattro valori come membri di dati semplici, è chiaro e diretto:! rect.ytop (nessun pensiero richiesto) l'uso di due punti significa che nel trattare con la verticale, si deve groviglio orizzontale; c'è una relazione tra elementi estranei indepenent.

Come è nata questa idea a due punti arrivati ??a tanto e perché persiste? Ha a qualche beneficio su coordinate X e Y nude?

Nota aggiunta: Questa domanda è nel contesto di X-Y rettangoli allineati, come ad esempio in finestre manager e toolkit GUI, non nel contesto di forme arbitrarie di disegno e pittura app

.
È stato utile?

Soluzione

Avete considerato che è meno soggetto ad errori?

Se si utilizza (Point1, Point2) è allora molto chiaro che cosa si specifica. Se si forniscono 2 punti, allora l'errore è possibile solo che l'utente ha mescolato il loro X e Y nel costruire i punti come l'ordine dei punti non importa.

Se si fornisce 4 interi, quindi se qualcuno non sta prestando attenzione, possono fornire (x1, x2, Y1, Y2) quando si voleva (x1, y1, x2, y2) o viceversa. Inoltre, alcune API come Rect struttura di WCF definiscono un rettangolo come (x, y, larghezza, altezza) in modo da forzare confusione su ciò 1, 2, 3, 4) mezzi (. È che (x, y, w, h) o (x1, y1, x2, y2) o (x1, x2, Y1, Y2)?

Tutto sommato, (Point1, Point2) sembra un po 'più sicuro di me.

Altri suggerimenti

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

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

e quindi aggiungere qualsiasi metodo è necessario prendere le altre metriche. Come la versione Java

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

Esistono diversi modi per rappresentare rettangoli che sono paralleli agli assi:

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

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

La scelta della rappresentazione può essere guidato dallo scopo originale della definizione rettangolare, ma immagino che spesso arbitraria . Le rappresentazioni sono equivalenti nelle informazioni che portano. Essi, tuttavia, si differenziano per la facilità con cui possono essere calcolati proprietà del rettangolo e la comodità con cui operazioni possono essere eseguite sul reectangle.

I vantaggi di definizione (1) sugli altri comprendono:

  • La coerenza di API con altri poligoni, linee ecc.
  • topLeft, bottomRight può essere passato a qualsiasi metodo che accetta punti
  • I metodi di classe Point può essere chiamato su topLeft, bottomRight
  • La maggior parte delle proprietà può essere derivata facilmente, per esempio. bottomLeft, topRight, larghezza, altezza, centro, lunghezza diagonale, ecc.

Bene p1: Point e p2: Point sono ciascuno avranno due int coordinate in loro comunque, quindi non l'importo classe per la stessa cosa?

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

Quindi, se si effettua un oggetto che non utilizza la classe Point, hai divorziato quell'oggetto dal resto della gerarchia delle classi.

Questo è il motivo per cui mi piace TRect di Delphi. E 'definito come un record di variante (struct union in C-parlare) che può essere interpretata sia come TopLeft e un punto BottomRight, o superiore, sinistro, inferiore e interi destra, a seconda di quale è più conveniente al momento.

Sicuramente se si definisce il vostro rettangolo come:

class Rect
{
    Point bottomLeft;
    Point topRight;
}

poi si sa subito che punto è che.

Ancora meglio sarebbe quello di aggiungere proprietà in più che ha permesso di manipolare il rettangolo in cui mai modi il necessario per la vostra applicazione. Questi sarebbero semplicemente aggiornare la struttura di dati sottostante.

Con l'aggiunta di una trasformazione della forma è possibile orientare il vostro rettangolo in qualsiasi modo si desidera. Saresti ancora bisogno di un asse allineato dell'imballo per rapida accettare / rifiutare assegni:)

Tuttavia, se il modello permette rettangoli in qualsiasi orientamento senza applicare una trasformazione poi "in basso a sinistra" e "in alto a destra" non hanno alcun significato, che riconduce a "P1" e "P2" (o qualcosa di equivalente).

Credo ha più senso per un rettangolo per essere rappresentata da un xe y misura e un punto; Si potrebbe anche fare il punto posizione al centro del rettangolo quindi sarebbe indipendenti di rotazione

, ma probabilmente era più facile da codice come due punti!

Non mi piace perché abbiamo buttato fuori un potenziale grado di libertà, che permette in sostanza di una rotazione arbitraria. Un rettangolo generale 2D ha cinque incognite (gradi di libertà). potremmo specificare le coordinate di un punto, le lunghezze delle due parti che formano un vertice con questo punto, e l'angolo rispetto all'orizzontale della prima linea (l'altro essere presume di avere un angolo di 90 gradi maggiore). Un numero infinito di altre possibilità potrebbe essere utilizzata, ma ci sono cinque grandezze indipendenti che devono essere specificati. Alcune scelte porteranno a facilitare l'algebra di altri, a seconda di ciò che viene fatto con loro.

isnt che esattamente la stessa cosa di 2 punti? Come è imbarazzante ... la maggior parte delle routine di disegno richiedono punti, non separare x / y componenti.

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

Credo che sia soprattutto di stabilire uniformità tra tutte le primitive di forma.

Certo che si può definire rettangolo in molti modi diversi, ma come si fa a definire un triangolo, o una stella, o di un cerchio in un modo che può utilizzare le strutture dati simili?

Tutti i poligoni possono essere definiti dai loro punti, con un breve lasso di logica per determinare che cosa fare con i punti.

librerie grafiche operano principalmente su questi poligoni in termini di vertici e spigoli, così punti e le linee tra di loro, tutti i calcoli lavorano su queste due caratteristiche, bene che e sfaccettature, ma che si è solo una funzione dei bordi.

In due dimensioni, memorizzando un rettangolo come due punti è più chiaro di definire un determinato angolo e una larghezza e altezza -. Considerano larghezza o altezza negativo, oppure i calcoli necessari per determinare ciascuna opzione dall'altra

Esecuzione rotazioni su un rettangolo definito da punti è anche molto più semplice di quello definito con un punto di forza larghezza e altezza.

mi aspetto incapsulamento per rendere questa differenziazione poco importante come utente della classe.

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

E 'del tutto arbitraria. Avete bisogno di quattro pezzi di informazioni per disegnare un rettangolo. Il progettista libreria (s) ha deciso di rappresentarlo con due punti (ognuna con un x-coordinata y), ma avrebbe potuto facilmente fatto con x / y / w / h o alto / basso / sinistra / destra.

suppongo vera domanda del PO è: perché è stata questa particolare scelta fatta

La scelta dei parametri sono importanti solo per i bassi livelli progettisti / programmatori.

Gli utenti di alto livello devono solo pensare a:

  • IsPointInRect
  • Area
  • Intersezione (o path)
  • HasOverlap (lo stesso Intersection.Area> 0)
  • Union (diventa un elenco di rettangoli)
  • sottrazione (una lista di rettangoli che rappresentano lo stesso set point che è in rect A ma non in rect B)
  • Trasforma
    • Spostamenti in X e Y
    • rotazione (0, 90, 180, 270)
    • Scaling in X e Y (vedi nota)
  • sintassi semplice per le proprietà Xmin, Xmax, Ymin, Ymax, larghezza, altezza in modo che l'utente non ha bisogno di conoscere l'esatta scelta dei parametri.

Nota: Al fine di minimizzare la perdita di precisione di scalatura trasformare, a volte è opportuno attuare una seconda classe Rect che coordinate usi a virgola mobile, in modo che i risultati intermedi possono essere memorizzati con precisione in una sequenza di trasformazioni e solo arrotondato al numero intero nell'ultimo passaggio.

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

  012
0 XXX
1 XXX
2 XXX

Chiaramente è larghezza, altezza sono (3,3), ma ciò è che è secondo punto? E '(2,2) o (3,3)?

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

ho imparato il senso duri anni fa, che è meglio pensare a coordinate grafiche come le linee di tra i pixel, non come le linee dei pixel sono su . In questo modo non c'è ambiguità.

Pa(x,y)*-----------------------------------*Pb(x,y)
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
Pc(x,y)*-----------------------------------*Pd(x,y)

Possiamo definire sia Pb & Pc in tal modo:

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

e

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

Quindi non v'è alcuna necessità di definire tutti i quattro punti a causa di simmetria

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top