1. 程式人生 > >[GIS演算法] 點是否在多邊形內

[GIS演算法] 點是否在多邊形內

/*
  @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; }