ob x,y auf einer linie liegt

  • ob x,y auf einer linie liegt

    hallo,
    ich muss eine abfrage machen, ob sich ein punkt (Koordinaten x,y des objektes das den Script aufruft) auf einer Linie befindet. ich habe es so gemacht:

    GML-Quellcode

    1. var x1,y1,x2,y2,fak;
    2. x1 = argument0;
    3. y1 = argument1;
    4. x2 = argument2;
    5. y2 = argument3;
    6. draw_text(0,-32,round(point_direction(x1,y1,x2,y2)*180/pi));
    7. draw_text(0,-64,round(point_direction(x1,y1,x,y)*180/pi));
    8. if ( round(point_direction(x1,y1,x2,y2)) < round(point_direction(x1,y1,x,y))+5 && round(point_direction(x1,y1,x2,y2)) > round(point_direction(x1,y1,x,y))-5 ) {
    9. if ( round(point_distance(x1,y1,x2,y2))>=round(point_distance(x1,y1,x,y)-5) ) {
    10. return true;
    11. }
    12. }
    Alles anzeigen
    leider kommt es zu Konflikten an Eckpunkten und manchmal auch an pixelsprüngen (kennt ja jeder wen man eine linie nicht 100% hor, oder vert. zeichnet, das sie an manchen stellen springt.)

    ps: collision_line kann ich aus verschiedenen gründen nicht verwenden.
    :) Nobody is perfect (-:

    "Dummköpfe sind Denkerköpfen weit überlegen. Zahlenmäßig." Ernst Ferstl
  • Bei diesem Script wird geprüft ob der Vektor x2-x1/y2-y1 ein Vielfaches des Vektors x-x1/y-y1 ist, was bedeuten würde, dass die Punkte auf der selben Gerade liegen. Falls nötig kannst du jetzt ja einfach testen ob der Punkt auf der Vergindungslinie liegt.
    Spoiler anzeigen

    GML-Quellcode

    1. {
    2. var x1,y1,x2,y2,t;
    3. x1 = argument0;
    4. y1 = argument1;
    5. x2 = argument2;
    6. y2 = argument3;
    7. if(x2-x1!=0) //Division durch 0 verhindern
    8. {
    9. t=(x-x1)/(x2-x1); //Streckungsfaktor
    10. if(round(t*(y2-y1))==round(y-y1))
    11. {
    12. return true;
    13. }
    14. else
    15. {
    16. return false;
    17. }
    18. }
    19. else if(y2-y1!=0) //Division durch 0 verhindern
    20. {
    21. t=(y-y1)/(y2-y1); //Streckungsfaktor
    22. if(round(t*(x2-x1))==round(x-x1))
    23. {
    24. return true;
    25. }
    26. else
    27. {
    28. return false;
    29. }
    30. }
    31. else // Nullvektor
    32. {
    33. return false;
    34. }
    35. }
    Alles anzeigen


    Dragoon
    int (*x(*x(int))[5])(int*);
    Confused? Yes, it's C!
  • ich habs nicht getestet, aber schau mal das an:

    GML-Quellcode

    1. var x1,y1,x2,y2,m,b,tol,yt;
    2. x1 = argument0;
    3. y1 = argument1;
    4. x2 = argument2;
    5. y2 = argument3;
    6. tol=0.5;
    7. m= (y2-y1)/(x2-x1);
    8. b= y2-m*x2;
    9. yt=m*x+b;
    10. if( (yt<(y+tol)) && (yt>(y-tol)))
    11. return true;
    12. else
    13. return false;
    Alles anzeigen


    den wert fuer tol kannst du variieren... so kannst du eine toleranz einstellen. Bei dem Code sollte jedoch nicht geprueft werden ob der punkt auf einer linie liegt, sondern auf der geraden, auf die durch die 2 Punkte beschrieben wird... kriegst du aber bestimmt mit 2 Zeilen Code erweitert.
    Zwei kleine Fabeln zum Thema Copyright und Patente:
    Das Schwein und die Kiste und Die Krähe die fliegen konnte

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Ledif ()

  • So gehts, habs auch getestet:

    GML-Quellcode

    1. // argument0 = x1
    2. // argument1 = y1
    3. // argument2 = x2
    4. // argument3 = y2
    5. var x1, y1, x2, y2, nx, ny, l;
    6. x1 = x-argument0;
    7. y1 = argument1-y;
    8. x2 = argument2-argument0;
    9. y2 = argument3-argument1;
    10. nx = y2;
    11. ny = -x2;
    12. l = sqrt(sqr(nx)+sqr(ny));
    13. nx /= l;
    14. ny /= l;
    15. s = (ny*x1+nx*y1)/(x2*ny-y2*nx);
    16. if (s >= 0 and s <= 1) {
    17. r = (y2*x1+x2*y1)/(nx*y2-ny*x2);
    18. if (abs(r) <= 2) // Toleranz
    19. return true;
    20. }
    21. return false;
    Alles anzeigen
  • so, ich bin es nochmal.
    Die letzte Lösung ist nicht schlecht, leider sogar ein bisschen zugut^^ sprich es werden Linien erkannt, die eigentlich nicht da sind. Weiß noch nicht genau warum.
    Ich habe mal die gm7 Datei angehängt.
    Es geht wie folgt:
    Wen man mit der Maus ins weiße Kästchen klickt, ist es aktiviert, wen man ins graue klickt, deaktiviert. Klickt man ins aktivierte weiße Kästchen, kann man Linien ziehen (eine geschlossene Kontur).
    Und wen man 'F' drückt, und innerhalb der Kontur klickt, soll die gesamte Kontur mit den Objekten 'obj_infel' gefüllt werden.

    // edit:
    // Fehlertäufel
    Dateien
    • schwerpunkt.rar

      (11,12 kB, 153 mal heruntergeladen, zuletzt: )
    :) Nobody is perfect (-:

    "Dummköpfe sind Denkerköpfen weit überlegen. Zahlenmäßig." Ernst Ferstl
  • Die eine Abfrage im Alarm0 Event von obj_infel war ein bissl konfus.
    Ersetz mal den ersten Teil mit diesem Code dann sollte es gehen:

    GML-Quellcode

    1. if ( x > obj_sheet.x && x < obj_sheet.x+obj_sheet.xsize && y < obj_sheet.y && y > obj_sheet.y-obj_sheet.ysize ) {
    2. create = true
    3. for ( i=0; i<ds_list_size(obj_sheet.xkontur); i+=1 ) {
    4. j = (i+1) mod ds_list_size(obj_sheet.xkontur);
    5. if ( scr_on_line(ds_list_find_value(obj_sheet.xkontur,i),ds_list_find_value(obj_sheet.ykontur,i),ds_list_find_value(obj_sheet.xkontur,j),ds_list_find_value(obj_sheet.ykontur,j))) {
    6. create = false;
    7. }
    8. }
    9. }
    10. ...