ZOJ1081 Points Within
计算几何问题,基本思想从要判断的点引一条射线看和多边形交点的个数,如果是奇数个,那么就在多边形内,否则在多边形外。先判断点是否在多边形边上的情况判掉,再判断线段相交。
#include <iostream>
#include <vector>
using namespace std;
const int MAXSIZE = 100;
const double Max = 100000000;
struct Point
{
double x;
double y;
}points[MAXSIZE];
Point pc;//选择的射线点
double CrossMultiply(const Point& a,const Point& b,const Point& c)
{//叉乘
double x1,y1,x2,y2;
x1= b.x - a.x;
y1 = b.y - a.y;
x2 = c.x - b.x;
y2 = c.y - b.y;
return x1 * y2 - x2 * y1;
}
double interSect(const Point& a,const Point& b,const Point& c,const Point& d)
{
double d1,d2,d3,d4;
d1 = CrossMultiply(a,b,c),
d2 = CrossMultiply(a,b,d),
d3 = CrossMultiply(c,d,a),
d4 = CrossMultiply(c,d,b);
if((d1 * d2) < 0 && (d3 * d4) < 0)
return 1.;
else if((d1 * d2) == 0 || (d3 * d4) == 0)
return 0;
else
return -1.;
}
bool IsOnEdge(const Point& p,const vector<Point>& ptVect)
{//点是否在边上
int i,j,size,minX,maxX,minY,maxY;
size = ptVect.size();//点的数目
for (i=0;i<size;++i)
{
j= i+1;
if (j==size)
{
j=0;
}
if (CrossMultiply(ptVect[i],ptVect[j],p)==0)
{//在同一直线上
if (p.x>=min(ptVect[i].x,ptVect[j].x)&&p.x<=max(ptVect[i].x,ptVect[j].x)&&p.y>=min(ptVect[i].y,ptVect[j].y)&&p.y<=max(ptVect[i].y,ptVect[j].y))
{//在线段内
return true;
}
}
}
return false;
}
bool isInside(const Point& p,const vector<Point>& ptVect)
{//判断点是否在多边形内部
int i,j,num,size;
double d;
num = 0; //射线与线段相交的点的个数
size = ptVect.size();
for(i = 0 ; i <size; ++i)
{ //处理每条线段
j= i+1;
if (j==size)
{
j=0;
}
d = interSect(p,pc,ptVect[i],ptVect[j]);
if(d > 0)
num++; //严格相交
else if(d == 0)
{ //有一端点在另一直线上
if(ptVect[i].y > 0 || ptVect[j].y > 0)
num++;
}
}
if(num % 2 == 0)
return false;
else
return true;
}
int main(void)
{
int N,M,i,pX,pY,cases=0;
while (cin>>N&&N!=0)
{
cin>>M;
if(cases != 0)
cout << endl;
vector<Point> pointVect;
for (i=0;i<N;++i)
{
cin>>points[i].x>>points[i].y;
pointVect.push_back(points[i]);
}
cout << "Problem " << ++cases<< ":" << endl;
for (i=0;i<M;++i)
{
Point p;
cin>>p.x>>p.y;
pc.x = Max,pc.y = p.y;//故意把射线点选择在同一水平线,无穷远处
if (IsOnEdge(p,pointVect))
{//在一条边上
cout<<"Within"<<endl;
continue;
}
else if (isInside(p,pointVect))
{//在多边形内部
cout<<"Within"<<endl;
}
else
{
cout<<"Outside"<<endl;
}
}
}
return 0;
}
#include <vector>
using namespace std;
const int MAXSIZE = 100;
const double Max = 100000000;
struct Point
{
double x;
double y;
}points[MAXSIZE];
Point pc;//选择的射线点
double CrossMultiply(const Point& a,const Point& b,const Point& c)
{//叉乘
double x1,y1,x2,y2;
x1= b.x - a.x;
y1 = b.y - a.y;
x2 = c.x - b.x;
y2 = c.y - b.y;
return x1 * y2 - x2 * y1;
}
double interSect(const Point& a,const Point& b,const Point& c,const Point& d)
{
double d1,d2,d3,d4;
d1 = CrossMultiply(a,b,c),
d2 = CrossMultiply(a,b,d),
d3 = CrossMultiply(c,d,a),
d4 = CrossMultiply(c,d,b);
if((d1 * d2) < 0 && (d3 * d4) < 0)
return 1.;
else if((d1 * d2) == 0 || (d3 * d4) == 0)
return 0;
else
return -1.;
}
bool IsOnEdge(const Point& p,const vector<Point>& ptVect)
{//点是否在边上
int i,j,size,minX,maxX,minY,maxY;
size = ptVect.size();//点的数目
for (i=0;i<size;++i)
{
j= i+1;
if (j==size)
{
j=0;
}
if (CrossMultiply(ptVect[i],ptVect[j],p)==0)
{//在同一直线上
if (p.x>=min(ptVect[i].x,ptVect[j].x)&&p.x<=max(ptVect[i].x,ptVect[j].x)&&p.y>=min(ptVect[i].y,ptVect[j].y)&&p.y<=max(ptVect[i].y,ptVect[j].y))
{//在线段内
return true;
}
}
}
return false;
}
bool isInside(const Point& p,const vector<Point>& ptVect)
{//判断点是否在多边形内部
int i,j,num,size;
double d;
num = 0; //射线与线段相交的点的个数
size = ptVect.size();
for(i = 0 ; i <size; ++i)
{ //处理每条线段
j= i+1;
if (j==size)
{
j=0;
}
d = interSect(p,pc,ptVect[i],ptVect[j]);
if(d > 0)
num++; //严格相交
else if(d == 0)
{ //有一端点在另一直线上
if(ptVect[i].y > 0 || ptVect[j].y > 0)
num++;
}
}
if(num % 2 == 0)
return false;
else
return true;
}
int main(void)
{
int N,M,i,pX,pY,cases=0;
while (cin>>N&&N!=0)
{
cin>>M;
if(cases != 0)
cout << endl;
vector<Point> pointVect;
for (i=0;i<N;++i)
{
cin>>points[i].x>>points[i].y;
pointVect.push_back(points[i]);
}
cout << "Problem " << ++cases<< ":" << endl;
for (i=0;i<M;++i)
{
Point p;
cin>>p.x>>p.y;
pc.x = Max,pc.y = p.y;//故意把射线点选择在同一水平线,无穷远处
if (IsOnEdge(p,pointVect))
{//在一条边上
cout<<"Within"<<endl;
continue;
}
else if (isInside(p,pointVect))
{//在多边形内部
cout<<"Within"<<endl;
}
else
{
cout<<"Outside"<<endl;
}
}
}
return 0;
}
作者:洞庭散人
出处:http://phinecos.cnblogs.com/
本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。
分类:
ACM
, C/C++/VC++
posted on 2008-10-30 20:46 Phinecos(洞庭散人) 阅读(778) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2007-10-30 ubuntu下配置eclipse3.3