日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算几何_多边形

發布時間:2023/12/1 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算几何_多边形 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

判定凸多邊形:頂點凹凸性法

? ? 連續三個頂點p1,p2,p3。計算p1p2,p2p3的叉乘,階乘大于0,則表示p3點在線段p1和p2的左側,然后依次計算下一個前后所組成向量的階乘,如果在計算時,出現負值,則此多邊形是凹多邊形,如果所有頂點計算完畢,其結果都大于0,則多邊形是凸多邊形。

判斷點在凸多邊形內外:

? ? ①:與判定凸多邊形差不多,用判斷點與多邊形兩頂點叉乘,都大于0,點在多邊形內,小于0,點在多邊形外。
? ? ②:水平/垂直交叉點數判別法(適用于任意多邊形包括凹凸邊形)
注意到如果從P作水平向左的射線的話,如果P在多邊形內部,那么這條射線與多邊形的交點必為奇數,如果P在多邊形外部,則交點個數必為偶數(0也在內)。所以,我們可以順序考慮多邊形的每條邊,求出交點的總個數。還有一些特殊情況要考慮。

判斷線段在任意多邊形內:

? ? (1)首先,要判斷一條線段是否在多邊形內,先要判斷線段的兩個端點是否在多邊形內。如果兩個端點不全在多邊形內,那么,線段肯定是不在多邊形內的。
? ? (2)其次,如果線段和多邊形的某條邊內交(兩線段內交是指兩線段相交且交點不在兩線段的端點),則線段肯定不在多邊形內。
? ? (3)如果多邊形的某個頂點和線段相交,則必須判斷兩相交交點之間的線段是否包含于多邊形內。

求多邊形重心:

? ? ? ?以第一個頂點為基準,分別連接p[i],p[i+1],1<i<n。將多邊形劃分為若干個三角形,求出了每個三角形的重心,用叉積求三角形面積,對凸多邊形和凹多邊形都適用(因為值有正負);作為二維的多邊形,把面積作為權值,分別乘以重心坐標的X和Y值;分別將求出的X, Y值的加權平均數除以總面積,即多邊形面積的重心坐標。

具體代碼實現:

#include <iostream> #include <stdlib.h> #include <math.h> #define MAXN 1000 #define offset 10000 #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) #define _sign(x) ((x)>eps?1:((x)<-eps?2:0))using namespace std ;struct point{double x,y;}p[MAXN]; struct line{point a,b;};double xmult(point p1,point p2,point p0) //計算向量p1p2,p2p3的叉積 {return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); }int is_convex(int n,point* p) //判定凸多邊形,頂點按順時針或逆時針給出,允許相鄰邊共線 {int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[1]|s[2]; } int is_convex_v2(int n,point* p) //判定凸多邊形,頂點按順時針或逆時針給出,不允許相鄰邊共線 {int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[0]&&s[1]|s[2]; }int inside_convex(point q,int n,point* p) //判點在凸多邊形內或多邊形邊上,頂點按順時針或逆時針給出 {int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[1]|s[2]; } int inside_convex_v2(point q,int n,point* p) //判點在凸多邊形內,頂點按順時針或逆時針給出,在多邊形邊上返回0 {int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[0]&&s[1]|s[2]; }int inside_polygon(point q,int n,point* p,int on_edge=2) //判點在任意多邊形內,頂點按順時針或逆時針給出,on_edge表示點在多邊形邊上時的返回值,offset為多邊形坐標上限 {point q2;int i=0,count;while (i<n)for (count=i=0,q2.x=rand()+offset,q2.y=rand()+offset;i<n;i++)//隨機取一個足夠遠的點q,以p為起點q為終點做射線L,依次對多邊形的每條邊進行考察if( zero(xmult(q,p[i],p[(i+1)%n])) && (p[i].x-q.x)*(p[(i+1)%n].x-q.x)<eps && (p[i].y-q.y)*(p[(i+1)%n].y-q.y)<eps )return on_edge;//點p在邊上,返回on_edgeelse if (zero(xmult(q,q2,p[i])))break;//點q在射線pq2上,停止本循環,另取q2else if(xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmult(p[i],q,p[(i+1)%n])*xmult(p[i],q2,p[(i+1)%n])<-eps)count++;return count&1; } inline int opposite_side(point p1,point p2,point l1,point l2) {return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps; } inline int dot_online_in(point p,point l1,point l2) {return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps; } int inside_polygon(point l1,point l2,int n,point* p) //判線段在任意多邊形內,頂點按順時針或逆時針給出,與邊界相交返回1 {point t[MAXN],tt;int i,j,k=0;if (!inside_polygon(l1,n,p)||!inside_polygon(l2,n,p))return 0;for (i=0;i<n;i++)if (opposite_side(l1,l2,p[i],p[(i+1)%n])&&opposite_side(p[i],p[(i+1)%n],l1,l2))return 0;else if (dot_online_in(l1,p[i],p[(i+1)%n]))t[k++]=l1;else if (dot_online_in(l2,p[i],p[(i+1)%n]))//線段的某個端點在S上t[k++]=l2;else if (dot_online_in(p[i],l1,l2))t[k++]=p[i];for (i=0;i<k;i++)for (j=i+1;j<k;j++){tt.x=(t[i].x+t[j].x)/2;tt.y=(t[i].y+t[j].y)/2;if (!inside_polygon(tt,n,p))return 0;}return 1; }point intersection(line u,line v) //求多邊形重心 {point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret; } point barycenter(point a,point b,point c) {line u,v;u.a.x=(a.x+b.x)/2;u.a.y=(a.y+b.y)/2;u.b=c;v.a.x=(a.x+c.x)/2;v.a.y=(a.y+c.y)/2;v.b=b;return intersection(u,v); } point barycenter(int n,point* p) {point ret,t;double t1=0,t2;int i;ret.x=ret.y=0;for (i=1;i<n-1;i++)if (fabs(t2=xmult(p[0],p[i],p[i+1]))>eps){t=barycenter(p[0],p[i],p[i+1]);ret.x+=t.x*t2;ret.y+=t.y*t2;t1+=t2;}if (fabs(t1)>eps)ret.x/=t1,ret.y/=t1;return ret; }int main() { }

版權聲明:本文為博主原創文章,未經博主允許不得轉載。

轉載于:https://www.cnblogs.com/wanglaoda/p/4937174.html

總結

以上是生活随笔為你收集整理的计算几何_多边形的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。