# Rotating a group of sprites - How to calculate origin

I am rotating a group of sprites in XNA, which I developed with the help of the following example: http://msdn.microsoft.com/en-us/library/bb194912%28v=xnagamestudio.10%29.aspx

It all works very well, however, the rotations rely on a point of origin, which it will rotate around. The problem is that I do not know how to calculate the point of origin, so that it is exactly in the center of the sprite group.

I am able to set the point of origin to where I want it, but as soon as the sprite group changes, the origin is typically off, and it doesn't rotate from the center of the group.

My main question, is there a way to calculate the center of a group of sprites? My original idea was to calc the boundaries (left, right, top, bottom), and place the origin the the center, but this doesn't work properly.

• Your bounding box solution is conceptually correct. What do you mean by "doesn't work properly"? – sam hocevar Nov 4 '11 at 16:44
• I would guess that it gives too much weight to the outlying sprites, an issue which taking the mean average of the positions would reduce. – Kylotan Nov 4 '11 at 17:40
• Exactly. It looks like it is rotating off center when there are certain combination of sprites, such as a small number of sprites very far off the calculated center. – jgallant Nov 4 '11 at 17:54

If you have three sprites (or if they have very specific relative positions, which almost never happens) there is a special point called the circumcentre which is at an equal distance of each sprite. However, this doesn't scale to more than 3 sprites and doesn't work if they are aligned.

The best solution would probably be to compute the barycentre of all sprites, which is guaranteed to remain at the same position when rotating objects around it. In its basic form it's just a matter of averaging all X and Y coordinates. Also, it allows you to set separate weights for each sprite, if necessary.

Here is some C# code for a list of points:

Point bary = Point.Zero;
foreach (Point p in list)
{
bary.X += p.X;
bary.Y += p.Y;
}
/* Final division by list.Count. Since we handle integers,
* we add list.Count/2 beforehands for rounding */
bary.X = (bary.X + list.Count / 2) / list.Count;
bary.Y = (bary.Y + list.Count / 2) / list.Count;
return bary;