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

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

Ответы [ 12 ]

0 голосов
/ 28 мая 2019

Это векторизованная функция Matlab для нахождения парных проекций m точек на n отрезки линии. Здесь xp и yp являются m by 1 векторами, содержащими координаты m различных точек, а x1, y1, x2 и y2 являются n by 1 векторами, содержащими координаты начальной и конечной точек n различных отрезков. Возвращает m by n матрицы, x и y, где x(i, j) и y(i, j) являются координатами проекции i -ой точки на j -ую линию.

Фактическая работа выполняется в первые несколько строк, а остальная часть функции запускает демонстрацию самопроверки, на случай, если она вызывается без параметров. Это относительно быстро, мне удалось найти проекции 2k точек на отрезки линии 2k менее чем за 0,05 с.

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
0 голосов
/ 01 мая 2019

Это реализация принятого ответа на C #. Он также использует ArcGis для возврата MapPoint, поскольку именно это мы используем для этого проекта.

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

Спасибо Рэю, потому что это отлично сработало для меня.

...