Combien d'entiers points dans les trois points formant un triangle?
En fait c'est un problème classique que de SORTE que l'utilisateur Victor mettre (dans l'autre, de SORTE question concernant les tâches à poser lors d'un entretien).
Je ne pouvais pas le faire en une heure (soupir) alors, quel est l'algorithme qui calcule le nombre entier de points à l'intérieur d'un triangle?
MODIFIER: Supposons que les sommets sont au nombre entier coordonnées. (sinon ça devient un problème de trouver tous les points à l'intérieur du triangle, puis en soustrayant toutes les floating points pour être laissé avec seulement le nombre entier de points, un de moins élégant problème).
- Quels points sur l'un des bords? Les bords exclusif ou inclusif?
- Je ne comprends pas la question, pouvez-vous donner un peu plus de détails?
- Admettons inclusive. Votre question n'a de sens que si il y a une bordure de largeur définie autour du triangle. Dans ce cas, c'est une ligne sans largeur, et il serait donc toujours être inclus. Maintenant, si il y a une frontière avec de largeur sur elle, alors cette question retient l'eau.
- par exemple, étant donné un triangle dont les sommets (0,0), (0,3), (3,0), trouver le nombre entier coordonnées de l'intérieur (c'est à dire 1,1) est l'un d'entre eux
- Pouvez-vous lier à l'autre question, veuillez
- stackoverflow.com/questions/1047232/...
- Bon point. Je pensais à "l'intérieur" implicite d'une bordure d'une certaine sorte.
- Sont les sommets du triangle en entier coordonnées de trop?
Vous devez vous connecter pour publier un commentaire.
En supposant que les sommets sont au nombre entier coordonnées, vous pouvez obtenir la réponse par la construction d'un rectangle autour du triangle, comme expliqué dans Kyle Schultz Une Enquête de Choisir le Théorème de.
Pour un j x k rectangle, le nombre de l'intérieur de points est
Pour l'5 x 3 rectangle ci-dessous, il y a 8 intérieur des points.
(source: uga.edu)
Pour les triangles avec un pied vertical (j) et d'un bras horizontal (k) le nombre de l'intérieur de points est donné par
où h est le nombre de points à l'intérieur du rectangle qui coïncident à l'hypoténuse des triangles (pas la longueur).
(source: uga.edu)
Pour les triangles avec un côté vertical ou horizontal, le nombre de l'intérieur, les points (I) est donnée par
(source: uga.edu)
où j, k, h1, h2, et b sont marqués dans le diagramme suivant
(source: uga.edu)
Enfin, le cas de triangles sans la verticale ou à l'horizontale côtés peut être divisé en deux sous-cas, celui où la zone entourant le triangle formes de trois triangles, et où la région environnante forme trois triangles et un rectangle (voir les schémas ci-dessous).
Le nombre de l'intérieur, les points (I) dans le premier sous-cas est donné par
(source: uga.edu)
où toutes les variables sont identifiées dans le schéma suivant
(source: uga.edu)
Le nombre de l'intérieur, les points (I) dans le second sous-cas est donné par
(source: uga.edu)
où toutes les variables sont identifiées dans le schéma suivant
(source: uga.edu)
I= A - B/2 +1
(j - a) * (k - b)
je pense. il semble plus propreChoisir le théorème de (http://en.wikipedia.org/wiki/Pick%27s_theorem) stipule que la surface d'un polygone simple placé sur un nombre entier de points est donné par:
Ici, A est la surface du triangle, i est le nombre de l'intérieur, points et b est le nombre de points de limite. Le nombre de points de limite b peut être facilement calculé en additionnant le plus grand diviseur commun de la pentes de chaque ligne:
La surface peut également être calculé. Pour une formule qui calcule la surface de voir https://stackoverflow.com/a/14382692/2491535 . La combinaison de ces valeurs connues j'ai peut être calculé par:
Mon réflexe serait de brute-forcer:
Ce qui est appelé le "Point dans le Triangle" de test.
Ici est un article avec plusieurs solutions à ce problème: Point dans le Triangle d'Essai.
Une voie commune pour vérifier si un point est dans un triangle a pour trouver les vecteurs reliant le point à chacun des trois sommets du triangle et somme des angles entre ces vecteurs. Si la somme des angles est 2*pi (à 360 degrés), alors le point est à l'intérieur du triangle, sinon il ne l'est pas.
Ok, je vais proposer un algorithme, il ne sera pas brillant, mais il faudra travailler.
Abord, nous avons besoin d'un point dans le triangle d'essai. Je propose d'utiliser le "Barycentrique Technique", comme expliqué dans cet excellent billet:
http://www.blackpawn.com/texts/pointinpoly/default.html
Maintenant à l'algorithme:
soit (x1,y1) (x2,y2) (x3,y3) est le triangle de sommets
laisser ymin = sol(min(y1,y2,y3)) ymax = plafond(max(y1,y2,y3)) xmin = sol(min(x1,x2,x3)) ymax = plafond(max(x1,x2,3))
itération de xmin à xmax et ymin à ymax vous pouvez énumérer tous les entiers de points dans la zone rectangulaire qui contient le triangle
en utilisant le point dans le triangle de test, vous pouvez tester pour chaque point de l'énumération pour voir si elle est sur le triangle.
C'est simple, je pense qu'il peut être programmé en moins d'une demi-heure.
Je n'ai qu'une demi-réponse pour un non-brute-force de la méthode. Si les sommets ont été entier, vous pouvez le réduire à trouver comment trouver combien d'entiers points les arêtes se croisent. Avec ce numéro et l'aire du triangle (la formule de Héron), vous pouvez Choisir le théorème de trouver le nombre de l'intérieur entier de points.
Edit: pour l'autre moitié, de trouver le nombre entier de points d'intersection du bord, je soupçonne que c'est le plus grand dénominateur commun entre le x et le y de différence entre les points moins un, ou si la distance moins un, si l'un de x ou y des différences est nulle.
Voici une autre méthode, pas forcément le meilleur, mais assurez-vous d'impressionner les interviewer.
Tout d'abord, appelez le point le plus bas X co-ord 'L', le point le plus haut X co-ord 'R', et le reste des point 'M' (Gauche, Droit et central).
Ensuite, mis en place deux instances de Bresenham ligne de l'algorithme. Paramétrer un exemple de tirage de L à R, et la seconde à dessiner à partir de L à M. Exécuter les algorithmes simultanément pour X = X[L] X[M]. Mais au lieu de dessiner des lignes ou d'allumer les pixels, comptez le nombre de pixels entre les lignes.
Après progression de X[L] X[M], modifiez les paramètres de la deuxième Bresenham pour attirer de M à R, puis continuer à exécuter les algorithmes simultanément pour X = X[M] X[R].
Ceci est très similaire à la solution proposée par Erwin Smout 7 heures, mais à l'aide de Bresenham au lieu d'une ligne de pente de la formule.
Je pense que, pour compter les colonnes de pixels, vous aurez besoin de déterminer si M se situe au-dessus ou au-dessous de la ligne de LR, et bien sûr des cas particuliers surviennent lorsque deux points ont la même X ou Y à coordonner. Mais par le temps que cela arrive, votre interlocuteur sera suffisamment impressionné et vous pouvez passer à la question suivante.
Rapide n'dirty pseudocode:
J'ai cette idée -
Laisser Une(x1, y1), B(x2, y2) et(x3, y3) être les sommets du triangle. Laissez "compter" le nombre entier de points formant le triangle.
Si nous avons besoin de les points sur les bords des triangles, puis en utilisant la Distance Euclidienne formule http://en.wikipedia.org/wiki/Euclidean_distance, la longueur des trois côtés peut être établie.
La somme de la longueur des trois côtés - 3, donnerait qui comptent.
Pour trouver le nombre de points à l'intérieur du triangle, nous devons utiliser un triangle algorithme de remplissage et au lieu de faire le rendu réel c'est à dire l'exécution de drawpixel(x,y), il suffit d'aller à travers les boucles et les maintenir à jour le comte comme nous l'avons effectue une boucle.
Un triangle algorithme de remplissage de
devrait aider. Sa visée ici http://www.gidforums.com/t-20838.html
acclamations
Je ferais comme ceci :
Prendre le plus haut point du triangle (celui avec la plus haute de l'ordonnée). Il y a deux "pistes" à partir de ce point. Ce n'est pas la solution générale, mais pour faciliter la visualisation, pensez à l'une des deux "aller à gauche" (pour diminuer les coordonnées x) et l'autre un "aller vers la droite".
De ces deux pentes et tout Y coordonner moins que le point le plus élevé, vous devriez être en mesure de calculer le nombre entier de points qui apparaissent dans les limites fixées par les pentes. Itération sur la diminution de coordonnées Y, ajouter tous ceux qui nombre de points de l'ensemble.
Arrêter lorsque la réduction de votre Y les coordonnées d'atteindre le deuxième plus haut point du triangle.
Vous avez maintenant compté tous les points "ci-dessus, le deuxième plus haut point", et vous êtes maintenant à gauche avec le problème du "comptage de tous les points à l'intérieur de certains (beaucoup plus petit !!!) triangle, de qui vous savez que le haut de son côté parallèle à l'axe des abscisses.
Répéter la même procédure, mais maintenant, avec la prise de la "gauche" au lieu de "supérieure", et avec proceedding "par l'augmentation de x", plutôt que par "la diminution de y".
Après cela, vous êtes de gauche avec le problème de comptage de tous les entiers de points de dans une, encore une fois beaucoup plus faible, de triangle, de qui vous savez que le haut de son côté parallèle à l'axe des X, et son côté gauche, parallèle à l'axe des Y.
Répéter (récurrents), jusqu'à ce que vous comptez pas les points dans le triangle, vous êtes de gauche avec.
(J'ai maintenant fait vos devoirs pour vous ?)
(bizarre) pseudo-code pour un peu-mieux-que-brute-force (il doit avoir O(n))
j'espère que vous comprenez ce que je veux dire
cet algorithme est assez facile de le prolonger pour les sommets de type float (a seulement besoin d'une tour à l' "je.." partie, avec un cas particulier pour p2.x entier (y, arrondi=arrondi à la hausse))
et il y a certaines possibilités d'optimisation dans une véritable mise en œuvre
J'ai trouvé un lien très utile qui explique clairement la solution à ce problème. Je suis faible dans la géométrie des coordonnées j'ai donc utilisé cette solution et codé en Java qui fonctionne (au moins pour le cas de test, j'ai essayé..)
http://mathforum.org/library/drmath/view/55169.html
Ici est un Python de mise en œuvre de @Prabhala de la solution:
Utilisation: