 # Formula to calculate vector components proportional to distance (hairy circle)

Following my previous thread, what I need to find is a formula that calculates the vector components according to its distance from the centre of the circle. Looking at the image above, you see that the hairs move in towards the centre the further away it is from the centre. I’m having trouble finding a good algorithm that simulates this behaviour. I’ve tried using calculating an angle beta=(O,v) with O being the vector from the centre of the circle to the point (x,y), which is the origin of vector v, and v the new vector of the line that we’re drawing for the hair. This means that there should be a limit of what that beta value should be, which is proportional to (x,y)'s distance to the centre. Let’s call this beta_max function :

``````float beta_max(float dist, float dist_max) {
return abs(PI/4-map(dist, 0, dist_max, PI/4, PI/2));
}
``````

So when we draw the next line segment of our hair, we should run a randomGaussian then map it to a range that takes into account the beta angle, but I can’t think of a solution. Right now, all I have is randomising v_x,v_y such that they fit necessary conditions. Needless to say, it doesn’t work but I’ve commented the code well enough to be largely understood. It would be great if advice was given, thanks.

``````            float colour_coeff = abs(1-dist(x,y,width/2,height/2)/(width/2))+2*noise(x,y)-1;
pg.stroke(red(colour)*colour_coeff, green(colour)*colour_coeff, blue(colour)*colour_coeff, colour_alpha);

/* Drawing line */
pg.line(x, y, x+v_x, y+v_y);

/* Moving x, y */
x+=v_x;
y+=v_y;

/* Store old vector coordinates */
v_x_0=v_x;
v_y_0=v_y;

/* Distance between x,y and centre */
float d = dist(width/2, height/2,x,y);
do {

v_x = int(v_norm*randomGaussian());
v_y = int(v_norm*randomGaussian());

/* (Experimental) Setting v_x,v_y by mapping randomGaussian to -1+v_coeff and 1+v_coeff with v_coeff dependant on distance to centre, meaning the further away the x,y with from width/2,height/2, the more likely v_x,v_y will turn take values closer to the centre
v_x = int(v_norm*map(randomGaussian(),-1,1, -1+v_coeff,1+v_coeff);
*/

/* (Experimental) Calculates v_x,v_y between -v_norm,v_norm
v_x = int(random(-v_norm,v_norm));
v_y = int(random(-v_norm,v_norm));
*/

/* (Experimental) Calculates v_x,v_y between v_norm,v_norm using noise function
v_x=int(map(noise(j*x,j*y),0,1,-v_norm,v_norm));
v_y=int(map(noise(j*x,j*y),0,1,-v_norm,v_norm));
*/

/* Variables used to calculate angle beta=(A,B)
* x_A : x-width/2
* x_B : v_x
* y_A : y-height/2
* y_B : v_y
* ||A|| : dist(x,y,width/2,height/2)
* ||B|| : v_norm
*/
beta = acos(((x-width/2)*v_x+(y-height/2)*v_y)/(v_norm*dist(x,y,width/2,height/2)));
// NB: !(A AND B AND ...) = (!A OR !B OR ...)
} while(/* The norm v_x,v_y is not greater than v_norm */
dist(0,0,v_x,v_y)>v_norm

/* 2- The angle between v_x_0,v_y_0 (preceding vector) and v_x,v_y is not greater than alpha_max */
|| acos((v_x_0*v_x+v_y_0*v_y)/(v_norm*v_norm))>alpha_max

/* 3- Angle between x,y and v_x,v_y does not exceed beta_max (specified in beta_max mapping function)