用途:
游戏里使用的检查目标是否在扇形攻击范围内
或者目标是否在扇形视野内
用法:
CRangeFan fan;
fan.setStartAngle(0) // 设置起始角度
fan.setAngleStep(120) // 设置角度范围
fan.setRadius(500) // 设置半径(距离检查)
BOOL bIn = fan.PointHitTest(x, y); // 坐标x, y是否在扇形范围内
注明: 数学好的同志应该有很快和简便的做法吧;-)。
下面是源代码:
lass CRangeFan // 扇形范围对象(适用的坐标系为 : 正上方为0度, 顺时针角度增加)
{
public:
CRangeFan()
:_nAngle(0),
_nAngleStep(60) // 默认角度
{
SetRadius(200); // 默认半径
}
BOOL PointHitTest(int x, int y); // 检查指定点是否在扇形范围
void setStartAngle(int nAngle) // 设置起始角度
{
if(nAngle <= 0) nAngle = 359;
else if(nAngle >= 360) nAngle = 0;
_nAngle = nAngle;
}
void setAngleStep(int nAngleStep) // 设置角度范围
{
if(nAngleStep < 0) nAngleStep = 0;
else if(nAngleStep > 150) nAngleStep = 150;
_nAngleStep = nAngleStep;
}
int getAngleStep() { return _nAngleStep; }
int getStartAngle() { return _nAngle; }
void setPos(int x, int y) // 圆心
{
_nCenterX = x;
_nCenterY = y;
}
void SetRadius(int nRadius) // 半径
{
if(nRadius <0 ) nRadius = 0;
_nRadius = nRadius;
_nTempRadius = nRadius * nRadius;
}
int getRadius() { return _nRadius; }
int getPosX() { return _nCenterX;}
int getPosY() { return _nCenterY;}
static float RADIAN;
protected:
float _Tan2Angle(int nOffX, int nOffY, float fTan);
int _nAngle;
int _nCenterX;
int _nCenterY;
int _nAngleStep;
int _nRadius;
int _nTempRadius;
int _nStartAngle;
};
float CRangeFan::RADIAN = 57.296f; // = 180.0 / 3.1415926
inline BOOL CRangeFan::PointHitTest(int x, int y)
{
int nX = x - _nCenterX;
int nY = _nCenterY - y;
int nDis = nX * nX + nY * nY;
if(nDis > _nTempRadius)
{
return FALSE;
}
float k = (float)(nY) / (float)(nX);
int nAngle = (int)_Tan2Angle(nX, nY, k); // 由斜率按照4个象限转化为0 ~ 360度之间的值
if(_nAngle > 180 && nAngle < 180) // 角度间隔范围不会超过180, 这样可以方便比较
{
nAngle+=360;
}
if(nAngle >= _nAngle && nAngle <= (_nAngle + _nAngleStep))
{
return TRUE;
}
return FALSE;
}
// 斜率转化为0 ~ 360之间的角度值
inline float CRangeFan::_Tan2Angle(int nOffX, int nOffY, float fTan)
{
float fAngle = atan(fTan) * RADIAN;
if(nOffX >= 0 && nOffY >= 0)
{
return 90.0f - fAngle;
}
else if(nOffX >=0 && nOffY < 0)
{
return 180.0f - (90.0f + fAngle);
}
else if(nOffX < 0 && nOffY < 0)
{
return 270.0f - fAngle;
}
else if(nOffX < 0 && nOffY >=0)
{
return 270.0f - fAngle;
}
return fAngle;
}
CRangeFan fan;