看到网上除了射线法,很长一段代码之外,看到了一个很简单的算法解决这个问题,特意转了过来

/*
这个算法是源自《计算机图形学基础教程》(孙家广,清华大学出版社),在该书
的48-49页,名字可称为"改进的弧长法"。该算法只需O(1)的附加空间,时间复杂度为O
(n),但系数很小;最大的优点是具有很高的精度,只需做乘法和减法,若针对整数坐标则
完全没有精度问题。而且实现起来也非常简单,比转角法和射线法都要好写且不易出错。 首先从该收中摘抄一段弧长法的介绍:"弧长法要求多边形是有向多边形,一般规
定沿多边形的正向,边的左侧为多边形的内侧域。以被测点为圆心作单位圆,将全部有向
边向单位圆作径向投影,并计算其中单位圆上弧长的代数和。若代数和为0,则点在多边形
外部;若代数和为2π则点在多边形内部;若代数和为π,则点在多边形上。" 按书上的这个介绍,其实弧长法就是转角法。但它的改进方法比较厉害:将坐标原
点平移到被测点P,这个新坐标系将平面划分为4个象限,对每个多边形顶点P,只考虑
其所在的象限,然后按邻接顺序访问多边形的各个顶点P,分析P和P[i+1],有下列
三种情况:
(1)P[i+1]在P的下一象限。此时弧长和加π/2;
(2)P[i+1]在P的上一象限。此时弧长和减π/2;
(3)P[i+1]在Pi的相对象限。首先计算f=y[i+1]*x-x[i+1]*y(叉积),若f=
0,则点在多边形上;若f<0,弧长和减π;若f>0,弧长和加π。 最后对算出的代数和和上述的情况一样判断即可。 实现的时候还有两点要注意,第一个是若P的某个坐标为0时,一律当正号处理;
第二点是若被测点和多边形的顶点重合时要特殊处理。 以上就是书上讲解的内容,其实还存在一个问题。那就是当多边形的某条边在坐标
轴上而且两个顶点分别在原点的两侧时会出错。如边(3,0)-(-3,0),按以上的处理,象限
分别是第一和第二,这样会使代数和加π/2,有可能导致最后结果是被测点在多边形外。
而实际上被测点是在多边形上(该边穿过该点)。
对于这点,我的处理办法是:每次算P和P[i+1]时,就计算叉积和点积,判断该
点是否在该边上,是则判断结束,否则继续上述过程。这样牺牲了时间,但保证了正确性

具体实现的时候,由于只需知道当前点和上一点的象限位置,所以附加空间只需O(
1)。实现的时候可以把上述的"π/2"改成1,"π"改成2,这样便可以完全使用整数进
行计算。不必考虑顶点的顺序,逆时针和顺时针都可以处理,只是最后的代数和符号不同
而已。整个算法编写起来非常容易。 */
#include <stdio.h>
#include <math.h>
const int MAX = ;
struct point
{
int x , y ;
} p[MAX] ;
int main()
{
int n , m , i , sum , t1 , t2 , f , prob = ;
point t ;
while (scanf("%d",&n),n)
{
if(prob ++)
printf ("\n");
printf ("Problem %d:\n",prob) ;
scanf ("%d" ,&m) ;
for (i = ; i < n;i++)
scanf ("%d%d",&p[i].x,&p[i].y) ;
p[n] = p[] ;
while(m--)
{
scanf ("%d%d",&t.x,&t.y);
for (i=;i<=n;i++)
p[i].x -=t.x,p[i].y -= t.y ; // 坐标平移,将被测点设置为坐标原点
t1 = p[].x>= ? ( p[].y>=?: ) : ( p[].y>=?: ) ; // 计算象限
for (sum = ,i =;i <= n;i ++ )
{
if ( !p[i].x && !p[i].y ) break ; // 被测点为多边形顶点
f = p[i].y * p[i-].x - p[i].x * p[i-].y ; // 计算叉积
if ( !f && p[i-].x*p[i].x <= && p[i-].y*p[i].y <= ) break ; // 点在边上
t2 = p[i].x>= ? ( p[i].y>= ?: ) : ( p[i].y>=?: ) ; // 计算象限
if ( t2 == ( t1 + ) % ) sum += ; // 情况1
else if ( t2 == ( t1 + ) % ) sum -= ; // 情况2
else if ( t2 == ( t1 + ) % ) // 情况3
if ( f > ) sum += ;
else sum -= ;
t1 = t2 ;
}
if ( i<=n || sum ) printf( "Within\n" ) ;
else printf( "Outside\n" ) ;
for ( i = ; i <= n ; i ++ )
p[i].x += t.x , p[i].y += t.y ; // 恢复坐标
}
}
return ;
}

zoj 1081 (改进的弧长算法)(转)的更多相关文章

  1. 《图形学》实验五:改进的Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用改进的Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h ...

  2. 倒排索引压缩:改进的PForDelta算法

    由于倒排索引文件往往占用巨大的磁盘空间,我们自然想到对数据进行压缩.同时,引进压缩算法后,使得磁盘占用减少,操作系统在query processing过程中磁盘读取效率也能提升.另外,压缩算法不仅要考 ...

  3. 大话数据结构(十二)java程序——KMP算法及改进的KMP算法实现

    1.朴素的模式匹配算法 朴素的模式匹配算法:就是对主串的每个字符作为子串开头,与要连接的字符串进行匹配.对主串做大循环,每个字符开头做T的长度的小循环,直到成功匹配或全部遍历完成为止. 又称BF算法 ...

  4. ZOJ 1081 Within(点是否在多边形内)| 计算几何

    ZOJ 1081 Within 我使用的是"射线法":从该点出发,作一条向左的水平射线,与多边形的边的交点有奇数个则点在多边形内. 需要注意的点: 如果点在多边形的边上特判. 考虑 ...

  5. 改进的SMS4算法的差分故障与暴力联合攻击

    改进的SMS4算法的差分故障与暴力联合攻击 (1.中国科学院研究生院,北京100049) 摘要SMS4是在国内正式使用并于2006年发布的第一个用于无线局域网的商用分组password算法.文中研究了 ...

  6. 基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)

    其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登 ...

  7. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  8. 改进的SMO算法

    S. S. Keerthi等人在Improvements to Platt's SMO Algorithm for SVM Classifier Design一文中提出了对SMO算法的改进,纵观SMO ...

  9. SpringCloud升级之路2020.0.x版-32. 改进负载均衡算法

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 在前面一节,我们梳理了实现 Feign 断路器以及线程隔离的思路,这一节,我们先不看如何源 ...

随机推荐

  1. M​i​c​r​o​s​o​f​t​ ​w​e​b​ ​a​p​p​l​i​c​a​t​i​o​n​ ​s​t​r​e​s​s​ ​t​o​o​l​ 测试

    一.准备工作 为了测试数据的准备性,首先需要删除缓存和Cookies等临时文件.启动IE后打开“工具”菜单下的“Internet”选项命令,在打开的“Internet选项”窗口的“常规”选项卡中,单击 ...

  2. iPhone/iTouch免99美刀真机调试

    本文经本人验证,攻略来源于网上,由于多次转载原始出处不可靠,故无法对原作者进行链接引用,抱歉. 本文仅为记录流程,以备日后查询.本文版权所无,欢迎转载和拍砖. 测试环境: XCode 4.0.2 + ...

  3. Vxlan 原理

    https://www.gitbook.com/book/yeasy/openstack_understand_neutron/details 自己总结一下: 分析 VTEP的情况, 即Vxlan跟V ...

  4. 菜鸟级SQL Server21天自学通(文档+视频)

    SQL语言的主要功能就是同各种数据库建立联系,进行沟通.按照ANSI(美国国家标准协会)的规定,SQL被作为关系型数据库管理系统的标准语言.SQL语句可以用来执行各种各样的操作,例如更新数据库中的数据 ...

  5. UVA507-- Jill Rides Again

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. 更新cydia“sub-process/usr/libexec/cydia/cydo returned anerror code(2)”是怎么回事?

    最近更新cydia的时候出现了sub-process/usr/libexec/cydia/cydo returned anerror code(2)的红字是怎么回事? 解决方法:删掉有关升级的东西,把 ...

  7. 在View中使用CGridCtrl时出现系统异常

    一.简介 我的程序是单文档程序,我的View视图需要使用CGridCtrl,于是我把CGridCtrl作为子窗口嵌入到View中覆盖住整个View.由于不能像gridctrl_demo227那样直接在 ...

  8. leetcode Container With Most Water python

    class Solution(object): def maxArea(self, height): """ :type height: List[int] :rtype ...

  9. R与数据分析旧笔记(十七) 主成分分析

    主成分分析 主成分分析 Pearson于1901年提出的,再由Hotelling(1933)加以发展的一种多变量统计方法 通过析取主成分显出最大的个别差异,也用来削减回归分析和聚类分析中变量的数目 可 ...

  10. Hadoop学习笔记01——Hadoop分布式文件系统

    Hadoop有一个称为HDFS的分布式系统,全称为Hadoop Distributed Filesystem. HDFS有块(block)的概念,默认为64MB,HDFS上的文件被划分为块大小的多个分 ...