Подтвердить что ты не робот

Перпендикулярно отрезку линии от заданной точки

Я хочу вычислить точку на заданной прямой, перпендикулярную к данной точке.

У меня есть отрезок AB и есть сегмент внешней линии точки C. Я хочу вычислить точку D на AB так, что CD перпендикулярен AB.

Find point D

Мне нужно найти точку D.

Это очень похоже на this, но я хочу рассмотреть и координату Z, так как она не отображается правильно в 3D-пространстве.

4b9b3361

Ответ 1

Доказательство: Точка D находится на линии CD, перпендикулярной AB, и, конечно, D принадлежит AB. Запишем произведение Dot двух векторов CD.AB = 0 и выражаем факт, что D принадлежит AB как D = A + t (B-A).

В итоге получим 3 уравнения:

 Dx=Ax+t(Bx-Ax)
 Dy=Ay+t(By-Ay)
(Dx-Cx)(Bx-Ax)+(Dy-Cy)(By-Ay)=0

Подставляем первые два уравнения в третий:

(Ax+t(Bx-Ax)-Cx)(Bx-Ax)+(Ay+t(By-Ay)-Cy)(By-Ay)=0

Распространение решения для t дает:

(Ax-Cx)(Bx-Ax)+t(Bx-Ax)(Bx-Ax)+(Ay-Cy)(By-Ay)+t(By-Ay)(By-Ay)=0

который дает:

t= -[(Ax-Cx)(Bx-Ax)+(Ay-Cy)(By-Ay)]/[(Bx-Ax)^2+(By-Ay)^2]

избавление от отрицательных знаков:

t=[(Cx-Ax)(Bx-Ax)+(Cy-Ay)(By-Ay)]/[(Bx-Ax)^2+(By-Ay)^2]

Как только у вас есть t, вы можете определить координаты для D из первых двух уравнений.

 Dx=Ax+t(Bx-Ax)
 Dy=Ay+t(By-Ay)

Ответ 2

function getSpPoint(A,B,C){
    var x1=A.x, y1=A.y, x2=B.x, y2=B.y, x3=C.x, y3=C.y;
    var px = x2-x1, py = y2-y1, dAB = px*px + py*py;
    var u = ((x3 - x1) * px + (y3 - y1) * py) / dAB;
    var x = x1 + u * px, y = y1 + u * py;
    return {x:x, y:y}; //this is D
}

question

Ответ 3

Для этого есть простое замкнутое решение (не требующее петель или аппроксимаций) с использованием векторного точечного произведения.

Представьте свои точки как векторы, где точка A находится в начале координат (0,0), и все остальные точки ссылаются на нее (вы можете легко преобразовать свои точки в этот опорный кадр, вычитая точку A из каждой точки).

В этой точке отсчета D является просто вектор проекции точки C на вектор B, который выражается в виде:

// Per wikipedia this is more efficient than the standard (A . Bhat) * Bhat
Vector projection = Vector.DotProduct(A, B) / Vector.DotProduct(B, B) * B

Вектор результата можно преобразовать обратно в исходную систему координат, добавив к нему точку A.

Ответ 4

Точку на линии AB можно параметризовать:

M (x) = A + x * (B-A), для вещественного x.

Вы хотите, чтобы D = M (x), что DC и AB ортогональны:

точка (В-А, С-М (х)) = 0.

То есть: точка (B-A, C-A-x * (B-A)) = 0 или точка (B-A, C-A) = x * точка (B-A, B-A), дающая:

x = точка (B-A, C-A)/точка (B-A, B-A), которая определена, если A = B.

Ответ 6

Здесь я преобразовал ответный код из "cuixiping" в код 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

Ответ 7

Поскольку вы не указываете, какой язык вы используете, я дам вам общий ответ:

Просто проведите петлю, проходящую через все точки вашего сегмента AB, "отрисуйте отрезок" до C от них, получите расстояние от C до D и от A до D и примените теорему pithagoras. Если AD ^ 2 + CD ^ 2 = AC ^ 2, вы нашли свою точку.

Кроме того, вы можете оптимизировать свой код, запустив цикл по кратчайшей (учитывая стороны AD и BD), так как вы найдете эту точку раньше.

Ответ 8

Я не видел ответа на этот вопрос, но у Рона Уорхолика было большое предложение с Vector Projection. ACD - просто правый треугольник.

  • Создайте вектор AC i.e(Cx-Ax, Cy-Ay)
  • Создайте вектор AB i.e(Bx - Ax, By - Ay)
  • Точечный продукт AC и AB равен косинусу угла между векторами. i.e cos (theta) = ACx * ABx + ACy * ABy.
  • Длина вектора - это sqrt (x * x + y * y)
  • Длина AD = cos (theta) * длина (AC)
  • Нормализовать AB i.e(ABx/length (AB), ABy/length (AB))
  • D = A + NAB * length (AD)

Ответ 9

Вот реализация python на основе ответа Кори Огберна из этого потока.
Он проецирует точку q на сегмент линии, определяемый p1 и p2, в результате чего точка r.
Он вернет значение null, если r выходит за пределы сегмента строки:

def is_point_on_line(p1, p2, q):

    if (p1[0] == p2[0]) and (p1[1] == p2[1]):
        p1[0] -= 0.00001

    U = ((q[0] - p1[0]) * (p2[0] - p1[0])) + ((q[1] - p1[1]) * (p2[1] - p1[1]))
    Udenom = math.pow(p2[0] - p1[0], 2) + math.pow(p2[1] - p1[1], 2)
    U /= Udenom

    r = [0, 0]
    r[0] = p1[0] + (U * (p2[0] - p1[0]))
    r[1] = p1[1] + (U * (p2[1] - p1[1]))

    minx = min(p1[0], p2[0])
    maxx = max(p1[0], p2[0])
    miny = min(p1[1], p2[1])
    maxy = max(p1[1], p2[1])

    is_valid = (minx <= r[0] <= maxx) and (miny <= r[1] <= maxy)

    if is_valid:
        return r
    else:
        return None