Як визначити, на яку сторону лінії падає ознака багатокутника?


9

У мене пересічні дані пересікаються. У даних про посилку є деякі посилки, які не перетинають лінію. Як я міг би програматично розібратися, якщо непересічна посилка знаходиться на правій чи лівій стороні лінії? Дякую.

Відповіді:


8

Використовуйте інтерфейс IHitTest . Вашою точкою запиту буде центр багатокутника, а вхідна геометрія буде лінією. Одним з результатів буде булева (bRightSide), яка підкаже вам, на якій стороні лінії ви перебуваєте.


2

Для цього можна використовувати крапковий продукт

/// <summary>
/// Used to indicate the orientation of an object in space 
/// with respect to another object
/// </summary>
public enum OrientationType
{
    Left,
    Right,
    Coincident,
    Unknown
}


/// <summary>
    /// Determines if a point is oriented left, right or coincident with
    /// a directed line. 
    /// Line direction is determined by its From and To points.
    /// </summary>
    /// <param name="p">The point to test.</param>
    /// <param name="segment">The line dividing the space</param>
    /// <returns>An OrientationType indicating the orientation.</returns>
    public static OrientationType GetPointOrientation(IPoint p, ISegment segment)
    {

        OrientationType result = OrientationType.Unknown;

        double Ax = segment.FromPoint.X;
        double Ay = segment.FromPoint.Y;
        double Bx = segment.ToPoint.X;
        double By = segment.ToPoint.Y;
        double Px = p.X;
        double Py = p.Y;

        double nDotV = ((Ay - By) * (Px - Ax)) + ((Bx - Ax) * (Py - Ay));

        if (nDotV < 0)
        {
            result = OrientationType.Right;//opposite direction to normal vector
        }
        else if (nDotV > 0)
        {
            result = OrientationType.Left;
        }
        else if (nDotV == 0)
        {
            result = OrientationType.Coincident;
        }

        return result;
    }

1
Я думаю, що варто зазначити, що ця методика вимагає, щоб вхідний рядок був лінією, що складається лише з двох вершин, оскільки вона приймає об'єкт ISegment.
Хорнбідд

Це чудово працює для правильної евклідової лінії (вся справа, а не лише сегмент чи промінь), але я впевнений, що ОП використовував "лінію" та "дані про лінії" як сипучі синоніми для поліліній, де підхід крапкового продукту не вдається .
whuber

2

Алгоритм отримання бажаного результату:

  1. Візьміть лінію у фокусі
  2. Додайте трохи буфера (0,0000005) в правій (або лівій) частині геометрії лінії.
  3. Перевірте, чи є геометрія буфера "Всередині" геометрії полігона чи "Перекриття" геометрією полігону.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.