Перпендикуляр на линии от заданной точки - PullRequest
35 голосов
/ 28 ноября 2009

Как я могу нарисовать перпендикуляр на отрезке линии от заданной точки? Мой сегмент линии определяется как (x1, y1), (x2, y2), если я рисую перпендикуляр из точки (x3, y3), и он встречается с линией в точке (x4, y4). Я хочу это выяснить (x4, y4).

Ответы [ 12 ]

62 голосов
/ 28 ноября 2009

Я решил уравнения для вас:

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)

Где ^ 2 означает квадрат

17 голосов
/ 28 ноября 2009

С вики :

В алгебре для любого линейного уравнения y = mx + b, перпендикуляры будут все иметь наклон (-1 / м), противоположный обратный исходному склону. Это полезно запомнить лозунг найти наклон перпендикуляра линия, переверните дробь и измените знак ". Напомним, что любое целое число сам по себе, и может быть написано как (а / 1)

Чтобы найти перпендикуляр данного линия, которая также проходит через конкретную точку (х, у), решить уравнение у = (-1 / м) х + б, подставляя в известных значениях m, x и y к решить для б.

Наклон линии m через (x1, y1) и (x2, y2) равен m = (y1 - y2) / (x1 - x2)

9 голосов
/ 11 января 2014

Я согласен с peter.murray.rust, векторы делают решение более понятным:

// 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;
8 голосов
/ 28 ноября 2009

Часто вы обнаружите, что использование векторов делает решение более понятным ...

Вот процедура из моей собственной библиотеки:

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

}

Вам нужно будет реализовать Real2 (точка) и Vector2 и dotProduct (), но они должны быть простыми:

Код выглядит примерно так:

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

Библиотека (org.xmlcml.euclid) находится по адресу: http://sourceforge.net/projects/cml/

и есть модульные тесты, которые будут использовать этот метод и покажут вам, как его использовать.

@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);
}
7 голосов
/ 28 ноября 2009

Вы знаете и точку, и наклон, поэтому уравнение для новой линии:

y-y3=m*(x-x3)

Поскольку линия перпендикулярна, наклон отрицательный обратный. Теперь у вас есть два уравнения и вы можете решить для их пересечения.

y-y3=-(1/m)*(x-x3)
y-y1=m*(x-x1)
3 голосов
/ 28 ноября 2009

Вычислить наклон точек, соединяющих линии (x1, y1) и (x2, y2), как m=(y2-y1)/(x2-x1)

Уравнение соединения линий (x1, y1) и (x2, y2) с использованием формы линейного уравнения с наклоном точки будет равно y-y2 = m(x-x2)

Наклон линии, соединяющей (x3, y3) и (x4, y4), будет -(1/m)

Опять же, уравнение соединения линий (x3, y3) и (x4, y4) с использованием формы линейного уравнения с наклоном точки будет иметь вид y-y3 = -(1/m)(x-x3)

Решите эти два линейных уравнения, когда вы решите линейное уравнение с двумя переменными, и значения x и y, которые вы получите, будут вашими (x4, y4)

Надеюсь, это поможет.

ура

2 голосов
/ 09 марта 2016

Код функции Matlab для следующей задачи

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
2 голосов
/ 28 ноября 2009

Узнайте склоны для обоих линии, скажем, наклоны m1 и m2, то м1 * м2 = -1 является условием для перпендикулярность.

1 голос
/ 10 января 2017

Это в основном дубликат ответа Арнкришна. Я просто хотел завершить его раздел полным фрагментом кода Mathematica:

m = (y2 - y1)/(x2 - x1)
eqn1 = y - y3 == -(1/m)*(x - x3)
eqn2 = y - y1 == m*(x - x1)
Solve[eqn1 && eqn2, {x, y}]
1 голос
/ 10 января 2017

Mathematica представила функцию RegionNearest[] в версии 10, 2014. Эту функцию можно использовать, чтобы вернуть ответ на этот вопрос:

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