Question

Il est pas que cela n'a pas de sens, mais il fonctionne à 99% maladroits du temps.

Souvent dans des rectangles graphiques 2D sont initialisés, stocké et manipulé comme une paire de points. Dans aucune langue particulière,

class Rect:
   p1, p2: point

Il est plus logique de définir un rectangle comme deux valeurs x et y deux valeurs, comme ceci:

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

Avec deux points, si, à un endroit dans le code source que vous voulez utiliser la valeur y de la partie supérieure, vous auriez à dire rect.p1.y (hmmm, arrêter et penser, est-il ou p1 p2), mais avec les quatre valeurs en tant que membres de données simples, il est clair et direct: rect.ytop (pas la pensée nécessaire) l'utilisation de deux points moyens pour faire face à la verticale, vous devez enchevêtrement l'horizontale; il y a une relation entre les éléments étrangers indepenent.

Comment cette idée de deux points viennent et pourquoi faut-il persiste? At-il un certain avantage sur les coordonnées nues x et y?

AJOUTÉE NOTE: Cette question est dans le contexte des rectangles alignés X-Y, comme dans les gestionnaires de fenêtres et des boîtes à outils GUI, pas dans le contexte des formes arbitraires dans le dessin et la peinture app

.
Était-ce utile?

La solution

Avez-vous considéré qu'il est moins sujette aux erreurs?

Si vous utilisez (Point1, Point2) il est alors très clair ce que vous spécifiez. Si vous fournissez des 2 points, l'erreur est possible que l'utilisateur a mélangé leur x et y lors de la construction des points que l'ordre des points n'a pas d'importance.

Si vous fournissez 4 entiers, alors si quelqu'un ne prête pas attention, ils peuvent fournir (x1, x2, y1, y2) lorsque vous vouliez (x1, y1, x2, y2) ou vice versa. En outre, certaines API telles que la structure de WCF Rect définissent un rectangle comme (x, y, largeur, hauteur) qui pourrait alors provoquer une confusion sur ce (1, 2, 3, 4) des moyens. Est-ce que (x, y, w, h) et (x1, y1, x2, y2) ou (x1, x2, y1, y2)?

Dans l'ensemble, (Point1, Point2) semble un peu plus sûr de moi.

Autres conseils

I toujours aimé définissant un rectangle en tant que point + largeur et la hauteur, où le point est le coin supérieur gauche du rectangle.

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

Et puis ajoutez toutes les méthodes dont vous avez besoin pour aller chercher les autres mesures. Tout comme la version Java

En fait, un rectagle est pas défini par 2 points. Un rectangle ne peut être défini par deux points si elle est parallèle aux axes.

Il y a plusieurs façons de représenter des rectangles qui sont parallèles aux axes:

  1. Deux points opposés en diagonale
  2. Un point d'angle, hauteur et largeur
  3. point central, mi-hauteur et la largeur (rare, mais parfois utile).
  4. Comme deux coordonnées X et deux coordonnées Y

Pour (1), de nombreuses bibliothèques utilisent une convention pour déterminer quels deux points sont utilisés -. TopLeft et bottomRight, par exemple

Le choix de la représentation peut être entraîné par l'objectif initial de la définition du rectangle, mais j'imagine que souvent arbitraire . Les représentations sont équivalentes dans les informations qu'ils transportent. Ils ne diffèrent cependant dans la facilité avec laquelle les propriétés du rectangle peuvent être calculées et la commodité à laquelle les opérations peuvent être effectuées sur le reectangle.

Avantages de la définition (1) sur les autres comprennent:

  • Cohérence de l'API avec d'autres polygones, lignes, etc.
  • topLeft, bottomRight peut être transmis à toute méthode qui accepte les points
  • Méthodes de classe Point peut être appelé topLeft, bottomRight
  • La plupart des propriétés peuvent être dérivées facilement, par exemple. bottomLeft, topRight, largeur, hauteur, au centre, une longueur diagonale, etc.

Eh bien p1: Point et p2: Point sont chacun vont avoir deux int coordonnées en eux de toute façon, ne pas le montant de votre classe à la même chose?

Et si vous stockez ces deux points comme des objets Point de première classe, ne vous obtenez un peu plus d'utilité d'eux? Dans la plupart des systèmes de coordonnées graphiques que je connais, les points sont sous-classés de cette façon de créer une hiérarchie d'objets. point -> circle -> ellipse etc.

Donc, si vous faites un objet qui n'utilise pas la classe Point, vous avez divorcé cet objet du reste de la hiérarchie des classes.

Voilà pourquoi je aime la TRect de Delphi. Il est défini comme un enregistrement variant (struct union en C-parler) qui peut être interprétée comme un TopLeft et un point de BottomRight, ou Haut, Gauche, entiers Bas et à droite, si elle est plus pratique pour le moment.

Certes, si vous définissez votre rectangle comme:

class Rect
{
    Point bottomLeft;
    Point topRight;
}

alors vous savez immédiatement quel point est qui.

Encore mieux serait d'ajouter des propriétés supplémentaires qui vous a permis de manipuler le rectangle dans lequel des moyens toujours vous avez besoin pour votre application. Ceux-ci seraient tout simplement mettre à jour la structure de données sous-jacentes.

En ajoutant une transformation à la forme que vous pouvez orienter votre rectangle comme vous le souhaitez. Vous auriez encore besoin d'un axe aligné boîte englobante pour accepter / rejeter rapidement les contrôles:)

Cependant, si votre modèle permet des rectangles dans une orientation sans appliquer une transformation puis « en bas à gauche » et « en haut à droite » ont pas de sens, ce qui nous ramène à « p1 » et « p2 » (ou équivalent).

i pense qu'il est plus logique pour un rectangle à être représenté par un x et y et un point de mesure; vous pourriez même faire le point de l'emplacement du centre du rectangle de sorte qu'il serait indépendant de rotation

mais il était probablement plus facile à coder comme deux points!

Je ne l'aime pas parce que nous avons jeté un degré potentiel de liberté, ce qui permet essentiellement d'une rotation arbitraire. Un rectangle 2D général a cinq inconnues (degrés de liberté). On pourrait les définir comme les coordonnées d'un point, les longueurs des deux côtés qui forment un sommet avec ce point, et l'angle de l'horizontale de la première ligne (l'autre étant supposé avoir un angle supérieur à 90 degrés). Un nombre infini d'autres possibilités pourrait également être utilisé, mais il y a cinq quantités indépendantes qui doivent être spécifiés. Certains choix conduiront à l'algèbre plus facile que d'autres, en fonction de ce qui est fait avec eux.

ISNT exactement la même chose que de 2 points? Comment est-ce routines difficiles ... la plupart des points de dessin ont besoin, pas séparer les composants x / y.

Définition des rectangles comme paires de points vous permet de réutiliser le point comme un sommet pour une autre forme. Juste une pensée ...

Je crois qu'il est surtout d'établir une uniformité entre toutes les formes primitives.

Bien sûr, vous pouvez définir un rectangle de plusieurs façons différentes, mais comment définissez-vous un triangle, ou une étoile ou un cercle d'une manière qui peut utiliser des structures de données similaires?

Tous les polygones peuvent être définis par leurs points, avec un peu de logique pour déterminer ce qu'il faut faire avec les points.

bibliothèques graphiques fonctionnent principalement sur ces polygones en termes de sommets et d'arêtes, de sorte que les points et les lignes entre eux, tous les calculs fonctionnent sur ces deux caractéristiques, bien que et facettes, mais lui-même est juste en fonction des bords.

en deux dimensions, le stockage d'un rectangle en deux points est plus clair que la définition d'un angle particulier, et une largeur et une hauteur. - envisager la largeur ou la hauteur négative, ou les calculs nécessaires pour déterminer chaque option de l'autre

Effectuer des rotations sur un rectangle défini par les points est également beaucoup plus simple que celle qui est définie avec un point ainsi que la largeur et la hauteur.

J'attendre l'encapsulation de faire ce pas important de différenciation en tant qu'utilisateur de la classe.

Un rectangle doit être défini comme trois points pour être bien défini en 3 dimensions. Je ne suis pas tout à fait sûr de l'exigence de définir un rectangle en 4 dimensions ou plus.

Il est tout à fait arbitraire. Vous avez besoin de quatre éléments d'information pour dessiner un rectangle. Le concepteur bibliothèque (s) a décidé de le représenter avec deux points (chacune avec une coordonnées x-y), mais aurait facilement pu le faire avec x / y / w / h ou haut / bas / gauche / droite.

Je suppose que la vraie question est de l'OP: pourquoi est ce choix particulier fait

Le choix des paramètres ne sont importants pour les concepteurs / codeurs bas niveau.

Les utilisateurs de haut niveau ne doivent penser à:

  • IsPointInRect
  • Espace
  • Intersection (ou détourage)
  • HasOverlap (comme Intersection.Area> 0)
  • Union (devient une liste des rectangles)
  • Soustraction (une liste de rectangles qui représentent le même ensemble de points qui se trouve dans rect A mais pas dans B rect)
  • Transformation
    • Les changements dans X et Y
    • Rotation (0, 90, 180, 270)
    • Mise à l'échelle en X et Y (voir la note)
  • syntaxe simple pour les propriétés Xmin, Xmax, Ymin, Ymax, largeur, hauteur afin que l'utilisateur n'a pas besoin de connaître le choix exact des paramètres.

Remarque: Afin de minimiser la perte de précision lors de mise à l'échelle de transformation, il est parfois approprié de mettre en œuvre une deuxième classe Rect qui utilise les coordonnées à virgule flottante, de sorte que les résultats intermédiaires peuvent être stockés avec précision dans une séquence de transformations et seulement arrondi au nombre entier dans la dernière étape.

Comme @Steven dit, je pense qu'il devrait être en termes d'un (x, y) le point, et (w, h) vecteur de taille. En effet, il est facile de tomber dans une ambiguïté. Supposons que vous ayez rempli les éléments suivants en rectangle à partir du point (0,0).

  012
0 XXX
1 XXX
2 XXX

Il est clair qu'il est, la hauteur sont la largeur (3,3), mais qu'est-ce deuxième point est? Est-il (2,2) ou (3,3)?

Cette ambiguïté peut causer toutes sortes de problèmes.

Je l'ai appris il y a des années de dure qu'il est préférable de penser à coordonnées graphiques comme les lignes entre les pixels, non pas comme les lignes les pixels sont sur . De cette façon, il n'y a pas d'ambiguïté.

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

On peut définir à la fois Pb et Pc ainsi:

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

et

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

Il n'y a donc pas besoin de définir les quatre points en raison de la symétrie

Licencié sous: CC-BY-SA avec attribution
scroll top