社区
数据结构与算法
帖子详情
关于几何算法的一个简单问题
jwd_1_cool
2003-08-18 09:28:17
谁能给我贴个
判断点是否在多边形内或上的c/c++程序啊?
另:如何将输入的多边形点,(可能是顺时针,也可能是逆时针顺序)转化到一个数组里按逆时针排列。
参考 zju1081 ,这道题过的人不少,若能相告,3x
...全文
99
7
打赏
收藏
关于几何算法的一个简单问题
谁能给我贴个 判断点是否在多边形内或上的c/c++程序啊? 另:如何将输入的多边形点,(可能是顺时针,也可能是逆时针顺序)转化到一个数组里按逆时针排列。 参考 zju1081 ,这道题过的人不少,若能相告,3x
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
jwd_1_cool
2003-08-24
打赏
举报
回复
继续
jwd_1_cool
2003-08-20
打赏
举报
回复
我怎么也看不出我和超超的程序有什么区别,但就是wa
我也试过copy超超的小函数,但还是不行,现在将的未改的最初程序,贴上来,实在是痛苦啊
#include<iostream.h>
#include<math.h>
int n,m;
#define infinity 1e200
#define EP 1e-10
struct TPoint{
double x,y;
};
struct TLineSeg{
TPoint a,b;
};
double max(double a,double b)
{
return a>b?a:b;
}
double min(double a,double b)
{
return a<b?a:b;
}
double multiply(TPoint p1,TPoint p2,TPoint p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
//确定两条线段是否相交
bool intersect(TLineSeg u,TLineSeg v)
{
return( (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&&
(max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&&
(max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&&
(max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&&
(multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)>=0)&&
(multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)>=0));
}
//判断点p是否在线段l上 不包括端点
bool online(TLineSeg l,TPoint p)
{
return( (multiply(l.b,p,l.a)==0)&&( ((p.x-l.a.x)*(p.x-l.b.x)<0 )||( (p.y-l.a.y)*(p.y-l.b.y)<0 )) );
}
//包括端点
bool online2(TLineSeg l,TPoint p)
{
return( (multiply(l.b,p,l.a)==0)&&( ((p.x-l.a.x)*(p.x-l.b.x)<=0 )||( (p.y-l.a.y)*(p.y-l.b.y)<=0 )) );
}
//判断两个点是否相等
bool Euqal_Point(TPoint p1,TPoint p2)
{
return((fabs(p1.x-p2.x)<EP)&&(fabs(p1.y-p2.y)<EP));
}
//一种线段相交判断函数,当且仅当u,v相交并且交点不是u,v的端点时函数为true;
bool intersect_A(TLineSeg u,TLineSeg v)
{
return((intersect(u,v))&&
(!Euqal_Point(u.a,v.a))&&
(!Euqal_Point(u.a,v.b))&&
(!Euqal_Point(u.b,v.a))&&
(!Euqal_Point(u.b,v.b)));
}
/*===============================================
判断点q是否在多边形Polygon内,
其中多边形是任意的凸或凹多边形,
Polygon中存放多边形的逆时针顶点序列
================================================*/
int InsidePolygon(int vcount,TPoint Polygon[],TPoint q)
{
int c=0,i,n;
TLineSeg l1,l2;
l1.a=q;
l1.b=q;
l1.b.x=infinity;
n=vcount;
for (i=0;i<vcount;i++)
{
l2.a=Polygon[i];
l2.b=Polygon[(i+1)%n];
if(online2(l2,q))return 1;
if ( (intersect_A(l1,l2))||
(
(online(l1,Polygon[(i+1)%n]))&&
(
(!online(l1,Polygon[(i+2)%n]))&&
(multiply(Polygon[i],Polygon[(i+1)%n],l1.a)*multiply(Polygon[(i+1)%n],Polygon[(i+2)%n],l1.a)>0)
||
(online(l1,Polygon[(i+2)%n]))&&
(multiply(Polygon[i],Polygon[(i+2)%n],l1.a)*multiply(Polygon[(i+2)%n],Polygon[(i+3)%n],l1.a)>0)
)
)
) c++;
}
return(c%2!=0);
}
TPoint p[100];
int main()
{
int cs(1);
bool first=true;
while(cin>>n){
if(n==0)return 0;
if(!first) cout<<endl;
cout<<"Problem "<<cs++<<':'<<endl;
cin>>m;
TPoint t;
for(int i=0;i<n;i++){
cin>>t.x>>t.y;
p[i]=t;
}
for(int i=0;i<m;i++){
cin>>t.x>>t.y;
if(InsidePolygon(n,p,t))
cout<<"Within"<<endl;
else cout<<"Outside"<<endl;
}
first=false;
}
return 1;
}
jwd_1_cool
2003-08-20
打赏
举报
回复
晕翻,kbsoft(景乐) 你给的那个贴子是什么时候的啊,小虎竟然说自己是第一次做计算几何的题目??
这道题目 典型的很,楼上这位说的我也知道。
我WA了,以后判断了一下,可能又两个原因:
1。 使用int 后面叉乘精度出错,改成double 了
2。 也是我疑惑的,题目输入数据没说是按什么顺序啊,可是象 超超 写的函数里 Polygon[],必须是逆时针的, 这怎么说????
LeeMaRS
2003-08-20
打赏
举报
回复
呵呵, 好久没来转转了, 1081没写总结, 不然可以帖出来给大家看看:)
前段时间又写了一个角度和法的, 感觉比射线法简单得多了. ^^
loewe
2003-08-18
打赏
举报
回复
哈哈,mmmcd(超超) 动作真的好快啊
判断点是否在多边行内,简单得说就是划射线,从这个点向左或又划一条平行的与x轴的射线,用射线和多边行的边去判断交点,如果交点个数是奇数的话,说明点在多边行内了
kbsoft
2003-08-18
打赏
举报
回复
超超的速度好快啊。刚要re就回复了....
ZOJ 1081以前讨论过了
http://search.csdn.net/expert/topic/6/603/2002/9/11/1013280.htm
mmmcd
2003-08-18
打赏
举报
回复
给你
//#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
#define INF 1E200 //无穷大
#define EP 1E-10 //无穷小
ifstream cin("1081.in");
ofstream cout("1081.out");
struct POINT
{
double x;
double y;
}poly[100];
struct LINESEG
{
POINT s;
POINT e;
};
double max(double a,double b)
{
return a>b?a:b;
}
double min(double a,double b)
{
return a<b?a:b;
}
double multiply(POINT sp,POINT ep,POINT op)
{
return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
}
bool online(LINESEG l,POINT p)
{
return( (multiply(l.e,p,l.s)==0) &&( ( (p.x-l.s.x)*(p.x-l.e.x)<=0 )&&( (p.y-l.s.y)*(p.y-l.e.y)<=0 ) ) );
}
/* 如果线段u和v相交(包括相交在端点处)时,返回true */
bool intersect(LINESEG u,LINESEG v)
{
return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&& //排斥实验
(max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
(max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
(max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&& //跨立实验
(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));
}
/* (线段u和v相交)&&(交点不是双方的端点) 时返回true */
bool intersect_A(LINESEG u,LINESEG v)
{
return((intersect(u,v))&&
(!online(u,v.s))&&
(!online(u,v.e))&&
(!online(v,u.e))&&
(!online(v,u.s)));
}
/* 射线法判断点q与多边形polygon的位置关系,要求polygon为简单多边形,顶点按逆时针排列
如果点在多边形内: 返回0
如果点在多边形边上:返回1
如果点在多边形外: 返回2 */
int insidepolygon(int vcount,POINT Polygon[],POINT q)
{
int c=0,i,n;
LINESEG l1,l2;
bool bintersect_a,bonline1,bonline2,bonline3;
double r1,r2;
l1.s=q;
l1.e=q;
l1.e.x=double(INF);
n=vcount;
for (i=0;i<vcount;i++)
{
l2.s=Polygon[i];
l2.e=Polygon[(i+1)%n];
if(online(l2,q))return 1; //如果点在边上,返回1
if ( (bintersect_a=intersect_A(l1,l2))|| //相交且不在端点
(
(bonline1=online(l1,Polygon[(i+1)%n]))&& //第二个端点在射线上
(
(!(bonline2=online(l1,Polygon[(i+2)%n])))&& //前一个端点和后一个端点在射线两侧
((r1=multiply(Polygon[i],Polygon[(i+1)%n],l1.s)*multiply(Polygon[(i+1)%n],Polygon[(i+2)%n],l1.s))>0)
||
(bonline3=online(l1,Polygon[(i+2)%n]))&& //下一条边是水平线,前一个端点和后一个端点在射线两侧
((r2=multiply(Polygon[i],Polygon[(i+2)%n],l1.s)*multiply(Polygon[(i+2)%n],Polygon[(i+3)%n],l1.s))>0)
)
)
) c++;
}
if(c%2 == 1)
return 0;
else
return 2;
}
int N,M;
int main()
{
int cn=1;
while(cin>> N && N)
{
if(cn > 1)cout<<endl;
cout<<"Problem "<<cn<<':'<<endl;cn++;
cin>>M;
for(int i=0;i<N;i++)
{
cin>>poly[i].x>>poly[i].y;
}
POINT q;
for(int i=0;i<M;i++)
{
cin>>q.x>>q.y;
if(insidepolygon(N,poly,q) < 2)
{
cout<<"Within\n";
}
else
{
cout<<"Outside\n";
}
}
}
return 0;
}
算法
篇----
几何
算法
几何
算法
1)知道两个点,求直线方程。 (2)求点到直线的距离 3)点到直线的投影 (4)点关于直线的对称点 (5)两条直线的位置关系 (6)两个线段是否会相交 (7)知识点 (8)两个线段的交点 (9)点到线段之间的距离...
计算
几何
算法
的应用
计算
几何
是计算机科学的
一个
分支,专注于创建
几何
问题
求解
算法
。许多行业,包括计算机图形学、机器人技术、地理信息系统、计算机视觉和计算生物学,都在一系列应用中使用这些方法。它是计算机科学的
一个
分支,具有...
计算
几何
学的基本概念和
算法
以上代码只是计算
几何
学中
一个
简单
算法
的C语言实现示例,计算
几何
学涵盖的内容丰富多样,不同的
算法
和应用场景需要根据具体情况进一步扩展和优化代码逻辑以及相关的数据结构等内容。两个成员变量,用于表示点的坐标...
夜深人静写
算法
(四)- 计算
几何
入门
简要介绍计算
几何
的几个
简单
算法
和应用
计算
几何
算法
实战:凸包、Voronoi与Delaunay
计算
几何
是计算机科学和数学的
一个
交叉领域,它研究
几何
数据的计算
问题
,包括
几何
对象的表示、
算法
和数据结构。在现代信息技术中,计算
几何
承担着至关重要的角色,尤其在计算机图形学、机器人学、GIS、CAD等领域。...
数据结构与算法
33,029
社区成员
35,337
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章