判断一个点有没有在扇形区域内

minigpsnet 2006-10-31 02:16:25
//////////////////////////////////////////////////////////////////////////
//判断一个点有没有在扇形区域内
//Pos 圆弧圆心点
//StartPoint 开始点
//EndPoint 结束点
//targetPoint 测试点
inline bool isInArc(const Vector2D& pos,const Vector2D& StartPoint, const Vector2D& EndPoint, const Vector2D& targetPoint)
{

return false;
}
这函数应该怎样写呢?
...全文
1185 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xxduan 2006-11-24
  • 打赏
  • 举报
回复
1.求测试点(X)到圆弧中心点的距离d,再求startpoint(S)或endpoint(E)任何一点到圆弧中心点的距离r;d>r测试点在扇形区域外,判断结束.d<r继续下面的步骤.
2.先进行坐标平移,把圆弧中心点移到坐标原点(O);
3.分别求出向量OS与x轴正向的夹角A(0~360),向量OE与x轴正向的夹角B(0~360),
向量OX与x轴正向的夹角C(0~360);如果A<C<B,X在扇形区域之内,否则在扇形区域之外.

前提是所指扇形是有OS沿顺时针方向旋转到OE形成的.
snookermx 2006-11-19
  • 打赏
  • 举报
回复
以前有人说过 点在不在四边形内的问题,你不妨一试,原理好象没什么区别,


从定点向任意方向引一条射线,判断是否与扇形边相交即可判断在不在扇形内,当然点线重合要多加一个判断‘;
minigpsnet 2006-11-08
  • 打赏
  • 举报
回复
没别的好办法的话就这样结了.
minigpsnet 2006-11-07
  • 打赏
  • 举报
回复
谢谢关注,能再详细点吗?或是来点代码.
dancing999 2006-11-07
  • 打赏
  • 举报
回复
//Pos 圆弧圆心点
//StartPoint 开始点
//EndPoint 结束点
//targetPoint 测试点
求出圆心点与开始点、结束点之间的夹角,范围在0-360度之间,或者取sin,cos等值(注意象限)关系,然后看测试点与圆心点的夹角是否则在上述两点之内,最后判断距离是否在半径之内

minigpsnet 2006-11-07
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/5138/5138743.xml?temp=.9269068
minigpsnet 2006-11-07
  • 打赏
  • 举报
回复
我也想过这个办法,
1.asin函数(MSDN):The asin function returns the arcsine of x in the range –π/2 to π/2 radians. If x is less than –1 or greater than 1, asin returns an indefinite (same as a quiet NaN).
并不能得到0~360之间.最后还是得自己分析它具体在哪个象限
2.asin这样的函数比较低效,手机可能不太合适,当然先可以不予考虑.

谢谢你的支持.过两天没有更好的办法,就此结了.
各位有空也顺便帮我看下另外一个贴.
leibniz_zsu 2006-11-07
  • 打赏
  • 举报
回复
int r = sqrt((startPoint.x-pos.x)*(startPoint.x-pos.x) + (startPoint.y-pos.y)*(startPoint.y-pos.y));
int d = sqrt((targetPoint.x - pos.x)*(targetPoint.x - pos.x) + (targetPoint.y-pos.y)*(targetPoint.y-pos.y));
if(d2 > r2)return false; // 比较半径

float targetAngle = asin((float)(targetPoint.y - pos.y)/r);
float startAngle = asin((float)(startPoint.y-pos.y)/r);
float endAngle = asin((float)(endPoint.y - pos.y)/r);
之后再利用余弦的正负来得到0~360度之间的角度,
这样就可以比较角度了


leibniz_zsu 2006-11-06
  • 打赏
  • 举报
回复
你计算测试点到圆心Pos的距离和它在圆心的那个方向,
再计算StartPoint、EndPoint在圆心哪个方向
最后确定测试点是否在这两个方向之间及它是否超出半径范围
minigpsnet 2006-11-06
  • 打赏
  • 举报
回复
希望有人能给点更好办法。
minigpsnet 2006-11-06
  • 打赏
  • 举报
回复
后来自己用死办法写了个,函数是可以再优化些,我觉得这办法不是太好,不过能用。呵呵。
优化建议:其实测试的是两条边所在的象限之差.
//////////////////////////////////////////////////////////////////////////
//判断一个点有没有在扇形区域内
//Pos 圆弧圆心点
//StartPoint 开始点
//EndPoint 结束点
//targetPoint 测试点
//因为扇形把平面分为两个空间
//按逆时针画的
//不一定要圆弧是不规则扇形也行
inline static bool isInArc(const Vector2D& pos,const Vector2D& StartPoint, const Vector2D& EndPoint, const Vector2D& targetPoint)
{
//这里判断比较烦
//先计算出StartPoint,EndPoint的象限
//原点

Vector2D Neg;
Vector2D o(0, 0);
Vector2D s(StartPoint - pos);
Vector2D e(EndPoint - pos);
Vector2D t(targetPoint - pos);
//注意:s, e的长度不能为0
ASSERT(s.Magnitude());
ASSERT(e.Magnitude());
int sQuad = whichquad(s, o);
int eQuad = whichquad(e, o);
bool a = false, b = false;
//然后再对不同的象限进行分析
switch(sQuad)
{
case 0:
switch(eQuad)
{
case 0:
//已测试过
//利用比较sin(theda)
if (s.y / s.Magnitude() < e.y / s.Magnitude())
{
//s的左边
a = LeftOn(o, s, t);
//e的右边
b = RightOn(o, e, t);

return a && b;
}
else
{
a = Right(o, s, t);
b = Left(o, e, t);
return !(a && b);
}
break;
case 1:
//已测试过
a = LeftOn(o, s, t);
b = RightOn(o, e, t);
return a && b;
break;
case 2:
//已测试过
//这里得判断e在s反向的左还是右
a = Left(o, -s, e);
//如果在左边
//说明s,e之间的夹角大于180
if (a)
{
a = Right(o,s, t);
b = Left(o,e, t);
return !(a && b);
}
else//右边说明s,e之间夹角<=180
{
//s的左边
a = LeftOn( o, s,t);
//e的右边
b = RightOn( o, e,t);
return a && b;
}
break;
case 3:
//已测试过
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
break;
}
break;
case 1:
switch(eQuad)
{
case 0:
//已测试过
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
break;
case 1:
//已测试过
if (s.y / s.Magnitude() > e.y / s.Magnitude())
{
a = LeftOn( o,s, t);
b = RightOn( o, e,t);
return a && b;
}
else
{
a = Right( o,s, t);
b = Left( o, e,t);
return !(a && b);
}
break;
case 2:
//已测试过
a = LeftOn( o,s, t);
b = RightOn( o,e, t);
return a && b;
break;
case 3:
//这里得判断e在s反向的左还是右
a = Left( o,-s, e);
//如果在左边
//说明s,e之间的夹角大于180
if (a)
{
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
}
else//右边说明s,e之间夹角<=180
{
//s的左边
a = LeftOn( o, s,t);
//e的右边
b = RightOn( o,e, t);
return a && b;
}
break;
}
break;
case 2:
switch(eQuad)
{
case 0:
//这里得判断e在s反向的左还是右
a = Left( o,-s, e);
//如果在左边
//说明s,e之间的夹角大于180
if (a)
{
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
}
else//右边说明s,e之间夹角<=180
{
//s的左边
a = LeftOn( o,s, t);
//e的右边
b = RightOn( o, e,t);
return a && b;
}
break;
case 1:
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
break;
case 2:
if (-s.y / s.Magnitude() < -e.y / s.Magnitude())
{
a = LeftOn( o,s, t);
b = RightOn( o,e, t);
return a && b;
}
else
{
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
}
break;
case 3:
a = LeftOn( o,s, t);
b = RightOn( o,e, t);
return a && b;
break;
}
break;
case 3:
switch(eQuad)
{
case 0:
a = LeftOn(o, s, t);
b = RightOn(o, e, t);
return a && b;
break;
case 1:
//这里得判断e在s反向的左还是右
a = Left( o,-s, e);
//如果在左边
//说明s,e之间的夹角大于180
if (a)
{
a = Right( o,s, t);
b = Left(o, e, t);
return !(a && b);
}
else//右边说明s,e之间夹角<=180
{
//s的左边
a = LeftOn( o,s, t);
//e的右边
b = RightOn( o,e, t);
return a && b;
}
break;
case 2:
a = Right( o, s,t);
b = Left( o,e, t);
return !(a && b);
break;
case 3:
if (-s.y / s.Magnitude() > -e.y / s.Magnitude())
{
a = LeftOn( o,s, t);
b = RightOn( o,e, t);
return a && b;
}
else
{
a = Right( o,s, t);
b = Left( o,e, t);
return !(a && b);
}
break;
}
break;
}
return false;
}
minigpsnet 2006-11-06
  • 打赏
  • 举报
回复
谢谢,我是做手机游戏的基本库,没有PtInRegion,也就相当于要自己来实现这个函数.
优途科技 2006-11-03
  • 打赏
  • 举报
回复
nod
BoxFan 2006-11-03
  • 打赏
  • 举报
回复
The PtInRegion function determines whether the specified point is inside the specified region.

BOOL PtInRegion(
HRGN hrgn, // handle to region
int X, // x-coordinate of point
int Y // y-coordinate of point
);

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧