[GIS演算法] 點是否在多邊形內
阿新 • • 發佈:2018-12-20
/*
@Time:20181111
@Title:判斷點是否在多邊形內,不考慮點在邊上
@Desc:用Point迴圈連結串列表示Polygon
*/
#include<stdio.h>
#include<stdlib.h>
#define EXP 1e-8 //精度
typedef struct point{
double x;
double y;
struct point *next;
}Point, *Polygon;
int CreatePolygon(Polygon *p);
int PointInPolygon(Point A, Polygon P) ;
/*測試資料
11
0 0
1 2
2 1
3 2
4 2
5 3
6 0
3 1
2 0
1 1.5
0 0
1 1
5 1.5
*/
int main() {
Point A;
Polygon polygon;
CreatePolygon(&polygon);
while (1) {
printf("輸入點A:\n>>> ");
scanf("%lf%lf", &A.x, &A.y);
printf("%d\n", PointInPolygon(A, polygon) );
}
return 0;
}
// 返回1:建立成功
// 返回0:建立不成功,點沒有閉合
int CreatePolygon(Polygon *pHead) {
int n;
int i;
Point *p,*q;
double a,b;
double suba,subb;
scanf("%d", &n);
p = NULL;
for (i=0; i<n; i++) {
scanf("%lf%lf", &a, &b);
if (p==NULL) { //第一個結點
p = (Point *)malloc(sizeof(Point)); if (!p) exit(0);
p->x = a; p->y = b;
p-> next = p; //迴圈連結串列
*pHead = p;
} else {
suba = (*pHead)->x - a;
subb = (*pHead)->y - b;
if ( suba>=-EXP && suba<=EXP && subb>=-EXP && subb<=EXP) { //閉合
return 1;
}
q = (Point *)malloc(sizeof(Point)); if (!q) exit(0);
q->x = a; q->y = b;
// 連線
p->next = q;
q->next = *pHead;
// 下一個
p = q;
}
}
return 0;
}
// 向右作射線
int PointInPolygon(Point A, Polygon head) {
Point *p, *p1, *p2;
int cnt;
double ymax;
double ymin;
double x;
cnt=0;
p = head;
do{
p1 = p;
p2 = p->next;
if (p1->y > p2->y) {
ymax = p1->y;
ymin = p2->y;
} else {
ymax = p2->y;
ymin = p1->y;
}
// 看交點
if ( p1->y-p2->y >=-EXP && p1->y-p2->y <=EXP ) { // p1p2 與 y=A.y 平行
p = p->next;
continue;
} else if ( A.y < ymin ) { //交點在p1p2延長線上
p = p->next;
continue;
} else if ( A.y >= ymax ) { //交點在p1p2延長線上
p = p->next;
continue;
}
// 求交點座標
x = (double)(A.y-p1->y) * (double)(p2->x-p1->x) / (double)(p2->y-p1->y) + p1->x;
if ( x > A.x)
cnt++;
p = p->next;
}while (p!=head);
return cnt%2==1;
}