Определите, представляет ли дуга рефлекс или острый угол - PullRequest
0 голосов
/ 08 июня 2018

У меня есть эта, казалось бы, простая, но очень запутанная проблема.

Учитывая, что у меня есть набор вершин (x1, y1), (x2, y2), (x3, y3) ...... представляющихдуга.Точки могут быть либо по часовой стрелке, либо против часовой стрелки, но все они расположены одинаково.И я знаю центр дуги (xc, yc).

Как я могу определить, соответствует ли дуга острому / тупому или рефлекторному углу?

Одно очевидное решение - принять разницуatan2 ((last_pt) - (в центре)) и atan2 ((first_pt) - (в центре))).Но если дуга проходит через точку, где PI становится -PI, этот метод ломается.

Кроме того, поскольку точки дуги получаются из довольно зашумленного пиксельного изображения, вершины не совсем гладкие.

Изображение острой и рефлекторной дуги

Я не могу обернуть свой мозг вокруг решения этой проблемы.

Спасибо за помощь!

1 Ответ

0 голосов
/ 09 июня 2018

Работа с 2D углами - это боль по описанной вами причине, поэтому лучше работать с векторной математикой, которая не зависит от вращения.

Определить 2D кросс-произведение ,A ^ B = Ax * By - Ay * Bx.Это положительно, если A повернут по часовой стрелке относительно B, и наоборот.

Логика:

  • Вычислить C = (last_pt - center) ^ (first_pt - center)
  • Если C = 0, дуга либо замкнута, либо на 180 градусов (забыла имя для этого)
  • Если C > 0, дуга должна быть (i) по часовой стрелке и острый / тупой или (ii) против часовой стрелки и рефлекс
  • Если C < 0, применяется обратное

Псевдокод:

int arc_type(Point first, Point last, Point center, bool clockwise)
{
    // cross-product
    float C = (last.x - center.x) * (first.y - center.y)
            - (last.y - center.y) * (first.x - center.x);

    if (Math.abs(C) < /* small epsilon */)
        return 0;                      // 180-degree

    return ((C > 0) ^ clockwise) ? 1   // reflex
                                 : -1; // acute / obtuse
}

Обратите внимание, что если у вас нет предварительных сведений о том, является ли дуга по часовой стрелке или против, вы можете использовать один и тот же метод перекрестного произведения для смежных точек.Вам нужно убедиться, что порядок точек соответствует - если нет, снова используя перекрестное произведение, отсортируйте их по (относительному) углу.

...