Pregunta

¿Cómo puedo dibujar una perpendicular en un segmento de línea desde un punto dado? Mi segmento de línea se define como (x1, y1), (x2, y2), si dibujo una perpendicular desde un punto (x3, y3) y se une a la línea en el punto (x4, y4). Quiero averiguar esto (x4, y4).

¿Fue útil?

Solución

Resolví las ecuaciones por ti:

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)

Donde ^ 2 significa al cuadrado

Otros consejos

De wiki :

  

En álgebra, para cualquier ecuación lineal   y = mx + b, todos los perpendiculares serán   tener una pendiente de (-1 / m), lo contrario   recíproco de la pendiente original. Eso   es útil para memorizar el eslogan "   encontrar la pendiente de la perpendicular   línea, voltear la fracción y cambiar el   signo. Recordemos que cualquier número entero a   está en sí mismo sobre uno, y se puede escribir   como (a / 1)

     

Para encontrar la perpendicular de un determinado   línea que también pasa por un   punto particular (x, y), resuelve el   ecuación y = (-1 / m) x + b, sustituyendo   en los valores conocidos de m, x e y para   resolver para b.

La pendiente de la línea, m, a través de (x1, y1) y (x2, y2) es m = (y1 - y2) / (x1 - x2)

Estoy de acuerdo con peter.murray.rust, los vectores aclaran la solución:

// 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;

A menudo encontrará que el uso de vectores aclara la solución ...

Aquí hay una rutina de mi propia biblioteca:

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);
    }

}

Tendrá que implementar Real2 (un punto) y Vector2 y dotProduct (), pero estos deben ser simples:

El código se parece a:

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 biblioteca (org.xmlcml.euclid) está en: http://sourceforge.net/projects/cml/

y hay pruebas unitarias que ejercitarán este método y le mostrarán cómo 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);
}

Usted sabe tanto el punto como la pendiente, por lo que la ecuación para la nueva línea es:

y-y3=m*(x-x3)

Dado que la línea es perpendicular, la pendiente es el recíproco negativo. Ahora tiene dos ecuaciones y puede resolver su intersección.

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

Calcule la pendiente de los puntos de unión de línea (x1, y1) y (x2, y2) como m=(y2-y1)/(x2-x1)

La ecuación de la unión de línea (x1, y1) y (x2, y2) usando la forma de punto-pendiente de la ecuación de línea, sería y-y2 = m (x-x2)

La pendiente de la línea que une (x3, y3) y (x4, y4) sería -(1/m)

Nuevamente, la ecuación de la unión de línea (x3, y3) y (x4, y4) usando la forma de punto-pendiente de la ecuación de línea, sería y-y3 = - (1 / m) (x-x3)

Resuelve estas dos ecuaciones de línea a medida que resuelves una ecuación lineal en dos variables y los valores de x e y que obtendrías serían tu (x4, y4)

Espero que esto ayude.

saludos

  

Descubre las pendientes tanto para el   líneas, digamos que las pendientes son m1 y m2 entonces    m1 * m2 = -1 es la condición para   perpendicularidad.

Código de función de Matlab para el siguiente 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 introdujo la función RegionNearest [] en la versión 10, 2014. Esta función podría usarse para devolver una respuesta a esta pregunta:

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

Esto es principalmente un duplicado de la respuesta de Arnkrishn. Solo quería completar su sección con un fragmento de código de 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}]

Esta es una implementación en C # de la respuesta aceptada. También está usando ArcGis para devolver un MapPoint, ya que eso es lo que estamos usando para este proyecto.

        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);
        }

Gracias a Ray ya que esto funcionó perfectamente para mí.

Esta es una función vectorizada de Matlab para encontrar proyecciones por pares de puntos m en segmentos de línea n . Aquí xp y yp son vectores m por 1 que tienen coordenadas de m puntos diferentes, y x1 , y1 , x2 y y2 son vectores n por 1 que contienen coordenadas de los puntos inicial y final de n diferentes segmentos de línea. Devuelve m por n matrices, x e y , donde x (i, j) y y (i, j) son coordenadas de proyección de i -th punto en j -th line.

El trabajo real se realiza en las primeras líneas y el resto de la función ejecuta una demostración de autocomprobación, en caso de que se llame sin parámetros. Es relativamente rápido, logré encontrar proyecciones de 2k puntos en segmentos de línea de 2k en menos de 0.05s.

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top