原理
假设已知扇形半径 弧度 朝向 圆心点
想判断任意点P是否在扇形内,需要两个条件:
1.点P与圆心O的距离不大于 朝向与扇形的交点A到圆心O的距离
2.角AOP的度数不大于扇形度数/2
代码
--- @brief 判断某个点是否在扇形内
--- @public
--- @param _degree number 扇形的弧度
--- @param _radius number 扇形的半径
--- @param _startPos UnityEngine.Vector3 角色所在的位置 扇形的圆心
--- @param _forward UnityEngine.Vector3 角色朝向 标准向量
--- @param _targetPos UnityEngine.Vector3 待判定的点位置
function NgUtils.IsPointFanShaped(_degree, _radius, _startPos, _forward, _targetPos)
_startPos = Vector2.New(_startPos.x, _startPos.z)
_forward = Vector2.New(_forward.x, _forward.z)
_targetPos = Vector2.New(_targetPos.x, _targetPos.z)
--点到圆心距离大于半径 一定不在扇形范围内
if Vector2.Distance(_targetPos, _startPos) > _radius then
return false
end
--圆心到检测点 OP向量
local op = _targetPos - _startPos
--在forward方向投影长度OP'
local projectionLength = Vector2.Dot(_forward, op)
--P O P'的余弦值
local cos = projectionLength / Vector2.Distance(_targetPos, _startPos)
--夹角度数
local degree = Mathf.Deg(Mathf.Acos(cos))
degree = degree * 2
--因为浮点有误差 两位以内看成相等的边界值情况
if Mathf.Abs(degree - _degree) <= 0.01 then
return true
end
--在扇形弧度范围内
return degree <= _degree
end