Perpendicolare su una linea da un determinato punto
-
06-07-2019 - |
Domanda
Come posso disegnare una perpendicolare su un segmento di linea da un determinato punto? Il mio segmento di linea è definito come (x1, y1), (x2, y2), se disegno una perpendicolare da un punto (x3, y3) e si incontra con la linea sul punto (x4, y4). Voglio scoprirlo (x4, y4).
Soluzione
Ho risolto le equazioni per te:
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)
Dove ^ 2 significa quadrato
Altri suggerimenti
Da wiki :
In algebra, per qualsiasi equazione lineare y = mx + b, le perpendicolari saranno tutte hanno una pendenza di (-1 / m), l'opposto reciproco della pendenza originale. esso è utile per memorizzare lo slogan "in trova la pendenza della perpendicolare linea, capovolgi la frazione e cambia il segno ".; Ricorda che qualsiasi numero intero a è esso stesso sopra uno e può essere scritto come (a / 1)
Per trovare la perpendicolare di un dato linea che attraversa anche a punto particolare (x, y), risolvi il equazione y = (-1 / m) x + b, in sostituzione nei valori noti di m, x e y a risolvere per b.
La pendenza della linea, m, attraverso (x1, y1) e (x2, y2) è m = (y1 - y2) / (x1 - x2)
Sono d'accordo con peter.murray.rust, i vettori rendono la soluzione più chiara:
// 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;
Scoprirai spesso che l'uso dei vettori rende la soluzione più chiara ...
Ecco una routine dalla mia libreria:
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);
}
}
Dovrai implementare Real2 (un punto) e Vector2 e dotProduct () ma questi dovrebbero essere semplici:
Il codice appare quindi come:
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);
La libreria (org.xmlcml.euclid) è su: http://sourceforge.net/projects/cml/
e ci sono test unitari che eserciteranno questo metodo e ti mostreranno come usarlo.
@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);
}
Conosci sia il punto che la pendenza, quindi l'equazione per la nuova linea è:
y-y3=m*(x-x3)
Poiché la linea è perpendicolare, la pendenza è il reciproco negativo. Ora hai due equazioni e puoi risolvere la loro intersezione.
y-y3=-(1/m)*(x-x3)
y-y1=m*(x-x1)
Calcola la pendenza della linea unendo i punti (x1, y1) e (x2, y2) come m=(y2-y1)/(x2-x1)
L'equazione della linea che unisce (x1, y1) e (x2, y2) usando la forma punto-pendenza dell'equazione della linea, sarebbe y-y2 = m (x-x2)
La pendenza della linea che unisce (x3, y3) e (x4, y4) sarebbe -(1/m)
Ancora una volta, l'equazione della linea che unisce (x3, y3) e (x4, y4) usando la forma punto-pendenza dell'equazione della linea, sarebbe y-y3 = - (1 / m) (x-x3)
Risolvi queste due equazioni di linea mentre risolvi un'equazione lineare in due variabili e i valori di xey che otterrai sarebbero i tuoi (x4, y4)
Spero che questo aiuti.
applausi
Scopri le piste per entrambi le linee, diciamo che le pendenze sono m1 e m2 allora m1 * m2 = -1 è la condizione per perpendicolarità.
Codice funzione Matlab per il seguente problema
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 ha introdotto la funzione RegionNearest []
nella versione 10, 2014. Questa funzione potrebbe essere utilizzata per restituire una risposta a questa domanda:
{x4,y4} = RegionNearest[Line[{{x1,y1},{x2,y2}}],{x3,y3}]
Questo è principalmente un duplicato della risposta di Arnkrishn. Volevo solo completare la sua sezione con uno snippet di codice Mathematica completo:
m = (y2 - y1)/(x2 - x1)
eqn1 = y - y3 == -(1/m)*(x - x3)
eqn2 = y - y1 == m*(x - x1)
Solve[eqn1 && eqn2, {x, y}]
Questa è un'implementazione in C # della risposta accettata. Sta anche usando ArcGis per restituire un MapPoint poiché è quello che stiamo usando per questo progetto.
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);
}
Grazie a Ray perché ha funzionato perfettamente per me. c # arcgis
Questa è una funzione Matlab vettoriale per trovare proiezioni a coppie di punti m
su segmenti di linea n
. Qui xp
e yp
sono vettori m by 1
con coordinate di m
punti diversi e x1
, y1
, x2
e y2
sono vettori n by 1
che contengono le coordinate dei punti iniziale e finale di n
segmenti di linea diversi.
Restituisce le matrici m by n
, x
e y
, dove x (i, j)
e y (i, j)
sono coordinate di proiezione di i
-th point su j
-th line.
Il lavoro effettivo viene eseguito nelle prime righe e il resto della funzione esegue una demo di auto-test, nel caso in cui venga chiamato senza parametri. È relativamente veloce, sono riuscito a trovare proiezioni di punti 2k su segmenti di linea 2k in meno di 0,05 secondi.
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