点在多边形内算法的C语言实现

本文是采用射线法判断点是否在多边形内的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 < rc->min_x) rc->min_x = vl[i].x;
if(vl[i].y < rc->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;
}
}

时间: 2024-10-29 20:54:17

点在多边形内算法的C语言实现的相关文章

算法系列(十二)多边形区域填充算法:扫描线填充算法(有序边表法)

二.扫描线算法(Scan-Line Filling) 扫描线算法适合对矢量图形进行区域填充,只需要 直到多边形区域的几何位置,不需要指定种子点,适合计算机自动进行图形处理的场合使用,比如电 脑游戏和三维CAD软件的渲染等等. 对矢量多边形区域填充,算法核心还是求交.<计算几何 与图形学有关的几种常用算法>一文给出了判断点与多边形关系的算法――扫描交点的奇偶数判断算 法,利用此算法可以判断一个点是否在多边形内,也就是是否需要填充,但是实际工程中使用的填充 算法都是只使用求交的思想,并不直接使用这

算法系列(十二) 多边形区域填充算法--递归种子填充算法

平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界(也 可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也 可能是图案填充).区域填充中最常用的是多边形填色,本文中我们就讨论几种多边形区域填充算法 . 一.种子填充算法(Seed Filling) 如果要填充的区域是以图像元数据方式给出的 ,通常使用种子填充算法(Seed Filling)进行区域填充.种子填充算法需要给出图像数据的区域, 以及区域内的一个点,这种算法比较适合人

《数据结构与算法:Python语言描述》一1.2 问题求解:交叉路口的红绿灯安排

1.2 问题求解:交叉路口的红绿灯安排 本节展示一个具体问题的计算机求解过程,以此说明在这种过程中可能出现的一些情况,需要考虑的一些问题,以及一些可能的处理方法. 交叉路口是现代城市路网中最重要的组成部分,繁忙的交叉路口需要用红绿灯指挥车辆通行与等待,正确的红绿灯调度安排对于保证交通安全.道路运行秩序和效率都非常重要.交叉路口的情况多种多样,常见形式有三岔路口.十字路口,也有较为少见的更复杂形式的路口.进一步说,有些道路是单行线,在中国的交叉路口还有人车分流和专门的人行/自行车红绿灯等许多情况,

基于C++实现的各种内部排序算法汇总_C 语言

提起排序算法相信大家都不陌生,或许很多人已经把它们记得滚瓜烂熟,甚至随时可以写出来.是的,这些都是最基本的算法.这里就把各种内部排序算法总结归纳了一下,包括插入排序(直接插入排序,折半插入排序,希尔排序).交换排序(冒泡排序,快速排序).选择排序(简单选择排序,堆排序).2-路归并排序.(另:至于堆排序算法,前面已经有一篇文章针对堆排序的算法实现做了详细的描述) C++实现代码如下: /*******************************************************

C/C++实现八大排序算法汇总_C 语言

概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1. 插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已

常用排序算法的C语言版实现示例整理_C 语言

所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来.其确切定义如下: 输入:n个记录R1,R2,-,Rn,其相应的关键字分别为K1,K2,-,Kn. 输出:Ril,Ri2,-,Rin,使得Ki1≤Ki2≤-≤Kin.(或Ki1≥Ki2≥-≥Kin).     排序的时间开销可用算法执行中的数据比较次数与数据移动次数来衡量.基本的排序算法有如下几种:交换排序(冒泡排序.快速排序).选择排序(直接选择排序.堆排序).插入排序(直接插入排序.希尔排序).归并排序.分配排序(基数排

C++快速幂与大数取模算法示例_C 语言

一.快速幂 其实就是求(a^b)% p ,(其中a,b,p都比较大在int范围内)这类问题. 首先要知道取余的公式: (a*b)%p=(a%p*b%p)%p . 那么幂不就是乘机的累积吗,由此给出代码: int fast(int a,int b,int p) { long long a1=a,t=1; while(b>0) { if(b&1) /如果幂b是奇数多乘一次,因为后边会除2变偶数,(7/2=3) t=(t%p)*(a1%p)%p; a1=(a1%p)*(a1%p)%p; b/=2;

快速排序算法的C语言实现

经典的快速排序算法, 作为一个编程者, 任何时候都要完整的手写. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> #include <stdlib.h> int RandomInRange(int min, int max) { int random = rand() % (max - min + 1) + min

C++多边形扫描转换算法

最近学习计算机图形学,写了个多边形扫描转换算法,贴出来分享一下; MFC还不是太明白,主要还是使用OnDraw函数... 大家多指教... void CPolyFillView::OnDraw(CDC* pDC) { CPolyFillDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here const int POINTNUM=6; //多边形点数. /定义结构体用于活性