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.

Recommended Answers

All 5 Replies

You can't achieve your last question. It isn't possible to have an even number of rays that are evenly spaced, with one right in the center. You have to have an odd number to have one in the center.

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.

I think need more R&D for ray distribution method for single algoritham

Unless you already own a copy this book might be of interest.

Unless you already own a copy this book might be of interest.

Thanks for the suggestion. I can look in my local library. Which chapter (or page) are you referring too?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.