Pergunta

Como posso desenhar uma perpendicular em um segmento de linha a partir de um determinado ponto? Meu segmento de linha é definido como (x1, y1), (x2, y2), Se eu desenhar uma perpendicular a partir de um ponto (x3, y3) e se encontra com a linha no ponto (x4, y4). Eu quero descobrir isso (x4, y4).

Foi útil?

Solução

Eu resolvi as equações para você:

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)

Onde ^ 2 significa quadrado

Outras dicas

A partir wiki :

Em álgebra, para qualquer equação linear y = mx + b, perpendiculares todos vai tem um declive de (-1 / m), o oposto recíproco da curva original. isto é útil para memorizar o slogan "para encontrar a inclinação da perpendicular linha, inverter a fracção e alterar o assinar." Lembre-se que qualquer número inteiro um é em si mais de um, e pode ser escrito como (a / 1)

Para encontrar o perpendicular de um determinado A linha que passa também através de um nomeadamente, o ponto (x, y), a resolver equação y = (-1 / m) x + b, substituindo nos valores conhecidos de m, x, y e a resolver para b.

O declive da linha, m, através de (x1, y1) e (x2, y2) é m = (y1 - y2) / (x1 - x2)

Eu concordo com peter.murray.rust, vetores fazer a solução mais clara:

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

Você vai encontrar muitas vezes que o uso de vetores torna a solução mais clara ...

Aqui está uma rotina de minha própria 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);
    }

}

Você terá que implementar real2 (um ponto) e Vector2 e dotProduct (), mas estes devem ser simples:

O código, em seguida, é algo como:

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

A biblioteca (org.xmlcml.euclid) está em: http://sourceforge.net/projects/cml/

e há testes de unidade que irá exercer este método e mostrar-lhe como usá-lo.

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

Você sabe tanto do ponto e a inclinação, então a equação para a nova linha é:

y-y3=m*(x-x3)

Uma vez que a linha é perpendicular, a inclinação é o inverso negativo. Agora você tem duas equações e pode resolver para sua interseção.

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

calcular a inclinação dos pontos linha que une (x1, y1) e (x2, y2) como m=(y2-y1)/(x2-x1)

A equação da linha que une (x1, y1) e (x2, y2), utilizando o formulário de ponto-inclinação da equação de linha, seria y-y2 = m(x-x2)

Inclinação da linha que une (x3, y3) e (x4, y4) seria -(1/m)

Mais uma vez, a equação da linha que une (x3, y3) e (x4, y4) usando forma ponto-inclinação da equação de linha, seria y-y3 = -(1/m)(x-x3)

Resolver estas duas equações de linha como você resolver uma equação linear em duas variáveis ??e os valores de x e y que você começa seria sua (x4, y4)

Espero que isso ajude.

aplausos

Saiba as encostas, tanto para o linhas, dizer encostas são M1 e M2, em seguida, m1 m2 * = -1 é a condição para perpendicularidade.

código de função Matlab para o seguinte 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 introduziu a função RegionNearest[] na versão 10, de 2014. Esta função pode ser usada para retornar uma resposta a esta pergunta:

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

Este é principalmente um duplicado da resposta de Arnkrishn. Eu só queria completar sua seção com um trecho completo código Mathematica:

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

Este é um C # implementação da resposta aceita. Ele também está usando ArcGis para retornar um MapPoint como é o que estamos usando para este projeto.

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

Graças a Ray como isso funcionou perfeitamente para mim.

Esta é uma função Matlab vectorizada para encontrar projecções de pares de pontos para os segmentos de linha m n. Aqui xp e yp são vetores m by 1 segurando coordenadas de m pontos diferentes, e x1, y1, x2 e y2 são vetores n by 1 segurando coordenadas dos pontos de início e fim de n diferentes segmentos de linha. Ele retorna matrizes m by n, x e y, onde x(i, j) e y(i, j) são coordenadas de projecção de i-th apontará para j-th linha.

O verdadeiro trabalho é feito em primeiras linhas eo resto da função executa uma demonstração de auto-teste, apenas no caso onde é chamado sem parâmetros. É relativamente rápido, eu consegui encontrar projeções de 2k pontos em 2k segmentos de linha em 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top