JavaScript Math – Generating Points in a Spiral Motion

javascriptmath

So I have a javascript program that currently gets random points, it generates a random x,y,z value around the center point, within the radius r

  var maxArms = 3;
  var i = 0;
    var color = [];
  for(var arm = 0; arm <= maxArms; arm++) {
    var perArm = (numStars/maxArms);
    var perPoint = Math.ceil((r/10)/5);
    var actualPoints = ((r/10)/5);
    perPoint = (perArm/(actualPoints+(actualPoints/4)));
    var angle = 8;

    for (var ra = 0; ra < 412; ra += 2) {
        for (var p = 0; p < (580-ra); p++) {
        var an = Math.random() * Math.PI * 2;
        var pX = x(ra,angle) + ((Math.cos(an) * (Math.random()*512)) * (Math.random() > .5 ? 1 : -1)), 
                pY = y(ra,angle) + ((Math.cos(an) * (Math.random()*512)) * (Math.random() > .5 ? 1 : -1)),
            pZ = Math.random() * ((r/2)-p) * (1 / ra) * (Math.random() > .5 ? 1 : -1),
                particle = new THREE.Vertex(
                    new THREE.Vector3(pX, pZ, pY)
                );
            innerRing.vertices.push(particle);

            var h = Math.random() * (291 - 185) + 185,
                s = Math.random() * (66 - 34) + 34,
                v = Math.random() * (100 - 72) + 72;
            color[i] = new THREE.Color(0xffffff);
            color[i].setHSV(h / 360, s / 100, v / 100);

        i++;
        }
    }
  }

Now I am trying to find a way rather than just randomly placing things anywhere within the radius, to spiral out the points, into a defined number of "Spiral Arms", I am sure this is going to require something with Sine and Cosine, but I have spent hours now looking to understand how to use these functions to do what I need and I am not sure how to do it.

What I am looking for is I want a variable for the number of arms numArms and I want to have the function above take the number of arms, and create an equal number of points in each arm, and each arm arc out from the center point 0,0 in a spiral motion.

Does that make sense?

I have found other questions, and different answers with google about how to make a spiral, as well as how to find random points (as shown above) but nothing that can help me find random points around spiral arms, but once I have the points for the spiral I am not sure how to get the random x,y,z coordinates around the spiral.

Also, if it is possible, to make it so towards the beginning of each arm there are more points than at the end of the arm.

Yes I know my script is not properly optimized, but I am looking more for function at the moment.

I have attached an image of what the currently generated with the code below, as well as a sample of a spiral galaxy, althought I do not want the center as huge as the second image.


Edit

I have made some changes to the generation script, although rather sloppy, it starts out making stars come from the middle like a spiral, but it inevitably gets larger and no longer looks like a spiral, I have tried playing with all of the variables (ra and angle) but it does not make the spiral look any better, what can I do?

Current Generation:

enter image description here

Sample Generation:

enter image description here

Best Answer

I believe you just need to follow the formula for a spiral, given as,

 x(t) = a * t * cos(t), y(t) = a * t * sin(t) 

where a is constant you can use to express how fast your spiral expands. For the 3D case just add the extra argument z. To define a number of arms, you could just place this inside another for statement. However, if don't want to create a growing 3D spiral, you could fix the z parameter within a certain range. To create the illusion of a galaxy, I believe you could add an offset to x and y and run it multiple times,

var a = 5;
var offset = 2; // You have to choose a good offset for your project.

var numArms = 3;
for (var arm; arm < numArms; arm++) {
    for (var p = 0; p < num; p++) {
        var pX = a * p * cos(p + (Math.PI * arm)) + (Math.random() * offset);
        var pY = a * p * sin(p + (Math.PI * arm)) + (Math.random() * offset);
        var pZ = Math.random() * a;   

        // do something with pX, pY, and pZ
    }
}

Look in here for the original spiral formulas, and to this question, which does something similar using PHP.