10
votes

Détecter un sous-ensemble coïncident de deux segments de ligne coïncidents

Cette question est liée à:

  • Comment puis-je déterminer le Point d'intersection de deux lignes dans GDI +? (grande explication de l'algèbre mais aucun code)
  • Comment détectez-vous où deux lignes segments intersect? (réponse acceptée ne fonctionne pas réellement)

    Mais notez qu'un sous-positif intéressant est totalement brillant dans la plupart des solutions qui viennent de renvoyer NULL pour le cas de coïncidence, même s'il existe trois sous-étuis:

    • coïncident mais ne se chevauchent pas
    • toucher juste des points et coïncidents
    • Sous-segment de ligne de chevauchement / coïncidence

      Par exemple, nous pourrions concevoir une fonction C # comme ceci: xxx

      où (A1, A2) est un segment de ligne et (B1, B2) est Un autre.

      Cette fonction nécessiterait de couvrir tous les cas étranges que la plupart des implémentations ou des explications brillent. Afin de rendre compte de l'étrangeté des lignes coïncidentes, la fonction pourrait renvoyer une gamme de Poing's:

      • points de résultat zéro (ou null) Si les lignes sont parallèles ou ne se croisent pas (les lignes infinies intersect, mais les segments de ligne sont disjoint ou des lignes sont parallèle )
      • Un point de résultat (contenant l'emplacement d'intersection) si elles le font intersect ou s'ils sont coïncident à un point
      • Deux points de résultat (pour la partie se chevauchent des segments de ligne) si les deux lignes sont coïncident

3 commentaires

Je me rends compte que cette question est juste posée afin que vous puissiez publier votre réponse. Vous devriez le marquer comme la réponse acceptée. Il ne ferait pas mal d'utiliser une langue moins conflictuelle dans la question également, FWIW.


@TFInniga: Je ne me suis pas réalisé qu'il était confrontalé avant de le réécrire et que je lui ai fait ressembler à un casse-tête au lieu d'une demande. Mon objectif n'était pas de rendre les autres personnes faire le travail pour moi, mais plutôt pour prouver qu'aucune autre mise en œuvre, même a travaillé . (Si vous pouvez me prouver tort et trouver une solution vraiment bonne (c'est là maintenant) qui fonctionne parfaitement, je vous donnerais volontiers 100 représentants).


Merci, je pense que c'est beaucoup mieux. Une mise en œuvre à la balle de balle pour ce besoin commun est précieuse et la question reformulée est beaucoup plus agréable.


4 Réponses :


14
votes
----------------------------------------------------------
line segments intersect
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=100, Y=100}
intersect {X=100, Y=0} -- {X=0, Y=100} and if so, where?

{X=50, Y=50}
----------------------------------------------------------
Does      {X=5, Y=17} -- {X=100, Y=100}
intersect {X=100, Y=29} -- {X=8, Y=100} and if so, where?

{X=56.85001, Y=62.30054}
----------------------------------------------------------

----------------------------------------------------------
just touching points and lines cross
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=25, Y=25}
intersect {X=25, Y=25} -- {X=100, Y=75} and if so, where?

{X=25, Y=25}
----------------------------------------------------------

----------------------------------------------------------
parallel
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=0, Y=100}
intersect {X=100, Y=0} -- {X=100, Y=100} and if so, where?

Doesn't intersect
----------------------------------------------------------

----
lines cross but segments don't intersect
----------------------------------------------------------
Does      {X=50, Y=50} -- {X=100, Y=100}
intersect {X=0, Y=25} -- {X=25, Y=0} and if so, where?

Doesn't intersect
----------------------------------------------------------

----------------------------------------------------------
coincident but do not overlap!
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=25, Y=25}
intersect {X=75, Y=75} -- {X=100, Y=100} and if so, where?

Doesn't intersect
----------------------------------------------------------

----------------------------------------------------------
touching points and coincident!
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=25, Y=25}
intersect {X=25, Y=25} -- {X=100, Y=100} and if so, where?

{X=25, Y=25}
----------------------------------------------------------

----------------------------------------------------------
overlap/coincident
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=75, Y=75}
intersect {X=25, Y=25} -- {X=100, Y=100} and if so, where?

{X=25, Y=25} -- {X=75, Y=75}
----------------------------------------------------------
Does      {X=0, Y=0} -- {X=100, Y=100}
intersect {X=0, Y=0} -- {X=100, Y=100} and if so, where?

{X=0, Y=0} -- {X=100, Y=100}
----------------------------------------------------------

7 commentaires

ERRR ... Je n'ai pas remarqué que vous avez posté la question aussi. p. J'ai enlevé le bowvote.


... Ou pas, on me dit que mon poste de 10 minutes de 10 minutes est trop vieux pour changer. J'ai suscité une autre de vos réponses pour le compenser. Désolé. :)


Merci de "le reprendre". Vous remarquerez que j'ai également marqué la question en tant que wiki communautaire pour éviter que les gens pensant que j'étais agriculture, etc. C'est une question intéressante si ... affiche un exemple de code de travail contre l'esprit du site? Peut-être que je devrais le poster ailleurs (blog, etc.) et lier-toi? Le point est que beaucoup de réponses à d'autres questions similaires ont des défauts fatals, ce qui est vraiment ... contre l'esprit du site aussi. Merci pour la tentative d'explication. Peut-être que j'aurais d'avoir juste posté ceci sur un blog quelque part, quand j'ai fini. Désolé...


De plus, depuis son wiki communautaire, aucun de nous n'a perdu aucun représentant!


Vous savez, j'ai lu la question originale qui, bien écrite, demandait simplement "Teh Codez" :). Je ne me suis tout simplement pas réalisé que vous l'avez écrit spécifiquement parce que vous deviez trouver la réponse vous-même.


Bonjour, grand et très serviable, mais il y a encore un bug. À POINTOFLINE, la distance a calculé le contrôle que le point est sur la ligne, pas dans le segment. Le segment de ligne IL est (0,0) -> (10,0) et le point est (15, 0), puis dist sur le segment est de 0, et pointoFline répond vrai


Pour ajouter à @yannlemOigne Commentaire, le code de la méthode distFromSeg peut être remplacé par une implémentation, comme on peut trouver dans différentes langues à l'aide de ce lien: Paulbourke.net/geometry/potonlinePane



-3
votes

C'est vraiment très simple. Si vous avez deux lignes, vous pouvez trouver deux équations sous la forme de y = mx + b. Par exemple:

2x + 5 = x - 3 
x + 5 = -3
x = -8


2 commentaires

Ceci est également subtilement faux: lorsque les points sont au-dessus et au-dessous de l'autre, la pente est infinie et toutes les cases d'enfer perdent.


Lorsque les pentes de chaque ligne sont égales, elles peuvent toujours intersecter à un point ou sur un segment de ligne, voire pas du tout.



7
votes

On dirait que vous avez votre solution, ce qui est génial. J'ai quelques suggestions pour l'améliorer.

La méthode a un problème de convivialité majeur en ce sens qu'il est très déroutant de comprendre (1) quels paramètres entrent en moyenne, et (2) quels sont les résultats qui sortent. Les deux sont de petites énigmes que vous devez comprendre si vous souhaitez utiliser la méthode. P>

Je serais plus enclin à utiliser le système de type pour en faire beaucoup plus clairement ce que cette méthode fait. P>

Je commencerais en définissant un type - peut-être une structure, en particulier si cela allait être immuable - appelé Linteseggment. Un lingese se compose de deux structures de pointage représentant le point final. P>

Deuxièmement, je définirais un type de base abstrait "locus" et des types dérivés Emptylocus, PointLocus, LineesgmentsLocus et peut-être UnionLocus Si vous devez représenter le locus qui est l'union de deux locus ou plus. Un locus vide n'est qu'un singleton, un lieu de point est juste un point unique, et ainsi de suite. P>

Maintenant que la signature de votre méthode devient beaucoup plus claire: p>

var point = new PointF(whatever);
var lineseg = new LineSegment(somepoint, someotherpoint);
var intersection = lineseg.Intersect(point);
if (intersection is EmptyLocus) ...


2 commentaires

Merci pour les recommandations et les extensions.


C'est une excellente méthode Eric, j'utilisais auparavant Enums associé à d'autres objets pour fournir un résultat. C'est élégant et bien supérieur. Merci.



2
votes

@jaré, une grande question et une bonne réponse.

Le problème peut être simplifié en représentant la position d'un point le long d'une ligne en fonction d'un seul paramètre, comme expliqué sur Joseph O 'Rourke's's CGA FAQ ici . P>

Soit R être un paramètre pour indiquer P emplacement le long de la ligne contenant ab, avec la signification suivante: p>

double deltax = bx - ax;
double deltay = by - ay;
double l2 = deltax * deltax + deltay * deltay;
double r = ((ay - cy) * (ay - by) - (ax - cx) * (bx - ax)) / l2;


1 commentaires

Un plus pour la référence de liaison. C'était utile pour moi