Ce n'est pas que cela n'a pas de sens, mais cela fonctionne simplement 99% du temps.
Souvent, dans les graphiques 2D, les rectangles sont initialisés, stockés et manipulés 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 deux valeurs y, comme ceci:
class Rect
xleft, xright: int
ytop, ybottom: int
Avec deux points, si à un endroit du code source vous voulez utiliser la valeur y du haut, vous devez dire rect.p1.y (hmmm, arrêtez et pensez, est-ce p1 ou p2) mais avec les quatre valeurs en tant que membres de données simples, c'est clair et direct: rect.ytop (aucune réflexion requise!) L'utilisation de deux points signifie qu'en traitant avec la verticale, vous devez emmêler l'horizontale; il y a une relation étrangère entre des éléments indépendants.
Comment est née cette idée en deux points et pourquoi persiste-t-elle? At-il un avantage sur les coordonnées nues x et y?
NOTE AJOUTÉE: Cette question est dans le contexte des rectangles alignés XY, comme dans les gestionnaires de fenêtres et les boîtes à outils GUI, pas dans le contexte des formes arbitraires dans l'application de dessin et de peinture.
Réponses:
Avez-vous considéré qu'il est moins sujet aux erreurs?
Si vous utilisez (Point1, Point2), il est alors très clair ce que vous spécifiez. Si vous fournissez 2 points, la seule erreur possible est que l'utilisateur a mélangé ses x et y lors de la construction des points car l'ordre des points n'a pas d'importance.
Si vous fournissez 4 entiers, alors si quelqu'un ne fait pas attention, il peut fournir (x1, x2, y1, y2) quand vous le souhaitez (x1, y1, x2, y2) ou vice versa. De plus, certaines API telles que la structure Rect de WCF définissent un rectangle comme (x, y, largeur, hauteur), ce qui pourrait alors créer de la confusion sur ce que (1, 2, 3, 4) signifie. Est-ce (x, y, w, h) ou (x1, y1, x2, y2) ou (x1, x2, y1, y2)?
Dans l'ensemble, (Point1, Point2) me semble un peu plus sûr.
la source
J'ai toujours aimé définir un rectangle comme un point + largeur et hauteur, où le point est le coin supérieur gauche du rectangle.
Et puis ajoutez les méthodes dont vous avez besoin pour récupérer les autres métriques. Comme la version Java
la source
En fait, un rectagle n'est pas défini par 2 points. Un rectangle ne peut être défini par deux points que s'il est parallèle aux axes.
Il existe plusieurs façons de représenter des rectangles parallèles aux axes:
Pour (1), de nombreuses bibliothèques utilisent une convention pour déterminer les deux points utilisés - topLeft et bottomRight, par exemple.
Le choix de la représentation peut être motivé par l'objectif initial de la définition du rectangle, mais j'imagine que c'est souvent arbitraire . Les représentations sont équivalentes dans les informations qu'elles véhiculent. Ils diffèrent cependant par la facilité avec laquelle les propriétés du rectangle peuvent être calculées et la commodité avec laquelle les opérations peuvent être effectuées sur le rectangle.
Les avantages de la définition (1) par rapport aux autres comprennent:
la source
Eh bien,
p1: Point
etp2: Point
chacun aura de toute façon deuxint
coordonnées , alors votre classe ne revient-elle pas à la même chose?Et si vous stockez ces deux points en tant
Point
qu'objets de première classe , n'en tirez-vous pas un peu plus d'utilité? Dans la plupart des systèmes de coordonnées graphiques que je connais, les points sont sous-classés de cette manière pour créer une hiérarchie d'objets:point -> circle -> ellipse
etc.Donc, si vous créez un objet qui n'utilise pas la
Point
classe, vous avez dissocié cet objet du reste de la hiérarchie des classes.la source
ytop
/ybottom
, cependant, il devrait également y avoir une garantie quelque part quiybottom
est en fait en dessousytop
.C'est pourquoi j'aime Delphi
TRect
. Il est défini comme un enregistrement variant (structure d'union en langage C) qui peut être interprété comme un point TopLeft et un point BottomRight, ou des entiers Top, Left, Bottom et Right, selon ce qui est plus pratique pour le moment.la source
Sûrement, si vous définissez votre rectangle comme:
alors vous savez tout de suite quel point est lequel.
Encore mieux serait d'ajouter des propriétés supplémentaires qui vous ont permis de manipuler le rectangle de la manière dont vous aviez besoin pour votre application. Celles-ci ne feraient que mettre à jour la structure de données sous-jacente.
En ajoutant une transformation à la forme, vous pouvez orienter votre rectangle comme vous le souhaitez. Vous auriez toujours besoin d'un cadre de délimitation aligné sur l'axe pour des vérifications d'acceptation / rejet rapides :)
Cependant, si votre modèle autorise les rectangles dans n'importe quelle orientation sans appliquer de transformation, alors "en bas à gauche" et "en haut à droite" n'ont aucune signification, ce qui ramène à "p1" et "p2" (ou quelque chose d'équivalent).
la source
je pense qu'il est plus logique qu'un rectangle soit représenté par une étendue x et y et un point; vous pouvez même placer le point de localisation au centre du rectangle afin qu'il soit indépendant de la rotation
mais il était probablement plus facile de le coder en deux points!
la source
Je n'aime pas ça parce que nous avons rejeté un degré de liberté potentiel, qui permet essentiellement une rotation arbitraire. Un rectangle 2D général a cinq inconnues (degrés de liberté). Nous pourrions les spécifier comme les coordonnées d'un point, les longueurs des deux côtés qui forment un sommet avec ce point, et l'angle par rapport à l'horizontale de la première ligne (l'autre étant supposé avoir un angle supérieur de 90 degrés). Un nombre infini d'autres possibilités pourraient également être utilisées, mais il y a cinq quantités indépendantes qui doivent être spécifiées. Certains choix conduiront à une algèbre plus facile que d'autres, selon ce qui sera fait avec eux.
la source
N'est-ce pas exactement la même chose que 2 points? Comment est-ce gênant ... la plupart des routines de dessin nécessitent des points, pas des composants x / y séparés.
la source
La définition de rectangles comme paires de points vous permet de réutiliser le point comme sommet pour une autre forme. Juste une pensée...
la source
Je crois que c'est principalement pour établir l'uniformité entre toutes les primitives de forme.
Bien sûr, vous pouvez définir un rectangle de différentes manières, mais comment définir un triangle, une étoile ou un cercle de manière à utiliser des structures de données similaires?
Tous les polygones peuvent être définis par leurs points, avec une petite quantité de logique pour déterminer quoi faire avec les points.
Les bibliothèques graphiques opèrent principalement sur ces polygones en termes de sommets et d'arêtes, donc les points et les lignes entre eux, tous les calculs fonctionnent sur ces deux entités, bien cela et les facettes, mais cela en soi n'est qu'une fonction des arêtes.
la source
En deux dimensions, le stockage d'un rectangle en deux points est plus clair que la définition d'un coin particulier et d'une largeur et d'une hauteur - considérez une largeur ou une hauteur négative, ou les calculs requis pour déterminer chaque option à partir de l'autre.
Effectuer des rotations sur un rectangle défini par des points est également beaucoup plus simple que celui défini avec un point plus une largeur et une hauteur.
Je m'attendrais à ce que l'encapsulation rende cette différenciation sans importance 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 entièrement sûr de la nécessité de définir un rectangle en 4 dimensions ou plus.
la source
C'est complètement arbitraire. Vous avez besoin de quatre informations pour dessiner un rectangle. Le ou les concepteurs de la bibliothèque ont décidé de le représenter avec deux points (chacun avec une coordonnée xy), mais auraient pu facilement le faire avec x / y / w / h ou en haut / en bas / à gauche / à droite.
Je suppose que la vraie question du PO est: pourquoi ce choix a-t-il été fait?
la source
Le choix des paramètres n'est important que pour les concepteurs / codeurs de bas niveau.
Les utilisateurs de haut niveau n'ont qu'à penser à:
Remarque: afin de minimiser la perte de précision lors de la transformation de mise à l'échelle, il est parfois approprié d'implémenter une deuxième classe Rect qui utilise des coordonnées à virgule flottante, afin que les résultats intermédiaires puissent être stockés avec précision dans une séquence de transformations et uniquement arrondis à un entier dans le dernière étape.
la source
Comme le dit @Steven, je pense que cela devrait être en termes d'un (x, y) point et d'un vecteur de taille (w, h). C'est parce qu'il est facile de tomber dans une ambiguïté. Supposons que vous ayez le rectangle rempli suivant commençant au point (0,0).
C'est clairement sa largeur, sa hauteur sont (3,3), mais quel est son deuxième point? Est-ce (2,2) ou (3,3)?
Cette ambiguïté peut provoquer toutes sortes de problèmes.
J'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, et non comme les lignes les pixels sont sur . De cette façon, il n'y a aucune ambiguïté.
la source
Nous pouvons définir les deux Pb et Pc ainsi:
et
Il n'est donc pas nécessaire de définir les quatre points en raison de la symétrie
la source