Frage

Wie kann ich eine senkrecht auf einer Strecke von einem gegebenen Punkt ziehen? My Liniensegment wird als (x1, y1) definiert sind, (x2, y2), wenn ich einen senkrecht von einem Punkt (x3, y3) zu ziehen und es trifft auf den Punkt (x4, y4) auszukleiden. Ich möchte diese (x4, y4) erfahren.

War es hilfreich?

Lösung

Ich löste die Gleichungen für Sie:

k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) / ((y2-y1)^2 + (x2-x1)^2)
x4 = x3 - k * (y2-y1)
y4 = y3 + k * (x2-x1)

Wo ^ 2 bedeutet Quadrat

Andere Tipps

Wiki :

  

In der Algebra für jede lineare Gleichung   y = mx + b, wird die Loten all   hat eine Steigung von (-1 / m), die gegenüberliegenden   Kehrwert der ursprünglichen Steigung. Es   ist hilfreich, um das Motto „zu merken   finden die Neigung der senkrechten   Linie, die die Flip-Fraktion und ändern   schreiben.“Daran erinnern, dass jede ganze Zahl ein   ist sich über ein und kann geschrieben werden   als (a / 1)

     

die senkrecht von einem bestimmten finden   Linie, die auch durch eine übergibt   bestimmter Punkt (x, y), die lösen   Gleichung y = (-1 / m) x + b, unter Substitution von   in den bekannten Werten von m, x und y zu   lösen für b.

Die Steigung der Linie, m, durch (x1, y1) und (x2, y2) ist m = (y1 - y2) / (x1 - x2)

ich mit peter.murray.rust zustimmen, Vektoren machen die Lösung deutlicher:

// first convert line to normalized unit vector
double dx = x2 - x1;
double dy = y2 - y1;
double mag = sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;

// translate the point and get the dot product
double lambda = (dx * (x3 - x1)) + (dy * (y3 - y1));
x4 = (dx * lambda) + x1;
y4 = (dy * lambda) + y1;

Sie werden oft feststellen, dass die Verwendung von Vektoren die Lösung klarer ... macht

Hier ist eine Routine aus meiner eigenen Bibliothek:

public class Line2  {

Real2 from;
Real2 to;
Vector2 vector;
Vector2 unitVector = null;


    public Real2 getNearestPointOnLine(Real2 point) {
        unitVector = to.subtract(from).getUnitVector();
        Vector2 lp = new Vector2(point.subtract(this.from));
        double lambda = unitVector.dotProduct(lp);
        Real2 vv = unitVector.multiplyBy(lambda);
        return from.plus(vv);
    }

}

Sie haben REAL2 (ein Punkt) und Vector2 und dotProduct () zu implementieren, aber diese sollten einfach sein:

Der Code sieht dann so etwas wie:

Point2 p1 = new Point2(x1, y1);
Point2 p2 = new Point2(x2, y2);
Point2 p3 = new Point2(x3, y3);
Line2 line = new Line2(p1, p2);
Point2 p4 = getNearestPointOnLine(p3);

Die Bibliothek (org.xmlcml.euclid) ist: http://sourceforge.net/projects/cml/

und es gibt Unit-Tests, die dieses Verfahren ausüben und zeigen Ihnen, wie es zu benutzen.

@Test
public final void testGetNearestPointOnLine() {
    Real2 p = l1112.getNearestPointOnLine(new Real2(0., 0.));
    Real2Test.assertEquals("point", new Real2(0.4, -0.2), p, 0.0000001);
}

Sie kennen sowohl den Punkt und die Steigung, so dass die Gleichung für die neue Linie ist:

y-y3=m*(x-x3)

Da die Linie, die senkrecht ist, ist die Steigung der negative Reziprokwert. Sie haben nun zwei Gleichungen und können für ihre Kreuzung lösen.

y-y3=-(1/m)*(x-x3)
y-y1=m*(x-x1)

Berechne die Steigung der Geraden Verbindungspunkte (x1, y1) und (x2, y2) als m=(y2-y1)/(x2-x1)

Gleichung der Verbindungslinie (x1, y1) und (x2, y2) Punkt-Steigungs-Form der Liniengleichung verwendet wird, würde y-y2 = m(x-x2)

Steigung der Verbindungslinie (x3, y3) und (x4, y4) würde -(1/m)

Wiederum Gleichung der Verbindungslinie (x3, y3) und (x4, y4) unter Verwendung von Punkt-Steigungs-Form der Liniengleichung, würde y-y3 = -(1/m)(x-x3)

Lösen Sie diese beiden Liniengleichungen, wie Sie eine lineare Gleichung in zwei Variablen und die Werte von x und y lösen Sie wäre bekommen (x4, y4)

Ich hoffe, das hilft.

cheers

  

die Pisten finden Sie sowohl für die   Linien, sagen Pisten sind m1 und m2 dann    m1 * m2 = -1 ist die Bedingung für   Rechtwinkligkeit.

Matlab Funktionscode für das folgende Problem

function Pr=getSpPoint(Line,Point)
% getSpPoint(): find Perpendicular on a line segment from a given point
x1=Line(1,1);
y1=Line(1,2);
x2=Line(2,1);
y2=Line(2,1);
x3=Point(1,1);
y3=Point(1,2);

px = x2-x1;
py = y2-y1;
dAB = px*px + py*py;

u = ((x3 - x1) * px + (y3 - y1) * py) / dAB;
x = x1 + u * px;
y = y1 + u * py;

Pr=[x,y];

end

Mathematica die Funktion RegionNearest[] in Version 10 eingeführt 2014. Diese Funktion verwendet werden könnte, eine Antwort auf diese Frage zurückzukommen:

{x4,y4} = RegionNearest[Line[{{x1,y1},{x2,y2}}],{x3,y3}]

Dies ist vor allem ein Duplikat Arnkrishn Antwort. Ich wollte nur seinen Abschnitt mit einem vollständigen Mathematica-Code-Snippet vervollständigen:

m = (y2 - y1)/(x2 - x1)
eqn1 = y - y3 == -(1/m)*(x - x3)
eqn2 = y - y1 == m*(x - x1)
Solve[eqn1 && eqn2, {x, y}]

Dies ist eine C # -Implementierung der akzeptierten Antwort. Es ist auch ArcGis mit einem MapPoint zurückzukehren, wie das ist, was wir für dieses Projekt verwenden.

        private MapPoint GenerateLinePoint(double startPointX, double startPointY, double endPointX, double endPointY, double pointX, double pointY)
        {
            double k = ((endPointY - startPointY) * (pointX - startPointX) - (endPointX - startPointX) * (pointY - startPointY)) / (Math.Pow(endPointY - startPointY, 2) 
                + Math.Pow(endPointX - startPointX, 2));
            double resultX = pointX - k * (endPointY - startPointY);
            double resultY = pointY + k * (endPointX - startPointX);

            return new MapPoint(resultX, resultY, 0, SpatialReferences.Wgs84);
        }

Dank Ray, da dies perfekt für mich gearbeitet.

Dies ist eine vektorisiert Matlab-Funktion für paarweise Projektionen von m Punkten auf n Liniensegmente zu finden. Hier xp und yp sind m by 1 Vektoren Koordinaten m verschiedenen Punkten halten, und x1, y1, x2 und y2 sind n by 1 Vektoren Koordinaten des Start- und Endpunkte der Liniensegmente verschiedene n zu halten. Es gibt m by n Matrizen, x und y, wo x(i, j) und y(i, j) sind Koordinaten der Projektion von i-ten Punkt auf j-ten Zeile.

Die eigentliche Arbeit wird in ersten Zeilen und der Rest der Funktion getan läuft einen Selbsttest Demo, nur für den Fall, dass es ohne Parameter aufgerufen wird. Es ist relativ schnell, ich es geschafft, Projektionen von 2k Punkte auf 2k Liniensegmente in weniger als 0,05 s zu finden.

function [x, y] = projectPointLine(xp, yp, x1, y1, x2, y2)
if nargin > 0
        xd = (x2-x1)';
    yd = (y2-y1)';
    dAB = xd.*xd + yd.*yd;
    u = bsxfun(@rdivide, bsxfun(@times, bsxfun(@minus, xp, x1'), xd) + ...
        bsxfun(@times, bsxfun(@minus, yp, y1'), yd), dAB);
    x = bsxfun(@plus, x1', bsxfun(@times, u, xd));
    y = bsxfun(@plus, y1', bsxfun(@times, u, yd));
else
    nLine = 3;
    nPoint = 2;
    xp = rand(nPoint, 1) * 2 -1;
    yp = rand(nPoint, 1) * 2 -1;
    x1 = rand(nLine, 1) * 2 -1;
    y1 = rand(nLine, 1) * 2 -1;
    x2 = rand(nLine, 1) * 2 -1;
    y2 = rand(nLine, 1) * 2 -1;
    tic;
    [x, y] = projectPointLine(xp, yp, x1, y1, x2, y2);
    toc
    close all;
    plot([x1'; x2'], [y1'; y2'], '.-', 'linewidth', 2, 'markersize', 20);
    axis equal;
    hold on
    C = lines(nPoint + nLine);
    for i=1:nPoint
        scatter(x(i, :), y(i, :), 100, C(i+nLine, :), 'x', 'linewidth', 2);
        scatter(xp(i), yp(i), 100, C(i+nLine, :), 'x', 'linewidth', 2);
    end
    for i=1:nLine
        scatter(x(:, i)', y(:, i)', 100, C(i, :), 'o', 'linewidth', 2);
    end
end
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top