문제

포인트가 특정 줄에 속하는지 어떻게 알 수 있습니까?

가능하면 예제에 감사합니다.

도움이 되었습니까?

해결책

가장 간단한 형태로 좌표를 선 방정식에 연결하고 평등을 확인하십시오.

주어진:

Point p (X=4, Y=5)
Line l (Slope=1, YIntersect=1)

X와 Y를 연결합니다.

   Y = Slope * X + YIntersect
=> 5 = 1 * 4 + 1
=> 5 = 5

그렇습니다. 요점은 줄에 있습니다.

라인이 (x1, y1), (x2, y2) 형태로 표시되면 다음과 같이 기울기를 계산할 수 있습니다.

 Slope = (y1 - y2) / (x1-x2)

그런 다음 y-intersect를 가져옵니다.

 YIntersect = - Slope * X1 + Y1;

편집 : y-intersect를 수정했습니다 (x1 / y1입니다 ...)

당신은 그것을 확인해야합니다 x1 - x2 아니다 0. 그것이 있다면, 포인트가 줄에 있는지 확인하는 것은 포인트의 y 값이 어느 쪽인지 확인하는 간단한 문제입니다. x1 또는 x2. 또한 포인트의 X가 'x1'또는 'x2'가 아닌지 확인하십시오.

다른 팁

방금 드로잉 응용 프로그램 에서이 점검을 사용한 이후 몇 가지 추가 요구 사항을 처리하는 기능을 작성했습니다.

  • 퍼지 - 함수는 라인을 클릭하여 선을 선택하는 데 사용되므로 오류의 공간이 있어야합니다.
  • 선은 끝점과 시작점, 무한 선이 없습니다.
  • 직선 수직 및 수평선을 처리해야합니다.
private const double SELECTION_FUZZINESS = 3;

internal override bool ContainsPoint(Point point)
{
    LineGeometry lineGeo = geometry as LineGeometry;
    Point leftPoint;
    Point rightPoint;

    // Normalize start/end to left right to make the offset calc simpler.
    if (lineGeo.StartPoint.X <= lineGeo.EndPoint.X)
    {
        leftPoint   = lineGeo.StartPoint;
        rightPoint  = lineGeo.EndPoint;
    }
    else
    {
        leftPoint   = lineGeo.EndPoint;
        rightPoint  = lineGeo.StartPoint;
    }

    // If point is out of bounds, no need to do further checks.                  
    if (point.X + SELECTION_FUZZINESS < leftPoint.X || rightPoint.X < point.X - SELECTION_FUZZINESS)
        return false;
    else if (point.Y + SELECTION_FUZZINESS < Math.Min(leftPoint.Y, rightPoint.Y) || Math.Max(leftPoint.Y, rightPoint.Y) < point.Y - SELECTION_FUZZINESS)
        return false;

    double deltaX = rightPoint.X - leftPoint.X;
    double deltaY = rightPoint.Y - leftPoint.Y;

    // If the line is straight, the earlier boundary check is enough to determine that the point is on the line.
    // Also prevents division by zero exceptions.
    if (deltaX == 0 || deltaY == 0) 
        return true;

    double slope        = deltaY / deltaX;
    double offset       = leftPoint.Y - leftPoint.X * slope;
    double calculatedY  = point.X * slope + offset;

    // Check calculated Y matches the points Y coord with some easing.
    bool lineContains = point.Y - SELECTION_FUZZINESS <= calculatedY && calculatedY <= point.Y + SELECTION_FUZZINESS;

    return lineContains;            
}

포인트 r = (rx, ry)가 줄 연결점 p = (px, py) 및 q = (qx, qy)에 있는지 여부를 결정하는 가장 좋은 방법은 매트릭스의 결정 요인을 확인하는 것입니다.

{{qx - px, qy - py}, {rx - px, ry - py}},

즉 (QX -PX) * (RY -PY) - (QY -PY) * (RX -PX)는 0에 가깝습니다.이 솔루션은 게시 된 다른 것보다 몇 가지 관련 이점이 있습니다. 첫째, 수직선에 대한 특별한 경우는 필요하지 않습니다. 둘째, 나누지 않고 (일반적으로 느린 작동), 셋째, 라인이 거의 수직 일 때 잘못된 부동 소수점 동작을 유발하지는 않습니다.

라인에 두 가지 점이 주어졌습니다 L0 그리고 L1 그리고 테스트 요점 P.

               (L1 - L0) * (P - L0)
n = (P - L0) - --------------------- (L1 - L0)
               (L1 - L0) * (L1 - L0)

벡터의 표준 n 요점의 거리입니다 P 라인에서 L0 그리고 L1. 이 거리가 0이거나 작은 경우 (반올림 오류의 경우) 점은 선 위에 있습니다.

상징물 * 도트 제품을 나타냅니다.

예시

P = (5, 5)

L0 = (0, 10)
L1 = (20, -10)

L1 - L0 = (20, -20)
P  - L0 = (5, -5)

              (20, -20) * (5, -5)
n = (5, -5) - --------------------- (20, -20)
              (20, -20) * (20, -20)

              200
  = (5, -5) - --- (20, -20)
              800

  = (5, -5) - (5, -5)

  = (0, 0)

패트릭 맥도날드 씨는 거의 정답을 썼고 이것이 그의 대답의 수정이라고 생각합니다.

public bool IsOnLine(Point endPoint1, Point endPoint2, Point checkPoint)
{
    return (((double)checkPoint.Y - endPoint1.Y)) / ((double)(checkPoint.X - endPoint1.X))
        == ((double)(endPoint2.Y - endPoint1.Y)) / ((double)(endPoint2.X - endPoint1.X));
}

물론 다른 많은 정답이 특히 많지만 조쉬 씨는 이것이 가장 좋은 것으로 나타났습니다.

Evryone에 감사드립니다.

y = m * x + c

이것은 선의 방정식입니다. X & Y는 코디네스입니다. 각 라인은 기울기 (m)와 y 축 (c)과 교차하는 곳으로 특징 지어집니다.

따라서 라인의 M & C가 주어지면, 지점 (x1, y1)이 방정식이 x = x1 및 y = y1에 대한 방정식을 확인하여 줄에 있는지 확인할 수 있습니다.

엔드 포인트로 정의 된 선이있는 경우

PointF pt1, pt2;

그리고 당신은 당신이 확인하고 싶은 지점이 있습니다

PointF checkPoint;

그런 다음 함수를 다음과 같이 정의 할 수 있습니다.

bool IsOnLine(PointF endPoint1, PointF endPoint2, PointF checkPoint) 
{
    return (checkPoint.Y - endPoint1.Y) / (endPoint2.Y - endPoint1.Y)
        == (checkPoint.X - endPoint1.X) / (endPoint2.X - endPoint1.X);
}

다음과 같이 부릅니다.

if (IsOnLine(pt1, pt2, checkPoint) {
    // Is on line
}

그래도 Zero의 분할을 확인해야합니다.

2D 라인은 일반적으로 두 변수 X와 Y의 방정식을 사용하여 표시됩니다. 여기에는 잘 알려진 방정식이 있습니다.

y-y1 = (y1-y2)/(x1-x2) (x-x1)

이제 GDI+ 라인이 (0,0)에서 (100, 100)에서 그려져 있다고 상상해보십시오. M = (0-100)/(0-100) = 1이므로 라인의 방정식은 y-0 = 1입니다. *(x-0) => y = x

이제 우리는 문제의 라인에 대한 방정식을 가지고 있기 때문에 포인트 가이 줄에 속하는지 테스트하기 쉽습니다. 주어진 점 (x3, y3)은 x = x3 및 y = y3을 대체 할 때 라인 방정식을 만족하면이 라인에 속합니다. 예를 들어, 점 (10, 10)은 10 = 10 이후이 줄에 속하지만 (10,12)는 12! = 10 이후이 줄에 속하지 않습니다.

참고 : 수직선의 경우 기울기 (m)의 값은 무한하지만이 특수한 경우에는 직접 x = c 인 수직선의 방정식을 사용할 수 있습니다. 여기서 c = x1 = x2.

비록 이것이 이것이 가장 효율적인 방법인지 확실하지 않습니다. 더 많은 시간이있을 때 더 효율적인 방법을 찾아 보겠습니다.

도움이 되었기를 바랍니다.

라인의 방정식은 다음과 같습니다.

y = mx + c

그래서이 방정식을 만족 시키면 포인트 (A, B) 가이 줄에 있습니다. b = ma + c

더 구체적 일 수 있습니까?

어떤 프로그래밍 언어에 대해 이야기하고 있습니까?

어떤 환경에 대해 이야기하고 있습니까?

당신은 어떤 "라인"에 대해 이야기하고 있습니까? 텍스트? 어떤 요점? 화면에 XY?

대안으로 slope/y-intercept 방법, 나는이 접근법을 사용하여 선택했다 Math.Atan2:

// as an extension method
public static bool Intersects(this Vector2 v, LineSegment s) {
    //  check from line segment start perspective
    var reference = Math.Atan2(s.Start.Y - s.End.Y, s.Start.X - s.End.X);
    var aTanTest = Math.Atan2(s.Start.Y - v.Y, s.Start.X - v.X);

    //  check from line segment end perspective
    if (reference == aTanTest) {
        reference = Math.Atan2(s.End.Y - s.Start.Y, s.End.X - s.Start.X);
        aTanTest = Math.Atan2(s.End.Y - v.Y, s.End.X - v.X);
    }

    return reference == aTanTest;
}

첫 번째 수표 reference 라인 세그먼트의 시작점에서 엔드 포인트까지 ArcTan을 결정합니다. 그런 다음 시작점 관점에서 ArcTan을 벡터로 결정합니다. v.

이러한 값이 동일하면 엔드 포인트의 관점에서 확인합니다.

단순하고 손잡이 수평, 수직 및 그 사이의 모든 내용.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top