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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

c语言实现点在多边形内部,C语言中实现 点在多边形内 算法

發布時間:2025/4/5 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言实现点在多边形内部,C语言中实现 点在多边形内 算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來源:

天極網

作者:

若水

2008-05-15/01:29

本文是采用射線法判斷點是否在多邊形內的C語言程序。多年前,我自己實現了這樣一個算法。但是隨著時間的推移,我決定重寫這個代碼。參考周培德的《計算幾何》一書,結合我的實踐和經驗,我相信,在這個算法的實現上,這是你迄今為止遇到的最優的代碼。

這是個C語言的小算法的實現程序,本來不想放到這里。可是,當我自己要實現這樣一個算法的時候,想在網上找個現成的,考察下來竟然一個符合需要的也沒有。我對自己大學讀書時寫的代碼沒有信心,所以,決定重新寫一個,并把它放到這里,以饗讀者。也增加一下BLOG的點擊量。

首先定義點結構如下:

以下是引用片段:

/*?Vertex?structure?*/

typedef?struct

{

double?x,?y;

}?vertex_t;

本算法里所指的多邊形,是指由一系列點序列組成的封閉簡單多邊形。它的首尾點可以是或不是同一個點(不強制要求首尾點是同一個點)。這樣的多邊形可以是任意形狀的,包括多條邊在一條絕對直線上。因此,定義多邊形結構如下:

以下是引用片段:

/*?Vertex?list?structure?–?polygon?*/

typedef?struct

{

int?num_vertices;?/*?Number?of?vertices?in?list?*/

vertex_t?*vertex;?/*?Vertex?array?pointer?*/

}?vertexlist_t;

為加快判別速度,首先計算多邊形的外包矩形(rect_t),判斷點是否落在外包矩形內,只有滿足落在外包矩形內的條件的點,才進入下一步的計算。為此,引入外包矩形結構rect_t和求點集合的外包矩形內的方法vertices_get_extent,代碼如下:

以下是引用片段:

/*?bounding?rectangle?type?*/

typedef?struct

{

double?min_x,?min_y,?max_x,?max_y;

}?rect_t;

/*?gets?extent?of?vertices?*/

void?vertices_get_extent?(const?vertex_t*?vl,?int?np,?/*?in?vertices?*/

rect_t*?rc?/*?out?extent*/?)

{

int?i;

if?(np?>?0){

rc->min_x?=?rc->max_x?=?vl[0].x;?rc->min_y?=?rc->max_y?=?vl[0].y;

}else{

rc->min_x?=?rc->min_y?=?rc->max_x?=?rc->max_y?=?0;?/*?=0???no?vertices?at?all?*/

}

for(i=1;?i

{

if(vl[i].x?min_x)?rc->min_x?=?vl[i].x;

if(vl[i].y?min_y)?rc->min_y?=?vl[i].y;

if(vl[i].x?>?rc->max_x)?rc->max_x?=?vl[i].x;

if(vl[i].y?>?rc->max_y)?rc->max_y?=?vl[i].y;

}

}

當點滿足落在多邊形外包矩形內的條件,要進一步判斷點(v)是否在多邊形(vl:np)內。本程序采用射線法,由待測試點(v)水平引出一條射線B(v,w),計算B與vl邊線的交點數目,記為c,根據奇內偶外原則(c為奇數說明v在vl內,否則v不在vl內)判斷點是否在多邊形內。

具體原理就不多說。為計算線段間是否存在交點,引入下面的函數:

(1)is_same判斷2(p、q)個點是(1)否(0)在直線l(l_start,l_end)的同側;

(2)is_intersect用來判斷2條線段(不是直線)s1、s2是(1)否(0)相交;

#p#分頁標題#e#以下是引用片段:

/*?p,?q?is?on?the?same?of?line?l?*/

static?int?is_same(const?vertex_t*?l_start,?const?vertex_t*?l_end,?/*?line?l?*/

const?vertex_t*?p,

const?vertex_t*?q)

{

double?dx?=?l_end->x?-?l_start->x;

double?dy?=?l_end->y?-?l_start->y;

double?dx1=?p->x?-?l_start->x;

double?dy1=?p->y?-?l_start->y;

double?dx2=?q->x?-?l_end->x;

double?dy2=?q->y?-?l_end->y;

return?((dx*dy1-dy*dx1)*(dx*dy2-dy*dx2)?>?0??1?:?0);

}

/*?2?line?segments?(s1,?s2)?are?intersect??*/

static?int?is_intersect(const?vertex_t*?s1_start,?const?vertex_t*?s1_end,

const?vertex_t*?s2_start,?const?vertex_t*?s2_end)

{

return?(is_same(s1_start,?s1_end,?s2_start,?s2_end)==0?&&

is_same(s2_start,?s2_end,?s1_start,?s1_end)==0)??1:?0;

}

下面的函數pt_in_poly就是判斷點(v)是(1)否(0)在多邊形(vl:np)內的程序:

以下是引用片段:

int?pt_in_poly?(?const?vertex_t*?vl,?int?np,?/*?polygon?vl?with?np?vertices?*/

const?vertex_t*?v)

{

int?i,?j,?k1,?k2,?c;

rect_t?rc;

vertex_t?w;

if?(np?

return?0;

vertices_get_extent(vl,?np,?&rc);

if?(v->x?x?>?rc.max_x?||?v->y?y?>?rc.max_y)

return?0;

/*?Set?a?horizontal?beam?l(*v,?w)?from?v?to?the?ultra?right?*/

w.x?=?rc.max_x?+?DBL_EPSILON;

w.y?=?v->y;

c?=?0;?/*?Intersection?points?counter?*/

for(i=0;?i

{

j?=?(i+1)?%?np;

if(is_intersect(vl+i,?vl+j,?v,?&w))

{

c++;

}

else?if(vl[i].y==w.y)

{

k1?=?(np+i-1)%np;

while(k1!=i?&&?vl[k1].y==w.y)

k1?=?(np+k1-1)%np;

k2?=?(i+1)%np;

while(k2!=i?&&?vl[k2].y==w.y)

k2?=?(k2+1)%np;

if(k1?!=?k2?&&?is_same(v,?&w,?vl+k1,?vl+k2)==0)

c++;

if(k2?<=?i)

break;

i?=?k2;

}

}

return?c%2;

}

本想配些插圖說明問題,但是,CSDN的文章里放圖片我還沒用過。以后再試吧!實踐證明,本程序算法的適應性極強。但是,對于點正好落在多邊形邊上的極端情形,有可能得出2種不同的結果。

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的c语言实现点在多边形内部,C语言中实现 点在多边形内 算法的全部內容,希望文章能夠幫你解決所遇到的問題。

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