I've created a ray distribution method that generates rays over a fixed angle with an even distribution along the xz plane.
/// <summary>
/// Generates rays that are evenly distrbuted in a circular formation around a point but are restricted to an angle
/// </summary>
/// <param name="point">The point around which the rays are generated</param>
/// <param name="forward">The forward vector from which the angle is taken</param>
/// <param name="angle">The angle over which to distribute the rays (radians)</param>
/// <param name="numRays">The number of rays to generate</param>
/// <returns>Generated rays</returns>
public static CollisionDetection.Ray[] RayDistributionCircular(Vector3 point, Vector3 forward, float angle, int numRays)
{
CollisionDetection.Ray[] rays = new CollisionDetection.Ray[numRays];
// Current heading is based on xz plane
float heading = (float)Math.Atan2(forward.Z, forward.X);
float increment = angle / (float)numRays;
Vector3 f = new Vector3();
f.Y = 0f;
if ((numRays & 2) == 0)
{
// Even number of rays
float currentHeading = 0;
currentHeading = heading - (increment * numRays * 0.5f);
for (int i = 0; i < numRays; ++i)
{
f.X = (float)Math.Cos(currentHeading);
f.Z = (float)Math.Sin(currentHeading);
// Create the ray
rays[i] = new CollisionDetection.Ray(point, f);
currentHeading += increment;
}
}
else
{
// Odd number of rays
// Calculate the direction based on the current heading
// Use xz plane only
f.X = (float)Math.Cos(heading);
f.Z = (float)Math.Sin(heading);
// Create the for the forward direction
rays[0] = new CollisionDetection.Ray(point, f);
float currentHeading = 0;
int j = 1;
float offset = 0;
for (int i = 1; i < numRays; i += 2)
{
offset = increment * j;
currentHeading = heading - offset;
f.X = (float)Math.Cos(currentHeading);
f.Z = (float)Math.Sin(currentHeading);
// Create the ray
rays[i] = new CollisionDetection.Ray(point, f);
currentHeading = heading + offset;
f.X = (float)Math.Cos(currentHeading);
f.Z = (float)Math.Sin(currentHeading);
// Create the ray
rays[i + 1] = new CollisionDetection.Ray(point, f);
j++;
}
}
return rays;
}
I'm currently splitting the algorithm into two separate algorithms to deal with either an even or odd number of rays.
- Even rays are distributed across the angle evenly.
- Odd rays are also distributed evenly but require another ray facing the same direction as the forward direction.
Is there any way to combine the two algorithms and always have a ray that points along the original supplied forward vector? The rays must be evenly spaced and constrained to the angle supplied.