zoukankan      html  css  js  c++  java
  • 判断一个多边形是顺时针还是逆时针的方法

    1、关于如何判定多边形是顺时针还是逆时针对于凸多边形而言,只需对某一个点计算叉积 = ((xi - xi-1),(yi - yi-1)) x ((xi+1 - xi),(yi+1 - yi)) = (xi - xi-1) * (yi+1 - yi) - (yi - yi-1) * (xi+1 - xi)
    如果上式的值为正,逆时针;为负则是顺时针。

    而对于一般的简单多边形,则需对于多边形的每一个点计算上述值,如果正值比较多,是逆时针;负值较多则为顺时针。

    2、还有一种说明是取多边形的极点值,多边形的方向和这个顶点与其相邻两边构成的方向相同。

    需要注意的是在屏幕坐标中,Y是向下的,所以在屏幕坐标系中看到的顺时针既是在Y轴向上的直角坐标系中看到的逆时针方向。

    1.凸包的时候,只要判断前三个点即可,计算叉积,判断方向

    2.凹包情况就复杂了,可以从三个方面考虑

    首先,可以去凸包上的特殊点,x最大最小的点,y最大最小的点,这些极值点肯定是在凸包上的,可以计算这些的叉积,其次,直接统计叉积正负的数量,正多负少,是逆时针,反之,顺时针。

    一个简单的做法是,计算面积,用面积的正负判断方向。

    【面积判断法】

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define mod 2000000000000000003
    #define rep(i,n,x) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int MAXN =  1e3 + 5;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int maxn = 200050;
    
    
    struct Point{
        double x, y;
    };
    double cross(Point a,Point b,Point c) {
        return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
    }
    //计算多边形面积
    double PolygonArea(Point p[], int n)
    {
        if(n < 3) return 0.0;
        double s = p[0].y * (p[n - 1].x - p[1].x);
        p[n] = p[0];
        for(int i = 1; i < n; ++ i)
            s += p[i].y * (p[i - 1].x - p[i + 1].x);
        return s * 0.5;
    }
    Point p1[maxn];
    int n1;
    int main()
    {
        while(scanf("%d",&n1) != EOF ){
            for(int i = 0; i < n1; i++)
                scanf("%lf%lf", &p1[i].x, &p1[i].y);
            if ( PolygonArea(p1,n1) > 0 )
                puts("counterclockwise");
            else
                puts("clockwise");
        }
        return 0;
    }
    
    
  • 相关阅读:
    思考--连续的还是跳跃的?(二)
    方法学导论--by 有只茄子
    时空、维度,以及其他(一)
    处理问题的方法--抽象和特例化
    tomcat server 152主机.xml
    java怎么重写覆盖Spring Bean的几种方式
    maven上传jar到私服
    sql_mode=only_full_group_by
    spring何时创建bean
    mysql 快速备份数据库
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9058424.html
Copyright © 2011-2022 走看看