HDU 2108 Shape of HDU 计算几何 判断多边形凹凸性

题目:https://cn.vjudge.net/problem/HDU-2108

题意:给一个多边形点的坐标,输入按逆时针排序,判断多边形的凹凸性。

思路
方法一:求凸包,比较顶点数是否相等。
方法二:根据凸多边形定义:
(1)对于每一条边,其余的边都在该边同一侧。
(2)多边形内角都小于180度。

也就是说对于逆时针排序的边,下一条边必定在上一条边左侧。
实现上可以用叉积判断,向量v1和v2的叉积小于零时,v2在v1左侧。

代码:C++

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const double eps = 1e-10;

int dcmp(double a)
{
    if(fabs(a) < eps)
    {
        return 0;
    }
    return a < 0 ? -1 : 1;
}

struct Point
{
    double x, y;
    Point(double xx = 0, double yy = 0) : x(xx), y(yy) {}
};

typedef Point Vector;

Vector operator - (Point p1, Point p2)
{
    return Vector(p2.x - p1.x, p2.y - p1.y);
}

double Cross(Vector v1, Vector v2)
{
    return v1.x * v2.y - v1.y * v2.x;
}

int n;

//输入多边形,顶点逆时针顺序排列
bool isConvex(vector<Point> &p)
{
    int n = p.size();
    if(dcmp(Cross(p[n-1] - p[0], p[1] - p[0]) >= 0))
    {
        return false;
    }
    if(dcmp(Cross(p[n - 2] - p[n - 1], p[0] - p[n - 1]) >= 0))
    {
        return false;
    }
    for(int i = 1; i < n - 1; i++)
    {
        if(dcmp(Cross(p[i - 1] - p[i], p[i + 1] - p[i])) >= 0)
        {
            return false;
        }
    }
    return true;
}

vector<Point> p;

int main()
{
    while(scanf("%d", &n) != EOF && n)
    {
        p.clear();
        for(int i = 0; i < n; i++)
        {
            double x, y;
            scanf("%lf%lf", &x, &y);
            p.push_back(Point(x, y));
        }
        printf("%s\n", isConvex(p) ? "convex" : "concave");
    }
    return 0;
}

你可能感兴趣的:(解题笔记)