Question

First of all, sorry for the bad title. I'm not really sure how to title this topic, so feel free to mod it where necessary.

I am drawing X rings inside my stage with given dimensions. To give this some sense of depth, each ring towards the screen boundaries is slightly wider:

enter image description here

The largest ring should be as wide as the largest dimension of the stage (note that in the picture i am drawing 3 extra rings which are drawn outside the stage boundaries). Also it should be twice as wide as the smallest ring. With ring i am refering to the space between 2 red circles.

After calculating an _innerRadius, which is the width of the smallest ring, i am drawing them using

const RINGS:Number = 10;    //the amount of rings, note we will draw 3 extra rings to fill the screen
const DEPTH:Number = 7; //the amount of size difference between rings to create depth effect

var radius:Number = 0;
for (var i:uint = 0; i < RINGS + 3; i++) {
    radius += _innerRadius + _innerRadius * ((i*DEPTH) / (RINGS - 1));
    _graphics.lineStyle(1, 0xFF0000, 1);
    _graphics.drawCircle(0, 0, radius * .5);
}

One of the sliders at the bottom goes from 0-100 being a percentage of the radius for the green ring which goes from the smallest to the largest ring.

I tried lerping between the smallest radius and the largest radius, which works fine if the DEPTH value is 1. However I don't want the distance between the rings to be the same for the sake of the illusion of depth.

Now I've been trying to figure this out for hours but it seems I've run into a wall.. it seems like I need some kind of non-linear formula here.. How would I calculate the radius based on the slider percentage value? Effectively for anywhere in between or on the red circles going from the smallest to the largest red circle?

thanks!

[edit] Here's my example calculation for _innerRadius

//lets calculate _innerRadius for 10 rings
//inner ring width =         X + 0/9 * X;
//ring 1 width =         X + 1/9 * X;
//ring 2 width =         X + 2/9 * X
//ring 3 width =         X + 3/9 * X 
//ring 4 width =         X + 4/9 * X 
//ring 5 width =         X + 5/9 * X
//ring 6 width =         X + 6/9 * X
//ring 8 width =         X + 7/9 * X
//ring 9 width =         X + 8/9 * X
//ring 10 width =        X + 9/9 * X

//extent = Math.max(stage.stageWidth, stage.stageHeight);
//now we should solve extent = X + (X + 0/9 * X) + (X + 1/9 * X) + (X + 2/9 * X) + (X + 3/9 * X) + (X + 4/9 * X) + (X + 5/9 * X) + (X + 6/9 * X) + (X + 7/9 * X) + (X + 8/9 * X) + (X + 9/9 * X);
//lets add all X's
//extent = 10 * X + 45/9 * X
//extent = 15 * X;
//now reverse to solve for _innerRadius
//_innerRadius = extent / 15;
Was it helpful?

Solution

The way your drawing algorithm works, your radii are:

r[i + 1] = r[i] + (1 + i*a)*r0

where a is a constant that is depth / (rings - 1). This results in:

r0
r1 = r0 + (1 + a)*r0 = (2 + a)*r0
r2 = r1 + (1 + 2*a)*r0 = (3 + 3*a)*r0
r3 = r2 + (1 + 3*a)*r0 = (4 + 6*a)*r0
     ...
rn = (1 + n + a * sum(1 ... n))*r0
   = (1 + n + a * n*(n - 1) / 2)*r0

Because you want ring n - 1 to correspond with your outer radius (let's forget about the three extra rings for now), you get:

r[n - 1] = (n + (n - 1)*(n - 2) / 2)*r0
       a = 2 * (extent / r0 - n) / (n - 1) / (n - 2)

Then you can draw the rings:

for (var i = 0; i < rings; i++) {
    r = (1 + i + 0.5 * a * (i - 1)*i) * r0;
    // draw circle with radius r
}

You must have at least three rings in order not to have a division by zero when calculating a. Also note that this does not yield good results for all combinations: if the ratio of outer and inner circles is smaller than the number of rings, you get a negative a and have the depth effect reversed.

Another, maybe simpler, approach to create the depth effect is to make each circle's radius a constant multiple of the previous:

r[i + 1] = r[i] * c

or

r[i] = r0 * Math.pow(c, i)

and draw them like this:

c = Math.pow(extent / r0, 1 / (rings - 1))

r = r0
for (var i = 0; i < rings; i++) {
    // draw circle with radius r        
    r *= c;
}

This will create a "positive" depth effect as long as the ratio of radii is positive. (And as long as there is more than one ring, of course.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top