/**
* Returns whether a circle is within view of an object at the origin
* facing some direction.
*
* @param origin
* The origin of the view.
* @param direction
* The direction of the view, must be a normalized vector.
* @param fov
* The vector where x=cos(FOV/2) and y=sin(FOV/2), must be normalized by definition.
* @param circle
* The center of the circle.
* @param radius
* The radius of the circle.
* @param entirely
* True if this method should return whether the circle is completely
* within view, or false if this method should return whether the circle
* is partially within view.
* @return
* True if the target is in view, otherwise false.
*/
public static boolean isCircleInView( Vector origin, Vector direction, Vector fov, Vector circle, float radius, boolean entirely )
{
// Calculate upper and lower vectors
// Calculate forward vector between target and origin
// Rotate forward by upper, resulting vector.y is the distance from upper to target
// Rotate forward by lower, resulting vector.y is the distance from lower to target
// If it doesn't matter if it's entirely in view, add radius*2 to the distances.
float fovy = Math.abs( fov.y );
float dxfx = direction.x * fov.x;
float dxfy = direction.x * fovy;
float dyfx = direction.y * fov.x;
float dyfy = direction.y * fovy;
float upperX = (dxfx - dyfy);
float upperY = (dxfy + dyfx);
float lowerX = (dxfx + dyfy);
float lowerY = (dyfx - dxfy);
float forwardX = circle.x - origin.x;
float forwardY = circle.y - origin.y;
float upperDist = (upperX * forwardY + upperY * forwardX);
float lowerDist =-(lowerX * forwardY + lowerY * forwardX);
if (!entirely)
{
upperDist += radius * 2;
lowerDist += radius * 2;
}
return (lowerDist >= radius && upperDist >= radius) || // FOV <= 90
(fov.x < 0 && (upperDist >= radius || lowerDist >= radius)); // FOV >= 90
}