I'm working on a 2D game in XNA based around floc开发者_JAVA技巧king. I've implemented Craig Reynold's flocking technique and now I want to dynamically assign a leader to the group to guide it towards a target.
To do this, I want to find a game agent that does not have any other agents in front of it and make it the leader but I'm unsure of the maths for this.
Currently I have:
Vector2 separation = agentContext.Entity.Position - otherAgent.Entity.Position;
float angleToAgent = (float) Math.Atan2(separation.Y, separation.X);
float angleDifference = Math.Abs(agentContext.Entity.Rotation - angleToAgent);
bool isVisible = angleDifference >= 0 && angleDifference <= agentContext.ViewAngle;
agentContext.ViewAngle is a radians values which I have played with to try and get the right effect but this mostly results in all agents being assigned as leaders.
Can anyone point me in the right direction to detect if an entity is within a "cone" of view of another entity?
You need to normalize the input to the Atan2 function. Also you have to be careful when subtracting angles because the result can be outside the range pi to -pi. I prefer to use direction vectors rather than angles so you can use the dot product operation for this sort of thing as that tends to be faster and you don't have to worry about angles outside of the canonical range.
The following code should achieve the result you are after:
double CanonizeAngle(double angle)
{
if (angle > Math.PI)
{
do
{
angle -= MathHelper.TwoPi;
}
while (angle > Math.PI);
}
else if (angle < -Math.PI)
{
do
{
angle += MathHelper.TwoPi;
} while (angle < -Math.PI);
}
return angle;
}
double VectorToAngle(Vector2 vector)
{
Vector2 direction = Vector2.Normalize(vector);
return Math.Atan2(direction.Y, direction.X);
}
bool IsPointWithinCone(Vector2 point, Vector2 conePosition, double coneAngle, double coneSize)
{
double toPoint = VectorToAngle(point - conePosition);
double angleDifference = CanonizeAngle(coneAngle - toPoint);
double halfConeSize = coneSize * 0.5f;
return angleDifference >= -halfConeSize && angleDifference <= halfConeSize;
}
I think you want to test +/- angle, not just + (ie angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2
). Or use absolute value.
精彩评论