문제

주어진 지점에서 라인 세그먼트에 수직을 어떻게 그릴 수 있습니까? 내 라인 세그먼트는 지점 (x3, y3)에서 수직을 그리면 (x4, y4)에서 수직을 그리면 (x1, y1), (x2, y2)로 정의됩니다. 나는 이것을 알고 싶다 (x4, y4).

도움이 되었습니까?

해결책

나는 당신을위한 방정식을 해결했습니다.

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는 제곱을 의미합니다

다른 팁

에서 위키:

대수에서, 임의의 선형 방정식 y = mx + b의 경우, 수직은 모두 (-1/m)의 기울기를 갖습니다. "수직선의 경사를 찾아서 분수를 뒤집고 부호를 변경하기 위해 슬로건을 외우는 것이 도움이됩니다. 정수 A 자체가 하나 이상이며 (a/1)으로 쓸 수 있습니다.

특정 지점 (x, y)을 통과하는 주어진 라인의 수직을 찾으려면, m, x 및 y의 알려진 값으로 대체하여 방정식 y = (-1/m) x + b 방정식을 해결하십시오. b.

라인의 기울기, m, (x1, y1) 및 (x2, y2)는 m = (y1 -y2) / (x1 -x2)입니다.

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;

벡터를 사용하여 솔루션을 더 명확하게 만듭니다.

다음은 내 도서관의 일상입니다.

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

당신은 포인트와 경사를 모두 알고 있으므로 새 선 방정식은 다음과 같습니다.

y-y3=m*(x-x3)

선은 수직이므로 경사는 음의 상호입니다. 이제 두 가지 방정식이 있으며 교차로를 해결할 수 있습니다.

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

선 결합 지점 (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)입니다.

이게 도움이 되길 바란다.

건배

두 선 모두에 대한 경사면을 찾으십시오. 경사는 M1과 M2라고 말합니다. M1*M2 = -1 수직의 조건입니다.

다음 문제에 대한 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

Mathematica는이 기능을 소개했습니다 RegionNearest[] 이 기능은이 질문에 대한 답을 반환하는 데 사용될 수 있습니다.

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

이것은 주로 Arnkrishn의 답변의 복제입니다. 방금 완전한 Mathematica 코드 스 니펫으로 그의 섹션을 완성하고 싶었습니다.

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

이것은 허용 된 답변의 C# 구현입니다. 또한 Arcgis를 사용 하여이 프로젝트에 사용하는 것입니다.

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

Ray에게 감사드립니다. 이것이 저에게 완벽하게 작동했습니다.

이것은 쌍별 예측을 찾기위한 벡터화 된 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-Th Point j-TH 라인.

실제 작업은 처음 몇 줄로 수행되며 나머지 기능은 매개 변수가없는 경우 자체 테스트 데모를 실행합니다. 상대적으로 빠르며 0.05 초 미만의 2K 라인 세그먼트에 2K 포인트를 투사했습니다.

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top