I am trying to figure out an algorithm to calculate where to place any number of icons for a circular menu on a device with a screen that is 240x320. The icons are 48x48 but can be scaled to any size. I would like to come up with a generic algorithm that will take any number of icons in any size and calculate the best scale for them and the best placement (ie radius and radian divisor).
Currently my code looks like this:
int iconWidth = icon.Width;//this is a poor approximation.
int radius = iconWidth + iconWidth / 2;//defines spacing between square icons
double factor = ((2 * Math.PI) / menuEntries.Count);
//transition is a value that describes the animation curve for the menu
float transitionOffsetR = (float)Math.Pow(TransitionPosition, 2) * radius;
float transitionOffsetP = (float)Math.Pow(TransitionPosition, 2) * (float)factor;
// menuEntries is a collection of objects that describe the menu items
// it has fields like icon and title and callback, things like that.
foreach (MenuEntry entry in menuEntries.Values)
{
int i = menuEntries.IndexOfValue(entry);
iconPos.X = ((float)radius - transitionOffsetR) *
(float)Math.Cos((factor - transitionOffsetP) * i + 1);
iconPos.Y = ((float)radius - transitionOffsetR) *
(float)Math.Sin((factor - transitionOffsetP) * i + 1);
Vector2 finalPos = Vector2.Add(iconPos, origin);
entry.Draw(this, finalPos, isSelected, worldTime, TransitionPosition);
}
What's happening here is this, first I calculate the widths of the icons and do some math to find a reasonable radius and factor. then using the TransitionPosition value that comes from the caller of this method I modify both the radius and divisor for calculating the X and Y values of the icon position. Adding iconPos and origin together (where origin is the coordinate (screen.Width/2, screen.Height/2)) I get the proper final position in world coordinates.
I am also considering drawing it as a graph similar to circo or twopi from the graphviz package.
Any questions or problems please let me know.
Thanks!