Friday, 15 April 2011

c# - How to position a ring of circles with a maximum ring radius -



c# - How to position a ring of circles with a maximum ring radius -

i'm trying create ring of circles, ala:

the circles have given radius, circleradius. ring has maximum radius, maxringradius. number of circles can integer number, circles, needs calculated, along ring's actual radius, ringradius. circles, when centers placed ringradius units center of ring, should touching, in diagram.

given circleradius, , maxringradius, how can 1 find nearest (or next smallest) ringradius fit integer number of circles, , position circles?

static vector3[] ringofcircles(float maxringradius, float circleradius) { //int circles = ...; // calculate this? //float ringradius = ...; // calculate this? //edit: solution. these 3 lines adapted inbetween's getnextsmallerringradius function unity3d-ized , without validation int circles = mathf.roundtoint(mathf.pi / mathf.asin(circleradius / maxringradius)); float centralangle = 2 * mathf.pi / (numberofcircles - 1); float ringradius = circleradius / mathf.sin(centralangle / 2); // create ring of center points float radspercircle = (mathf.pi * 2) / circles; vector3[] centerpoints = new vector3[circles]; (int i=0; < circles; i++) { float angle = * radspercircle; centerpoints[i] = new vector3( mathf.sin(angle) * ringradius, mathf.cos(angle) * ringradius, 0); } homecoming centerpoints; } `

note: maxringradius minringradius or approximateringradius purposes. ringradius should define next nearest 'ring' can hold whole number of circles.

solved: visual confirmation of solution

if i've understood question correctly, should it:

public static double getnextsmallerringradius(double startingringradius, double circleradius) { debug.assert(startingringradius >= 0); debug.assert(circleradius > 0); int currentnumberofcircles = getcurrentnumberofcircles(startingringradius, circleradius); //let's trivial cases out of way if (currentnumberofcircles == 1) throw new argumentexception(); if (currentnumberofcircles == 2) homecoming 0; //trivial solution 1 circle. if (currentnumberofcircles == 3) homecoming circleradius; //trivial solution 2 circles. double centralangle = 2 * math.pi / (currentnumberofcircles - 1); homecoming circleradius / math.sin(centralangle / 2); } public static double getnextlargerringradius(double startingringradius, double circleradius) { debug.assert(startingringradius >= 0); debug.assert(circleradius > 0); int currentnumberofcircles = getcurrentnumberofcircles(startingringradius, circleradius); //let's trivial cases out of way if (currentnumberofcircles == 1) homecoming circleradius; //trivial solution 2 circles. double centralangle = 2 * math.pi / (currentnumberofcircles + 1); homecoming circleradius / math.sin(centralangle / 2); } private static int getcurrentnumberofcircles(double startingringradius, double circleradius) { if (startingringradius == 0) { homecoming 1; } else { homecoming (int)math.round(math.pi / math.asin(circleradius / startingringradius), 0); //there need logic create sure input values correct. } }

to validate input (defined radii represent valid solution), can compare rounded , not rounded numberofcircles , create sure difference within given tolerance. remember, double can not check equality there representation error.

update whoops, didn't see asking positioning circles. 1 time know ring radius , central angle pretty straightforward.

c# unity3d 2d trigonometry unity3d-2dtools

No comments:

Post a Comment