Выпуклый многоугольник - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Очень нужно решить одну задачку, половину вроде бы сделал, но что-то не то, помогите, если сможете, пожалуйста. Фишка в том, что её нужно решить с подпрограммой

Выпуклый многоугольник

Многоугольник задан координатами своих вершин при их

последовательном

обходе. Составить подпрограмму, определяющую, является ли многоугольник выпуклым.

Вот то, что я надумал:
#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("Вогнутый ");
  }
Сейчас объясню задумку. Например, мы задали 5-ти угольник. Вершины обзовём, соответсвенно 1, 2, 3, 4 и 5. Я провожу линию через точки 1 и 3 и проверяю формулой выше, находятся ли точки 2 и 4 по одну сторону относительно этой линии, или же по разные. И так проверяю кажду точку, потом строю другую прямую через 2 и 4 вершину и проверяю точки снова. Если они находятся по разные стороны, то это выпуклый многоугольник, если же нет, то вогнутый. Посоветуйте пожалуйста что-нибудь, а то я вообще без понятия что дальше делать... И ещё эта подпрограмма.. Заранее спасибо!

Решение задачи: «Выпуклый многоугольник»

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; 
}

Объяснение кода листинга программы

В данном коде реализована функция, определяющая выпуклость заданного многоугольника.

  1. В начале кода подключаются необходимые библиотеки: iostream, limits, algorithm, complex, vector.
  2. Далее, с помощью директивы #define, определяется тип вершин многоугольника - T_coord, который представляет собой числа с плавающей точкой.
  3. Затем, с помощью директивы #define, определяется тип вектора вершин многоугольника - T_polygon.
  4. Далее, определяются функции equal_to_for_real, greater_for_real, less_for_real, greater_equal_for_real, less_equal_for_real, которые сравнивают числа с плавающей точкой, используя функцию std::numeric_limits::epsilon() для определения допустимой погрешности.
  5. Затем, определяется оператор < для вершин многоугольника, который сравнивает координаты вершин.
  6. Далее, определяется функция det, которая вычисляет определитель векторов.
  7. В функции main() пользователю предлагается ввести количество вершин многоугольника, после чего запрашиваются координаты вершин и сохраняются в векторе polygon.
  8. Затем, вызывается функция polygon_is_convex, которая проверяет выпуклость многоугольника. Результат проверки выводится на экран. Таким образом, данный код решает задачу определения выпуклости выпуклого многоугольника, заданного координатами своих вершин при их последовательном обходе.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.154 из 5
Похожие ответы