• 11
• 9
• 10
• 9
• 10

Adjusting the amount of spirals for output

This topic is 946 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello,

I have been experimenting with a galaxy type shape in JavaScript. I have got a pretty decent looking shape. But i do not know how to reduce the amount of arms in my maths for the output.

For example, say i wanted to have two spiral arms instead of the amount I currently have for more variability, i cannot figure out how to do it. If i just simply change the values in my maths such as the number of arms i wish to draw, then the shape is lost completely.

I am wondering if there is a better/simpler solution to create the kind of thing I am trying to do.

Here is a working example of the code: http://jsfiddle.net/erh5r4jm/

And the relevant code/logic/maths:

//settings
var a 				= 3;
var numArms                     = 20;
var num				= 100;
var stars			= 5;

//the draw function code:

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

for(s = 0; s < stars; s++){

pX +=  randFloat(-15,15,2); //get random float between range (-15, 15) to 2 decimal places
pY +=  randFloat(-15,15,2);

ctx.beginPath();
ctx.arc(pX+element.width/2,pY+element.height/2, 0.5 , 0, Math.PI*2 ,false);
ctx.fillStyle = "white";
ctx.fill();
ctx.closePath();
}

}
}

Edited by thefollower

Share on other sites

Hi i fixed your code, (this is a simplified version just to give you an idea.

var element 		= document.getElementById('background');
var ctx				= element.getContext("2d");
var flash			= true;
var a 				= 3;
var numArms 		= 3;
var num				= 100;
var twist 			= 20
var stars			= 5;
var	start			= new Date().getTime();
var button	 		= document.getElementById('i');

function refresh(){
draw();
}

function randFloat(min, max, places) {
if(places > 0){
return parseFloat((Math.random() * (max - min) + min).toFixed(places));
}else{
return Math.random() * (max - min) + min;
}
}

function draw(){
ctx.fillStyle = "white";

ctx.clearRect(0,0,element.width,element.height);
for (var arm = 0; arm < numArms; arm++) {
for (var p = 0; p < num; p++) {

var armt = Math.PI*2/numArms *(arm);
console.log(armt);
var pX =  (p * Math.cos((p/twist) + (armt)) -  Math.sin((p/twist) + armt)); //+
var pY =  (p* Math.sin((p/twist) +(armt)) + Math.cos((p/twist) +armt)); //+
ctx.fillRect(pX+element.width/2,pY+element.height/2,1,1);

}
}
}

draw();


Sorry I was not able to save directly a runnable version (maybe I need to be registered). So what you want to do is basically a 2d rotation where you start rotating more the further you get.

First you might want to have a uniform distribution of the "arms" means you want to rotate each arm in equal amount to distribute it in the circle, that s why I get a ration based on numbers of arms:

var armt = Math.PI*2/numArms *(arm);


If you apply this to all your points you will get straight line rotated , then what you want to do is add an extra rotation based on the distance, so since I gave as assumpion we started with a flat vector pointing X so like  vec2 = [p,0], p actually represent your vector length, and I use that as a factor to add rotation, I divide it by a twist factor in order to reduce or augument the aumount of tiwst, in this case reduce otherwise was going to spin like crazy.

So now you can start building on top of this example and ad back in the clouds of points for each arm etc.

The drawing propbably is not the fasted option, there might be a  path line you can use to draw, or you might want to go with webgl buffer.

I am not a javascript programmer so not sure what facility the browser provide you with, i would just use webgl.

Hope it helps

http://postimg.org/image/mvu452hrx/

Edited by giordi

Share on other sites

Hi i fixed your code, (this is a simplified version just to give you an idea.

var element 		= document.getElementById('background');
var ctx				= element.getContext("2d");
var flash			= true;
var a 				= 3;
var numArms 		= 3;
var num				= 100;
var twist 			= 20
var stars			= 5;
var	start			= new Date().getTime();
var button	 		= document.getElementById('i');

function refresh(){
draw();
}

function randFloat(min, max, places) {
if(places > 0){
return parseFloat((Math.random() * (max - min) + min).toFixed(places));
}else{
return Math.random() * (max - min) + min;
}
}

function draw(){
ctx.fillStyle = "white";

ctx.clearRect(0,0,element.width,element.height);
for (var arm = 0; arm < numArms; arm++) {
for (var p = 0; p < num; p++) {

var armt = Math.PI*2/numArms *(arm);
console.log(armt);
var pX =  (p * Math.cos((p/twist) + (armt)) -  Math.sin((p/twist) + armt)); //+
var pY =  (p* Math.sin((p/twist) +(armt)) + Math.cos((p/twist) +armt)); //+
ctx.fillRect(pX+element.width/2,pY+element.height/2,1,1);

}
}
}

draw();


Sorry I was not able to save directly a runnable version (maybe I need to be registered). So what you want to do is basically a 2d rotation where you start rotating more the further you get.

First you might want to have a uniform distribution of the "arms" means you want to rotate each arm in equal amount to distribute it in the circle, that s why I get a ration based on numbers of arms:

var armt = Math.PI*2/numArms *(arm);


If you apply this to all your points you will get straight line rotated , then what you want to do is add an extra rotation based on the distance, so since I gave as assumpion we started with a flat vector pointing X so like  vec2 = [p,0], p actually represent your vector length, and I use that as a factor to add rotation, I divide it by a twist factor in order to reduce or augument the aumount of tiwst, in this case reduce otherwise was going to spin like crazy.

So now you can start building on top of this example and ad back in the clouds of points for each arm etc.

The drawing propbably is not the fasted option, there might be a  path line you can use to draw, or you might want to go with webgl buffer.

I am not a javascript programmer so not sure what facility the browser provide you with, i would just use webgl.

Hope it helps

http://postimg.org/image/mvu452hrx/

Thank you for this. Just a quick question.. how do i make the arms larger in your situation ? I have made a browser fiddle of your code: http://jsfiddle.net/wb1jm8xt/

I am trying to enlarge the arms so it takes up more of the canvas by a pre-determined size but not sure how to go about this.

Share on other sites

so in order to make the spiral bigger or smaller you just need to scale the initial vector size, to scale a vector you multiply each vector member for a scalar, in your case your initial vector is v = [p ,0] so you actually just need to multiply p  by a factor.

in this way

http://jsfiddle.net/wb1jm8xt/5/