Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distribute angles so that consecutive angles are farthest apart

I'm trying to find a way to distribute n angles from a circle (let's assume at most 360 angles with 1 deg between each, so 0:1:359).

These angles should be generated as needed so that consecutive angles are as far from each other as possible. Angles cannot be repeated, nor can they be modified to accommodate new angles.

Example:

0, 180, 90, 270, 135, 315, 225, 45

and so on.

I've tried and can't seem to quite get how to code it. It may be easier to do if I slightly simplify the way I distribute the angles.

I tried to generate according to the last angle while keeping count of how many angles are generated in the current "wave," since the way the circle is going to be divided will be going up (4 times, 8 times, etc.).

package uniform_angles;

public class UniformAngles {

    public static void main(String[] args) 
    {
        int TOTAL_ANGLES = 360;

        // init number of angles to generate
        int numberOfAngles = 12;
        // store positions in array
        int[] positions = new int[numberOfAngles];

        // init first angle (special case for 0)
        int delta = 180;
        positions[0] = 0;
        int firstOrderPassCount = 1;
        //int secondOrderPassCount = 1;

        // generate
        for (int i = 1; i < numberOfAngles; i++) {
            if ((firstOrderPassCount*delta) == TOTAL_ANGLES) {
                delta /= 2;
            }

            int nextPos = (positions[i-1] + delta) % TOTAL_ANGLES;

            if ((nextPos % delta) == 0) {
                positions[i] = (positions[i-1] + (2*delta)) % TOTAL_ANGLES;
            }
            firstOrderPassCount++;
        }

        for (int i = 0; i < numberOfAngles; i++) {
            System.out.println(positions[i]);
        }
    }
}
like image 441
christophebedard Avatar asked Dec 05 '25 16:12

christophebedard


1 Answers

Just to add interesting tidbit wrt your problem - it looks like what you want to generate is one-dimensional low-discrepancy sequences (aka Quasi-Random MonteCalro).

If you look at Van der Corput/Halton or Sobol sequences in 1D, they look like

0 [1/2, 1/4, 3/4, 1/8, 5/8, 3/8, 7/8, 1/16, ...]

basically, dividing [0...1] interval at largest distance at each step.

Van der Corput/Halton: https://en.wikipedia.org/wiki/Van_der_Corput_sequence

Sobol: http://www.deltaquants.com/sobol-sequence-simplified

There is pretty good Java library from Apache for such things: http://commons.apache.org/proper/commons-math/javadocs/api-3.3/org/apache/commons/math3/random/HaltonSequenceGenerator.html or http://commons.apache.org/proper/commons-math/javadocs/api-3.3/org/apache/commons/math3/random/SobolSequenceGenerator.html

PS You need, of course, map QRNG back to your angle interval, [0...2pi] or [0...360]

like image 67
Severin Pappadeux Avatar answered Dec 08 '25 08:12

Severin Pappadeux



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!