Как определить тип полигона

Пользователь вводит n-е пункты. Мне нужно проверить, существует ли многоугольник, а затем определить тип — вогнутый или выпуклый многоугольник. Я знаю, что многоугольник является выпуклым, если каждый из его углов меньше 180 градусов. Таким образом, проблема сводится к поиску каждого внутреннего угла многоугольника. Я искал формулу или алгоритм, но безуспешно.

Пример:

Вход: n = 4;

Точка 1: (5; 6)

Точка 2: (4; -5)

Точка 3: (-5; 4)

Точка 4: (-5; 5)

Ожидаемый результат: полигон выпуклый

пример

Пока это код: прямо сейчас он находит только максимальное и минимальное расстояние между точками на плоскости.

#include "stdafx.h"#include <iostream>
using namespace std;

int main()
{
double a[15][2];
int n;
cin >> n;
if (n <= 0 && n > 15)
return 1;

for (int i = 0; i < n; i++)
{
cout << "x" << i << " = , y" << i << " = ";
cin >> a[i][0] >> a[i][1];
}

double maxDistance = 0.0;
double minDistance = 0.0;
double maxpoint1[2];
double maxpoint2[2];
double minpoint1[2];
double minpoint2[2];

for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (j != i)
{
double x1 = a[i][0];
double x2 = a[j][0];
double y1 = a[i][1];
double y2 = a[j][1];
double currentDistance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));

if (currentDistance > maxDistance)
{
maxDistance = currentDistance;
maxpoint1[0] = x1;
maxpoint1[1] = y1;
maxpoint2[0] = x2;
maxpoint2[1] = y2;

}

if (minDistance > currentDistance)
{
currentDistance = minDistance;
minpoint1[0] = x1;
minpoint1[1] = y1;
minpoint2[0] = x2;
minpoint2[1] = y2;
}

cout << "x1 = " << x1 << " y1 = " << y1 << " x2 = " << x2 << " y2 = " << y2;
cout << endl << "Distance is " << currentDistance;
cout << endl;
}
}
}

cout << "The max distance is: " << maxDistance << " between x1 = " << maxpoint1[0] << " y1 = " << maxpoint1[1] << " and x2 = " << maxpoint2[0] << " y2 = " << maxpoint2[1];
cout << "The min distance is: " << minDistance << " between x1 = " << minpoint1[0] << " y1 = " << minpoint1[1] << " and x2 = " << minpoint2[0] << " y2 = " << minpoint2[1];return 0;
}

2

Решение

Чтобы определить, является ли многоугольник выпуклым или вогнутым, просто проверьте признаки перекрестных произведений для всех последовательных точечных триплетов. CrossProduct(P[0], P[1], P[2]) etc, Как пример

CrossProductSign(A, B, C) =
SignOf((B.X - A.X) * (C.Y - B.Y) - (B.Y - A.Y) * (C.X - B.X))

Для выпуклой формы все перекрестные произведения должны иметь одинаковый знак (+ или -).

Как это работает: для выпуклого многоугольника каждый триплет поворачивается в одну сторону (или CW, или CCW в зависимости от направления ходьбы). Для вогнутых некоторые знаки будут отличаться (где внутренний угол превышает 180 градусов). Обратите внимание, что вам не нужно рассчитывать значения углов.

3

Другие решения

Если вы хотите найти угол между двумя сторонами, используйте перекрестное или точечное произведение векторов.

точка b = | a || b | cos (angle_between_vectors) = a [0] * b [0] + a [1] * b [1] + a [2] * b [2]

внутренний угол будет (pi — angle_between_vectors)

О, кстати, многоугольник может пересекаться сам по себе, что также вредно во многих случаях. Ваше определение не сможет обнаружить это … например сложный квад будет иметь все углы менее 90 градусов.

Это не единственный способ определить, является ли многоугольник выпуклым, и, возможно, один из наиболее сложных для вычисления?
Проблема с точечным произведением состоит в том, что его знак будет отображаться, если угол меньше или больше, чем pi / 2. Правильный способ определить, является ли ваш многоугольник сложным или невыпуклым, состоит в том, чтобы проверить, изменяется ли направление поворота. Для этого вам понадобится перекрестный продукт. Для 2d векторов результат их перекрестного произведения получил только z компонент (перпендикулярно плоскости), его знак определяет, в каком направлении произошло вращение.

Вопрос уже был здесь.

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

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector