[gelöst] Punkt im Dreieck?

  • Mal ne potentiell VDR-freie Fragestellung:
    Gegeben ist das Dreieck A(x1,y1), B(x2,y2), C(x3,y3) und der Punkt P(x,y) in karthesischen Koordinaten. Die Frage ist nun wie man (mit trivialem C/++-Code) herausfinden kann, ob P im Dreieck (incl. seiner Kanten) liegt, oder ausserhalb.
    Das Ganze sollte mit linearen Gleichungen (ohne trigonometrische Funktionen) gehen, aber ich bin zu dumm für die Herleitung. Ich habe u.a. das hier dazu gefunden. Zumindest der zweite Alkoholismus funzt aber net (auch wenn man die Bedingung 'q <= 1' nach 'q >= 0' korrigiert)...
    Hat irgend jemand ne funktionierende Lösung dafür (möglichst mit Herleitung)?


    -> Lösung

    yaVDR 0.6.2; H61M/U3S3 / G530 / 4GB / GT 520 (passiv) / Cine S2 (Rev. V5.5) + DuoFlex S2 / 120GB SSD (System; SATA>USB) + 3TB SATA 6Gb/s; LCD-TV Toshiba 42VL863G; AVR Yamaha RX-S600...

    Einmal editiert, zuletzt von habichthugo ()

  • Wir hatten so ein Problem mal mit Punkt in Polygon. Such doch vielleicht mal danach und dann hast Du eben ein Polygon, welches nur aus drei Punkten besteht. Lösungen kann ich Dir leider nicht geben, aber vielleicht hilft dieser Hinweis... *goodluck*

    Hardware: AMD Duron 900 MHz, 256 MB Ram, 1 x 400 GB und 2 x 200 GB Maxtor, 1 x 500 GB USB 2.0, Nec DVD-RW ND-3500AG, 1 x TT 1.6 FF DVB-S, 1 x Twinhan Budget DVB-T
    Software: VDR 1.4.1, BigPatch, DMH-DVD-Archive-Patch, Kernel 2.6.12
    ---
    "Hörma, wie heißt nomma dat Instrument mit den 3 Knöppen oben drauf...? - Ja richtig, Flöte!"

  • Du brauchst einen "Liegt rechts von Gerade" Algorithmus:


    Google->LiegtRechtsVon


    Wenn der Punkt rechts von allen 3 Geraden liegt, ist er im inneren.


    Gruß
    Roland

    Software: VDR 1.4.3, mp3, osdpip, streamdev-server, femon, wapd, X11, Wireless Keyboard Kernel: 2.6.18
    Hardware: 1x DVB-S v 1.3, 1x Skystar 2, Celeron@2GHz, 256 MB RAM, 4 HDs Raid1/5, Total: 600 GB, Asus P4S533 cmi8738 & LAN on board 6 PCI
    40" Sammelbestellungs-LCD an ATI Radeon 9550 DVI-Out + tvtime, 70 cm TV an J2-RGB-Out
    Organisator der ersten und zweiten VDR-Sanitizer Sammelbestellung.
    In progress: POV-ION 330 - MediaPointer MP-S2 - vdr 1.7.9 - vdr-xine(vdpau)

  • Zitat

    Original von pram
    Wenn der Punkt rechts von allen 3 Geraden liegt, ist er im inneren.


    Bin ich da jetzt auf dem falschen Dampfer?

    Code
    x
              P
    x   
            x


    Hier liegt der Punkt "P" rechts von allen drei begrenzenden Geraden des Dreiecks- aber nicht innerhalb....


    habichthugo:
    Stammen die Koordinaten aus der Menge der natürlichen Zahlen |N ?
    Oder darf es auch rational (|R) sein? Postiv oder auch Negativ? |R ist deutlich einfacher...also |R.


    [Gedankenmodell ON]
    Annahmen: X1=7;3,5 X2=0,0 X3=10;2
    Ich würde zuerst einmal feststellen, welche Koordinaten auf den drei Geraden liegen. Dazu kannst Du die Geraden als Funktion ausdrücken. Für die Gerade G12 wäre das also f(x)=0,5x; für G13 f(x)=0,2x und für G23 f(x)=-0,5x+7. Die Funktionen lassen sich ja einfach berechnen.
    Daraus kannst Du für einen gegebenen Punkt feststellen, ob er über oder unter einer der Geraden liegt.
    Ein Punkt liegt nun im genau dann im Dreieck, wenn er die folgende Bedingung erfüllt ist:
    Er liegt ÜBER GENAU EINER Geraden und UNTER den anderen beiden.


    Müßte so hinkommen ;)
    pram: Ist auch nichts groß anderes, als das "RechtsvonderGeraden", nur daß Deine Bedingung falsch formuliert war.


    Wenn's nicht stimmt: selbst optimieren :gap

    Glotze: yaVDR (ASRock Q1900M, 4GB RAM, DD Cine S2 V6.5, ZOTAC GT630 (Rev. 2)
    Server: HP ProLiant MicroServer G8, VMware ESXi 5.5 :P

  • Hi habichthubo!


    Suche mal nach dem ccw-Algorithmus von Robert Sedgewick, der gibt an, ob ein Punkt rechts oder links von der Geraden liegt (ccw=couterclockwise).


    ccw liefert -1,0,1 (0=auf der Linie)


    Dann ist der Punkt (echt) innerhalb, wenn


    abs(Summe(ccw(A,B,P)+ccw(B,C,P)+ccw(C,A,P)))=3 ist.
    (Das heißt nicht anderes als daß immer -1 oder immer 1 raus kommt, also immer auf der gleichen Seite).


    Sonderfälle wie Punkt auf Linie sind natürlich gesondert zu behandeln.


    knebb: In deinem Beispiel hast du die Orientierung der Geraden außer Acht gelassen. Du musst die Geraden durch die Punkte AB,BC und CA betrachten.


    Grüsse,


    Frank


    Wohnzimmer: Geode NX1750 512MB M811, TT1.5, TT-DVB-S Budget, 2,4TB, Mahlzeit 4.0b,vdr 1.4.6extp25
    Spielwiese: Scenic-S, Cel 900, TT-Budget-S, dxr3 oder xine, 40 GB
    Analog: Athlon 2000XP, ECS K7S5A, 512MB, PVR350+PVR150MCE, 500GB, easyVDR 0.5rc1
    Neu: Asus P5K-V, E6750, 2GB, TT-Budget-S, 80GB, NV 7300GS, easyVDR 0.5rc2 mit xineliboutput

    Einmal editiert, zuletzt von fabo ()

  • Hier findest du z.B. den ccw-Algorithmus.


    Grüsse,


    Frank


    Wohnzimmer: Geode NX1750 512MB M811, TT1.5, TT-DVB-S Budget, 2,4TB, Mahlzeit 4.0b,vdr 1.4.6extp25
    Spielwiese: Scenic-S, Cel 900, TT-Budget-S, dxr3 oder xine, 40 GB
    Analog: Athlon 2000XP, ECS K7S5A, 512MB, PVR350+PVR150MCE, 500GB, easyVDR 0.5rc1
    Neu: Asus P5K-V, E6750, 2GB, TT-Budget-S, 80GB, NV 7300GS, easyVDR 0.5rc2 mit xineliboutput

  • Zitat

    Original von fabo
    knebb: In deinem Beispiel hast du die Orientierung der Geraden außer Acht gelassen. Du musst die Geraden durch die Punkte AB,BC und CA betrachten.


    Stimmt, man muß vorher noch feststellen, welcher der beiden Punkte der drei Geraden "weiter rechts" ist. Dann kann man erst die Funktion bestimmen.


    Aber sonst paßt das ;D

    Glotze: yaVDR (ASRock Q1900M, 4GB RAM, DD Cine S2 V6.5, ZOTAC GT630 (Rev. 2)
    Server: HP ProLiant MicroServer G8, VMware ESXi 5.5 :P

  • knebb
    ...ganz 'normale', reelle Zahlen (double)...


    LiegtRechtsVon...ccw habe ich durchetestet. Tun nicht, oder ich bin zu blöd. Eventuell liegt's einfach daran, dass die Punkte bzw. Kanten geeignet sortiert sein müssen? Könnte mal einer der Weisen hier den Algorithmus komplett (in Cisch nebst Ausnahmebehandlung etc.)wiedergeben? :hat2
    Ich habe hier ein schönes Delaunay-Netz zum austesten...

    yaVDR 0.6.2; H61M/U3S3 / G530 / 4GB / GT 520 (passiv) / Cine S2 (Rev. V5.5) + DuoFlex S2 / 120GB SSD (System; SATA>USB) + 3TB SATA 6Gb/s; LCD-TV Toshiba 42VL863G; AVR Yamaha RX-S600...

  • Zitat

    Original von knebb


    Stimmt, man muß vorher noch feststellen, welcher der beiden Punkte der drei Geraden "weiter rechts" ist. Dann kann man erst die Funktion bestimmen.


    Aber sonst paßt das ;D


    Wenn man - wie von fabo vorgeschlagen - nur auf "alle drei rechts" oder "alle drei links" prüft, braucht man die Punkte vorher nicht zu sortieren, dann tut's nämlich jede Reihenfolge.


    Gruß,
    ARK

    VDR
    ASUS A7N8X-X, AMD 2600+, 2 GB, 320 GB HD, Hauppauge DVB-S 1.3, Hauppauge Nova-S-Plus, Funktastatur
    Debian 4.0/Etch-Kernel 2.6.18-5-486
    c't-VDR 6.1 mit e-tobi 1.6.0 (neu gepatched ohne sortrecordings), acpi, vdradmin-am, burn, osdteletext, ffnetdev, audiorecorder, infosatepg, ...
    Client
    dbox2 (Sagem 2xI_C) mit Neutrino-Derivat

  • ...tut devinitiv nicht!

    yaVDR 0.6.2; H61M/U3S3 / G530 / 4GB / GT 520 (passiv) / Cine S2 (Rev. V5.5) + DuoFlex S2 / 120GB SSD (System; SATA>USB) + 3TB SATA 6Gb/s; LCD-TV Toshiba 42VL863G; AVR Yamaha RX-S600...

  • dito mit

    Code
    ...
       return abs(ccw(x,y,x1,y1,x2,y2)+ccw(x,y,x2,y2,x3,y3)+ccw(x,y,x3,y3,x1,y1)) == 3;
    ...

    ...übrigens auch nicht!

    yaVDR 0.6.2; H61M/U3S3 / G530 / 4GB / GT 520 (passiv) / Cine S2 (Rev. V5.5) + DuoFlex S2 / 120GB SSD (System; SATA>USB) + 3TB SATA 6Gb/s; LCD-TV Toshiba 42VL863G; AVR Yamaha RX-S600...

  • Wie wäre es, wenn du für alle drei Seiten des Dreiecks mit ccw testest, ob der gesuchte Punkt und der Punkt des Dreiecks der nicht für die Gerade gebraucht wurde jeweils auf der gleichen Seite liegen? Dann hat man das Problem mit Links und Rechts nicht.


    Gruß,
    Fridi


  • Nö, tut auch mit Ausnahmebehandlung nich!? :schiel
    Wo liegt der Fehler?

    yaVDR 0.6.2; H61M/U3S3 / G530 / 4GB / GT 520 (passiv) / Cine S2 (Rev. V5.5) + DuoFlex S2 / 120GB SSD (System; SATA>USB) + 3TB SATA 6Gb/s; LCD-TV Toshiba 42VL863G; AVR Yamaha RX-S600...

    Einmal editiert, zuletzt von habichthugo ()

  • also ich würde jetzt behaupten, folgendes funktioniert:



    LRV müsste äquivalent mit ccw sein (hab den einfach aus meinem Info-Skript so übernommen)
    wenn alle 3 Punkte dann rechts (oder links, je nach Umlaufsinn) liegen, ist er im Dreieck.


    in deinem Code sehe ich gerade dass du noch prüfst ob er AUF der Gerade liegt. Da eine Gerade unendlich lang ist, kann er auch ausserhalb des Dreiecks auf der Gerade liegen!


    Gruß
    Roland

    Software: VDR 1.4.3, mp3, osdpip, streamdev-server, femon, wapd, X11, Wireless Keyboard Kernel: 2.6.18
    Hardware: 1x DVB-S v 1.3, 1x Skystar 2, Celeron@2GHz, 256 MB RAM, 4 HDs Raid1/5, Total: 600 GB, Asus P4S533 cmi8738 & LAN on board 6 PCI
    40" Sammelbestellungs-LCD an ATI Radeon 9550 DVI-Out + tvtime, 70 cm TV an J2-RGB-Out
    Organisator der ersten und zweiten VDR-Sanitizer Sammelbestellung.
    In progress: POV-ION 330 - MediaPointer MP-S2 - vdr 1.7.9 - vdr-xine(vdpau)

  • Vielleicht darf ich auch noch meinen Senf dazu geben: Ich erinner mich gerade wieder an eine Vorlesung im letzten Semester "Geometrische Algorithmen". Dabei haben wir auch den sogenannten "point-location" Algo durchgemacht.


    Bitte sich den Anhang anzusehen:


    Nehmen wir an, dass der Punkt q die Koordinaten qx und qy hat. Nun schneidet man die Gerade y=qy mit allen Kanten des Dreiecks und zählt die Schnittpunkte rechts von q.


    Ist die Anzahl gerade liegt der Punkt außerhalb, bei ungerade innerhalb. Funktioniert mit beliebigen geschlossenen Polygonen.


    Die einzige Ausnahme die mir einfällt ist, wenn man genau durch den obersten oder untersten Eckpunkt schneidet.


    HTH
    reini1305

    Bilder

    Mein neuer VDR:
    Hardware: Intel NUC
    (DN2820FYKH), 2GB RAM, DVB-T2: TT-connect CT2-4650 CI, 1TB HDD
    Software: vdr 2.1.6(yavdr), XBMC mit VNSI und VAAPI, Kernel 3.13

    Mein alter VDR:
    Hardware: Celeron 466, 512MB RAM, DVB-S: Nexus-S 2.1, DVB-T: TT-1300, 120 GB HD, DVD-Brenner, 240x128 GLCD, Mustek USV
    Software: vdr 1.6.0(e-tobi.net), graphlcd und mp3 mit span-support, Kernel 2.6.18

  • Zitat

    Original von habichthugo


    Nö, tut auch mit Ausnahmebehandlung nich!? :schiel
    Wo liegt der Fehler?


    Ich würde sagen, wenn du die Zeilen

    Code
    ccw(x,y,x2,y2,x3,y3)


    durch

    Code
    ccw(x2,y2,x3,y3,x,y)


    ersetzst, sollte es funktionieren.


    Wohnzimmer: Geode NX1750 512MB M811, TT1.5, TT-DVB-S Budget, 2,4TB, Mahlzeit 4.0b,vdr 1.4.6extp25
    Spielwiese: Scenic-S, Cel 900, TT-Budget-S, dxr3 oder xine, 40 GB
    Analog: Athlon 2000XP, ECS K7S5A, 512MB, PVR350+PVR150MCE, 500GB, easyVDR 0.5rc1
    Neu: Asus P5K-V, E6750, 2GB, TT-Budget-S, 80GB, NV 7300GS, easyVDR 0.5rc2 mit xineliboutput

  • pram:


    Zitat


    in deinem Code sehe ich gerade dass du noch prüfst ob er AUF der Gerade liegt. Da eine Gerade unendlich lang ist, kann er auch ausserhalb des Dreiecks auf der Gerade liegen!


    Dies sollte im ccw bereits geprüft sein, d.h. ccw(p1,p2,p)==0 nur dann, wenn p AUF p1p2 liegt.


    Grüsse,


    Frank


    Wohnzimmer: Geode NX1750 512MB M811, TT1.5, TT-DVB-S Budget, 2,4TB, Mahlzeit 4.0b,vdr 1.4.6extp25
    Spielwiese: Scenic-S, Cel 900, TT-Budget-S, dxr3 oder xine, 40 GB
    Analog: Athlon 2000XP, ECS K7S5A, 512MB, PVR350+PVR150MCE, 500GB, easyVDR 0.5rc1
    Neu: Asus P5K-V, E6750, 2GB, TT-Budget-S, 80GB, NV 7300GS, easyVDR 0.5rc2 mit xineliboutput

  • Zitat

    Original von pram
    LRV müsste äquivalent mit ccw sein (hab den einfach aus meinem Info-Skript so übernommen)
    wenn alle 3 Punkte dann rechts (oder links, je nach Umlaufsinn) liegen, ist er im Dreieck.


    LRV ist identisch mit dem 1. Teil von ccw. Es wird nicht geprüft, ob der Punkt auf der LINIE liegt, nur auf der GERADEN :) !


    Grüsse,


    Frank


    Wohnzimmer: Geode NX1750 512MB M811, TT1.5, TT-DVB-S Budget, 2,4TB, Mahlzeit 4.0b,vdr 1.4.6extp25
    Spielwiese: Scenic-S, Cel 900, TT-Budget-S, dxr3 oder xine, 40 GB
    Analog: Athlon 2000XP, ECS K7S5A, 512MB, PVR350+PVR150MCE, 500GB, easyVDR 0.5rc1
    Neu: Asus P5K-V, E6750, 2GB, TT-Budget-S, 80GB, NV 7300GS, easyVDR 0.5rc2 mit xineliboutput

  • Zoo geht dat (z.B.):

    Man muss die Fälle, wo der Punkt auf eine der Geraden bzw. Strecken der Dreieckskanten liegt, sauber behandeln bzw. auseinander halten, sonst wird's nix.


    :]:]:]:]:]:]:]
    :] Danke @All! :]
    :]:]:]:]:]:]:]

    yaVDR 0.6.2; H61M/U3S3 / G530 / 4GB / GT 520 (passiv) / Cine S2 (Rev. V5.5) + DuoFlex S2 / 120GB SSD (System; SATA>USB) + 3TB SATA 6Gb/s; LCD-TV Toshiba 42VL863G; AVR Yamaha RX-S600...

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!