Выпуклый многоугольник - C (СИ)
Формулировка задачи:
Очень нужно решить одну задачку, половину вроде бы сделал, но что-то не то, помогите, если сможете, пожалуйста. Фишка в том, что её нужно решить с подпрограммой
Сейчас объясню задумку. Например, мы задали 5-ти угольник. Вершины обзовём, соответсвенно 1, 2, 3, 4 и 5. Я провожу линию через точки 1 и 3 и проверяю формулой выше, находятся ли точки 2 и 4 по одну сторону относительно этой линии, или же по разные. И так проверяю кажду точку, потом строю другую прямую через 2 и 4 вершину и проверяю точки снова. Если они находятся по разные стороны, то это выпуклый многоугольник, если же нет, то вогнутый. Посоветуйте пожалуйста что-нибудь, а то я вообще без понятия что дальше делать... И ещё эта подпрограмма..
Заранее спасибо!
Выпуклый многоугольник
Многоугольник задан координатами своих вершин при их
последовательном
обходе. Составить подпрограмму, определяющую, является ли многоугольник выпуклым. Вот то, что я надумал:#include <stdio.h> #include <math.h> #include <conio.h> void main () { int n,i,s,k,t; int x[100], y[100]; float l,r; clrscr (); printf("Введите кол-во вершин многоугольника* - "); scanf("%i",&n); for(i=0; i<n; i++) { printf("Введите координаты вершины: "); scanf("%i %i", &x[i], &y[i]); for(s=1; s<=l; s++) for(k=1; k<=r; k++) { l=x[i]*(y[i+1]-y[i-1])+y[i]*(x[i-1]-x[i+1])+(x[i+1]*y[i-1]-x[i-1]*y[i+1]); r=x[i+2]*(y[i+1]-y[i-1])+y[i+2]*(x[i-1]-x[i+1])+(x[i+1]*y[i-1]-x[i-1]*y[i+1]); if(l*r<0) printf("Выпуклый "); else printf("Вогнутый "); }
Решение задачи: «Выпуклый многоугольник»
textual
Листинг программы
/////////////////////////////////////////////////////////////////////////////////////// //Многоугольник задан координатами своих вершин при их последовательном обходе. //Составить подпрограмму, определяющую, является ли многоугольник выпуклым. /////////////////////////////////////////////////////////////////////////////////////// #include <algorithm> #include <complex> #include <functional> #include <iostream> #include <limits> #include <vector> /////////////////////////////////////////////////////////////////////////////////////// typedef double T_coord; typedef std::complex<T_coord> T_vertice; typedef std::vector<T_vertice> T_polygon; typedef std::vector<T_coord> T_dets; /////////////////////////////////////////////////////////////////////////////////////// template<class T> bool equal_to_for_real(T a, T b) { const T coef = 10; return abs(a - b) < std::numeric_limits<T>::epsilon() * coef; } /////////////////////////////////////////////////////////////////////////////////////// template<class T> bool greater_for_real(T a, T b) { return a > b && !equal_to_for_real(a, b); } /////////////////////////////////////////////////////////////////////////////////////// template<class T> bool less_for_real(T a, T b) { return a < b && !equal_to_for_real(a, b); } /////////////////////////////////////////////////////////////////////////////////////// template<class T> bool greater_equal_for_real(T a, T b) { return !less_for_real(a, b); } /////////////////////////////////////////////////////////////////////////////////////// template<class T> bool less_equal_for_real(T a, T b) { return !greater_for_real(a, b); } ////////////////////////////////////////////////////////////////////////////////////// bool operator< (T_vertice vert_A, T_vertice vert_B) { return equal_to_for_real(vert_A.real(), vert_B.real()) ? less_for_real(vert_A.imag(), vert_B.imag()) : less_for_real(vert_A.real(), vert_B.real()); } /////////////////////////////////////////////////////////////////////////////////////// T_coord det(T_vertice A, T_vertice B) { return A.real() * B.imag() - B.real() * A.imag(); } /////////////////////////////////////////////////////////////////////////////////////// bool polygon_is_convex(const T_polygon& polygon) { //Сдвигаем циклически вершины. T_polygon turned_polygon(polygon); std::rotate(turned_polygon.begin(), turned_polygon.begin() + 1, turned_polygon.end()); //Находим векторы сторон многоугольника. Для этого вычитаем из элемнтов turned_polygon //элементы polygon. T_polygon edges;//Первый элемент - сторона 1-2. std::transform(turned_polygon.begin(), turned_polygon.end(), polygon.begin(), std::back_inserter(edges), std::minus<T_vertice>()); //Сдвигаем циклически стороны многоугольника. T_polygon turned_edges(edges); std::rotate(turned_edges.begin(), turned_edges.begin() + 1, turned_edges.end()); //Находим определители между соседними сторонами многоугольника. T_dets dets; std::transform(edges.begin(), edges.end(), turned_edges.begin(), std::back_inserter(dets), det); //Проверяем, что все определители ненулевые и одного знака. //--------------------------------------------------------- //Ищем нулевой элемент. T_dets::const_iterator zero_it = std::find_if(dets.begin(), dets.end(), std::bind2nd(std::ptr_fun(equal_to_for_real<T_coord>), 0.0)); if(zero_it != dets.end()) return false; //Ищем положительный определитель. T_dets::const_iterator positive_it = std::find_if(dets.begin(), dets.end(), std::bind2nd(std::ptr_fun(greater_for_real<T_coord>), 0.0)); //Ищем отрицательный определитель. T_dets::const_iterator negative_it = std::find_if(dets.begin(), dets.end(), std::bind2nd(std::ptr_fun(less_for_real<T_coord>), 0.0)); return positive_it == dets.end() || negative_it == dets.end(); } /////////////////////////////////////////////////////////////////////////////////////// int main() { std::locale::global(std::locale("")); int n = 0; do { std::cout << "Введите число вершин многоугольника >= 1: "; std::cin >> n; }while(n < 1); std::cout << "Введите " << n << " вершин многоугольника последовательно " << std::endl <<"в порядке обхода границы в любом направлении:" << std::endl; T_polygon polygon; while(polygon.size() < static_cast<size_t>(n)) { std::cout << std::endl << "X[" << polygon.size() + 1 << "] = "; T_coord x = 0; std::cin >> x; std::cout << "Y[" << polygon.size() + 1 << "] = "; T_coord y = 0; std::cin >> y; T_vertice vertice_cur(x, y); polygon.push_back(vertice_cur); } std::cout << "Заданный " << n << "-угольник " << (polygon_is_convex(polygon) ? "" : "НЕ ") <<"является выпуклым." << std::endl; }
Объяснение кода листинга программы
В данном коде реализована функция, определяющая выпуклость заданного многоугольника.
- В начале кода подключаются необходимые библиотеки: iostream, limits, algorithm, complex, vector.
- Далее, с помощью директивы #define, определяется тип вершин многоугольника - T_coord, который представляет собой числа с плавающей точкой.
- Затем, с помощью директивы #define, определяется тип вектора вершин многоугольника - T_polygon.
- Далее, определяются функции equal_to_for_real, greater_for_real, less_for_real, greater_equal_for_real, less_equal_for_real, которые сравнивают числа с плавающей точкой, используя функцию std::numeric_limits
::epsilon() для определения допустимой погрешности. - Затем, определяется оператор < для вершин многоугольника, который сравнивает координаты вершин.
- Далее, определяется функция det, которая вычисляет определитель векторов.
- В функции main() пользователю предлагается ввести количество вершин многоугольника, после чего запрашиваются координаты вершин и сохраняются в векторе polygon.
- Затем, вызывается функция polygon_is_convex, которая проверяет выпуклость многоугольника. Результат проверки выводится на экран. Таким образом, данный код решает задачу определения выпуклости выпуклого многоугольника, заданного координатами своих вершин при их последовательном обходе.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д