savoir si 4 points sur un plan en forme d'un rectangle?
Quelqu'un peut-il svp me montrer en C-style pseudo-code comment écrire une fonction (représentent les points comme bon vous semble) qui retourne true si 4 points (args à la fonction) forme un rectangle, et false dans le cas contraire?
Je suis venu avec une solution qui tente d'abord de trouver 2 paires de points d'égale valeur x, puis le fait pour l'axe des ordonnées. Mais le code est assez long. Juste curieux de voir ce que d'autres viennent avec.
- Sont-elles en ordre?
- Il est venu avec la solution? Où est-il? Vous pouvez montrer ici, et nous pouvons vous aider à en faire plus court et plus.
- Interressant question. Je remarque que votre solution ne fonctionne que si le rectangle est parallèle à l'axe.
- Gman - oui dans n'importe quel ordre. Milan - cela a été demandé de moi lors d'une interview donc je n'ai pas mon code (je n'ai pas nécessairement besoin de voir le code..un algorithme serait trop grand!). Christian - bon point à ce sujet d'avoir à être parallèles à l'axe.
Vous devez vous connecter pour publier un commentaire.
(Bien sûr, dans la pratique, les essais de l'égalité de deux nombres à virgule flottante a et b doit être fait avec une précision: par exemple abs(a-b) < 1E-6)
sqr(x) == x*x
qui signifieddi
est en fait le carré de la distance à partir decx
àxi
. Ce doit être sacrément rapide.sqr
fonctions de la ruine de précision). Cela exige une analyse minutieuse (et à mon avis je doute que cette question a une réponse significative, sans précision étendue de l'arithmétique).Si l'ordre n'est pas connu à l'avance, nous avons besoin d'un peu plus compliqué de vérifier:
if (IsOrthogonal(a, b, c)) return IsRectangle(a, b, c, d); else if (IsOrthogonal(a, b, d)) return IsRectangle(a, b, d, c); else return false;
il est beaucoup plus concis dans le code, si 🙂
(Si vous voulez la faire fonctionner avec des valeurs à virgule flottante, s'il vous plaît, ne pas seulement aveuglément remplacer le int déclarations dans les en-têtes. C'est une mauvaise pratique. Ils sont là pour une raison. Il faut toujours travailler avec une certaine limite supérieure de l'erreur lors de la comparaison à virgule flottante résultats.)
La distance d'un point à l'autre 3 doit avoir la forme d'un triangle rectangle:
Simplification:
Si les points A, B, C & D et vous savez l'ordre puis on calcule les vecteurs:
x=B-A, y=C-B, z=D-C et w=A-D
Puis prendre le point des produits (x dot y), (y dot z), (z point w) et (w point x). Si ils sont tous à zéro, alors vous avez un rectangle.
Ici, nous allons utiliser les propriétés géométriques de rectangle/carré et Peu de Magie.
Propriétés du Rectangle dans le jeu
Peu De Magie
Depuis les distances entre les 4 coins d'un rectangle sera toujours de 3 paires, une pour la diagonale et deux de chaque côté de longueur différente, XORing toutes les valeurs de retour de 0 pour un rectangle.
Nous savons que les deux straight lignes sont perpendiculaires si le produit de leurs pentes est de -1,depuis un avion est donnée, nous pouvons trouver les pentes de trois lignes consécutives et puis les multiplier pour vérifier si elles sont vraiment perpendiculaire ou non. Supposons que nous avons les lignes L1,L2,L3. Maintenant, si L1 est perpendiculaire à la L2 et L2 perpendiculaire à L3, alors c'est un rectangle et la pente de la m(L1)*m(L2)=-1 et m(L2)*m(L3)=-1, alors cela implique que c'est un rectangle. Le code est comme suit
en prenant le produit scalaire suggestion un peu plus loin, vérifier si deux des vecteurs faite par 3 points les points sont perpendiculaires et de voir ensuite si x et y correspondent le quatrième point.
Si vous avez des points de [Ax,Ay] [Bx,By] [Cx,Cy] [Dx,Dy]
vecteur v = B-A
vecteur u = C-A
v(dot)u/|v||u| == cos(theta)
donc, si (c. u == 0) il ya un couple de lignes perpendiculaires à droite.
Je n'en connais pas la programmation en C, mais voici quelques "méta" de programmation pour vous 😛
il n'y a pas de racines carrées dans le présent, et pas de potentiel pour une division par zéro. J'ai remarqué que les gens de mentionner ces questions sur les anciens messages, donc je pensais que je voudrais offrir une alternative.
Donc, par le calcul, vous avez besoin de quatre soustractions pour obtenir v et u, deux multiplications, un plus et vous avez pour vérifier quelque part entre 1 et 7 des égalités.
peut-être que je suis en train de faire cela, mais je me souviens vaguement avoir lu quelque part que les soustractions et les multiplications sont "plus vite" dans les calculs. Je suppose que la déclaration des variables/tableaux et de définir leurs valeurs est également très rapide?
Désolé, je suis assez nouveau à ce genre de chose, alors j'aimerais des commentaires à ce que je viens d'écrire.
Edit: essayez cette fonction sur mon commentaire ci-dessous:
Comment à ce sujet afin de vérifier ces 4 points pourrait forme d'un parallélogramme d'abord, puis de trouver s'il existe un angle droit.
1. vérifier parallélogramme
input 4 points A, B, C, D;
if(A, B, C, D are the same points), exit;//not a rectangle;
else form 3 vectors, AB, AC, AD, verify(AB=AC+AD || AC=AB+AD || AD=AB+AC), \\if one of them satisfied, this is a parallelogram;
2.vérifier qu'un angle droit
through the last step, we could find which two points are the adjacent points of A;
We need to find out if angle A is a right angle, if it is, then rectangle.
Je ne sais pas si il existe des bugs. S'il vous plaît comprendre si il y est.
J'ai récemment été confronté à un problème similaire, mais en Python, c'est ce que j'ai trouvé en Python, peut-être que cette méthode peut être utile. L'idée est qu'il y a six lignes, et si elle est créée dans un ensemble, il devrait être de 3 unique ligne de distances restantes - la longueur, la largeur et diagonale.
Voici mon algorithme de proposition, pour un axe aligné rectangle de test, mais en Python.
L'idée est de prendre le premier point comme sur un pivot, et que tous les autres points doivent être conformes à la même largeur et la hauteur, et vérifie que tous les points sont distincts, par l'intermédiaire d'un ensemble, afin de tenir compte des cas tels que (1, 2), (1, 2), (10, 30), (10, 30).