4 Stimmen

Wie unterteile ich eine nicht gerade Linie in gerade Segmente?

Ich habe eine nicht geradlinige Linie, die durch eine Reihe von x- und y-Koordinatenpunkten definiert ist. Ich könnte ohne Probleme eine gerade Linie direkt zwischen diesen Punkten auf dem Bildschirm zeichnen. Leider muss ich die Linie in gleich langen Segmenten zeichnen.

Hier ist ein Beispiel dafür, wie ich eine nicht gerade Linie mit 3 Punkten in eine Reihe von mehreren äquidistanten Punkten aufteilen muss. (Ignorieren Sie den letzten roten Punkt, er ist das Ergebnis, wenn eine Linie nicht gleichmäßig geteilt wird, und ist auch der Endpunkt)

Here is an example of how I need to break up a non-straight line with 3 points into an array of several equidistant points

Bitte beachten Sie die rote Linie am "Gelenk". Nehmen wir an, dass ich eine Linie A->B->C habe, bei der die Vektoren AB und BC einen Winkel bilden. Im Grunde knickt die Linie im Punkt B ab.

Das Segmentieren einer Linie zwischen Punkt A und B ist bis zu einem gewissen Punkt kein Problem. Aber wenn AB nicht gleichmäßig durch die Segmentlänge geteilt wird, muss ich etwas Besonderes tun. Ich muss die verbleibende Länge als eine Seite eines Dreiecks betrachten. Die konstante Segmentlänge ist eine weitere Seite eines Dreiecks, die sich mit dem BC-Segment verbindet (die rote Linie oben). Ich muss die Länge vom Punkt B bis zu diesem Schnittpunkt kennen. Mit dieser Information kann ich die Berechnung der Liniensegmente auf BC fortsetzen.

Hier ist das Dreieck, das ich zu lösen versuche (im Folgenden bezeichne ich die Variablen so, wie sie auf diesem Bild erscheinen) Bis jetzt habe ich das Problem auf die Anwendung des Kosinusgesetzes heruntergebrochen. c 2 \= a 2 + b 2 - 2ab * Cos( y )

Das Problem ist, dass ich c bereits kenne, es ist die Segmentlänge. Ich muss für a lösen (ich kann y berechnen).

Ich bin schon so weit gekommen, eine Polynomgleichung zu schreiben, aber jetzt komme ich nicht weiter: a 2 + b 2 - 2ab * Cos( y ) - c 2 \= 0

oder Ax 2 + Bx + C (A = 1, B = -2b * Cos( y ), C = b 2 - c 2 , x = a)

Ist das überhaupt der richtige Ansatz? Was soll ich als nächstes tun? Ich muss dies in Actionscript implementieren.

EDIT: Ach was, ich müsste die quadratische Formel verwenden. Also bekomme ich jetzt:

a = b * Cos( y ) +/- SqrRoot(c 2 - b 2 * Sin( y ) 2 )

Wie setzt man das nun in Code um...

0 Stimmen

Wenn Sie die Url zu dem Bild hinzufügen, kann ich es in Ihrem Beitrag bearbeiten.

0 Stimmen

Ich habe deine Frage hochgestuft, du hast jetzt 13 Vertreter, also kannst du das Bild posten.

0 Stimmen

Ich danke Ihnen! Ich weiß das wirklich zu schätzen. Ich glaube, ich habe die mathematische Lösung gefunden (über die quadratische Formel). Jetzt muss ich sie nur noch codieren. In der Zwischenzeit musste ich mich mit einem anderen Problem befassen, aber wenn ich die Möglichkeit habe, es zu kodieren, werde ich versuchen, zurückzukommen und eine Antwort zu posten. In der Zwischenzeit würde ich mich über jeden Vorschlag freuen. Zwei Gleichungen zu lösen und dann zu prüfen, welche davon positiv ist, scheint ziemlich aufwendig zu sein. Aber es sollte nur an den Verbindungsstellen notwendig sein, so dass die Auslosungslogik die Dinge hoffentlich nicht zu sehr verlangsamen wird.

3voto

Sam Punkte 1223

Ich habe das Problem folgendermaßen gelöst. B und C sind die gleichen, wie du sie definiert hast, ich nenne Punkt A das Ende des letzten vollen Segments auf der ersten Linie. (der letzte Punkt vor der Biegung) Wenn Sie einen Kreis zeichnen, dessen Mittelpunkt bei A liegt und dessen Radius der Länge Ihres Segments entspricht, dann ist der Schnittpunkt dieses Kreises mit der Linie BC der Endpunkt (nennen Sie ihn D) einer Linie von A, die Ihre Ecke schneidet. Um diesen Punkt zu finden, habe ich ein einfaches Verfahren gefunden Helferfunktion Er ist nicht sehr lang, und der Einfachheit halber füge ich ihn hier einfach ein.

/*---------------------------------------------------------------------------
Returns an Object with the following properties:
    enter           -Intersection Point entering the circle.
    exit            -Intersection Point exiting the circle.
    inside          -Boolean indicating if the points of the line are inside the circle.
    tangent     -Boolean indicating if line intersect at one point of the circle.
    intersects      -Boolean indicating if there is an intersection of the points and the circle.

If both "enter" and "exit" are null, or "intersects" == false, it indicates there is no intersection.

This is a customization of the intersectCircleLine Javascript function found here:

http://www.kevlindev.com/gui/index.htm

----------------------------------------------------------------------------*/
function lineIntersectCircle(A : Point, B : Point, C : Point, r : Number = 1):Object {
    var result : Object = new Object ();
    result.inside = false;
    result.tangent = false;
    result.intersects = false;
    result.enter=null;
    result.exit=null;
    var a : Number = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
    var b : Number = 2 * ((B.x - A.x) * (A.x - C.x) +(B.y - A.y) * (A.y - C.y));
    var cc : Number = C.x * C.x + C.y * C.y + A.x * A.x + A.y * A.y - 2 * (C.x * A.x + C.y * A.y) - r * r;
    var deter : Number = b * b - 4 * a * cc;
    if (deter <= 0 ) {
        result.inside = false;
    } else {
        var e : Number = Math.sqrt (deter);
        var u1 : Number = ( - b + e ) / (2 * a );
        var u2 : Number = ( - b - e ) / (2 * a );
        if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {
            if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {
                result.inside = false;
            } else {
                result.inside = true;
            }
        } else {
            if (0 <= u2 && u2 <= 1) {
                result.enter=Point.interpolate (A, B, 1 - u2);
            }
            if (0 <= u1 && u1 <= 1) {
                result.exit=Point.interpolate (A, B, 1 - u1);
            }
            result.intersects = true;
            if (result.exit != null && result.enter != null && result.exit.equals (result.enter)) {
                result.tangent = true;
            }
        }
    }
    return result;
}

Es handelt sich um eine Funktion, die ein Objekt mit mehreren Eigenschaften zurückgibt, so dass die Implementierung in Ihrem Code sehr einfach ist. Sie müssen der Funktion drei Punkte und einen Radius übergeben. Die ersten beiden Punkte sind einfach B und C, wie Sie sie oben definiert haben, und Punkt A, wie ich zu Beginn erklärt habe. Der Radius ist wiederum die Länge Ihres Segments.

//create an object
var myObject:Object = lineIntersectCircle(pointB, pointC, pointA, segmentLength);

Das war's! Die Koordinaten des Punktes D (siehe oben) sind: (myObject.exit.x, myObject.exit.y)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X