
用途: 游戏里使用的检查目标是否在扇形攻击范围内 或者目标是否在扇形视野内
用法: 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; 
|