C语言中的点在多边形内判定

在计算几何中,我们经常会遇到一个问题:如何确定一个给定的点是位于多边形的内部、外部,还是边界上。这个问题就是著名的 “点在多边形内” 问题。它在计算机图形学、地理信息系统(GIS)和机器人技术等领域有着广泛的应用。

在本文中,我们将学习如何使用 C 语言来检查一个给定点是位于多边形内部还是外部。我们还将探讨实现这一目标的不同方法。

示例:

**输入:**
多边形: { { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 } }
点: {20, 20};

**输出:**
点在多边形外部。

!stark

在 C 语言中解决点在多边形问题的方法

  • 方法 1:使用射线投射算法
  • 方法 2:使用环绕数算法
  • 方法 3:使用边交叉算法

方法 1:使用射线投射算法

在这种方法中,我们首先从给定点向无穷远处投射一条水平射线,然后计算该射线与多边形边缘相交的次数。如果相交次数为奇数,则该点在多边形内部;如果是偶数,则该点在外部。

如下图所示,点 A 和 C 与多边形边相交一次,数量为奇数,因此点 A 和 C 在多边形内部;而点 B 和 D 与多边形边相交两次,数量为偶数,因此点 B 和 D 在多边形外部;此外,点 E 与多边形边的相交次数为 0,这也是偶数,因此它也位于多边形外部。我们可以从图中证实上述推测是正确的。

!stark

方法思路

> – 将交点计数器初始化为零。

> – 对于多边形的每一条边:

> – 检查该边是否与从点向右延伸的水平射线相交。

> – 如果相交,则增加交点计数器的值。

> – 如果交点计数器为奇数,则点在多边形内;如果为偶数,则点在多边形外。

使用射线投射算法检查点在多边形内的 C 程序

下面的程序演示了我们如何在 C 语言中使用射线投射算法来检查一个点是位于多边形内部还是外部。

C


// C program to check if a point is inside a polygon using

// ray-casting algorithm

#include

#include

#include

// Structure for a point

typedef struct {

double x, y;

} Point;

// Function to check if a point is on the boundary of a

// polygon edge

int onSegment(Point p, Point q, Point r)

{

if (q.x = fmin(p.x, r.x)

&& q.y = fmin(p.y, r.y))

return 1;

return 0;

}

// Function to find the orientation of the triplet (p, q, r)

// 0 –> p, q and r are collinear

// 1 –> Clockwise

// 2 –> Counterclockwise

int orientation(Point p, Point q, Point r)

{

double val = (q.y – p.y) * (r.x – q.x)

– (q.x – p.x) * (r.y – q.y);

// collinear

if (val == 0)

return 0;

// clock or counterclock wise

return (val > 0) ? 1 : 2;

}

// Function to check if two line segments intersect

int doIntersect(Point p1, Point q1, Point p2, Point q2)

{

int o1 = orientation(p1, q1, p2);

int o2 = orientation(p1, q1, q2);

int o3 = orientation(p2, q2, p1);

int o4 = orientation(p2, q2, q1);

// General case

if (o1 != o2 && o3 != o4)

return 1;

// Special Cases

// p1, q1 and p2 are collinear and p2 lies on segment

// p1q1

if (o1 == 0 && onSegment(p1, p2, q1))

return 1;

// p1, q1 and p2 are collinear and q2 lies on segment

// p1q1

if (o2 == 0 && onSegment(p1, q2, q1))

return 1;

// p2, q2 and p1 are collinear and p1 lies on segment

// p2q2

if (o3 == 0 && onSegment(p2, p1, q2))

return 1;

// p2, q2 and q1 are collinear and q1 lies on segment

// p2q2

if (o4 == 0 && onSegment(p2, q1, q2))

return 1;

return 0; // Doesn‘t fall in any of the above cases

}

// Function to check if the point p is inside the polygon

int isInside(Point polygon[], int n, Point p)

{

// Create a point for the ray (a point far outside the

// polygon)

Point extreme = { DBL_MAX, p.y };

int count = 0, i = 0;

do {

int next = (i + 1) % n;

if (doIntersect(polygon[i], polygon[next], p,

extreme)) {

if (orientation(polygon[i], p, polygon[next])

== 0)

return onSegment(polygon[i], p,

polygon[next]);

count++;

}

i = next;

} while (i != 0);

// Return true if count is odd, false otherwise

return count & 1;

}

int main()

{

Point polygon[]

= { { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 } };

int n = sizeof(polygon) / sizeof(polygon[0]);

Point p = { 20, 20 };

isInside

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/37705.html
点赞
0.00 平均评分 (0% 分数) - 0