Theory
Since you didn't specify in what platform you're implementing this, I'll give a description of the algorithm in a language-agnostic way:
- First stack every card on top of each other by giving them the same initial position.
- Then for each card apply a rotation (usually centered around one of the bottom corners, but moving this origin around will essentialy allow you to tweak the look of the fan).
- Increment the angle of rotation between each call, depending on the number of cards and how much you want them to be spread.
That the rotation is centered around one of the card's bottom corners (or near the corner) should be evident from looking at it:
Implementation
As for how to implement this, it depends on your platform. On XNA you can simply use the Origin parameter of SpriteBatch.Draw
to change the center of your rotation.
Here's what I got with the following code (with a few tweaks to the origin to make it look better - basically the origin starts near the right corner and ends up near the left corner):
int cards = 20;
float range = MathHelper.ToRadians(90);
float initialAngle = MathHelper.ToRadians(-45);
float increment = range / cards;
Vector2 leftCorner = new Vector2(0, texture.Height * 0.9f);
Vector2 rightCorner = new Vector2(texture.Width, texture.Height * 0.9f);
Vector2 fanPosition = new Vector2(400, 300);
spriteBatch.Begin();
for (float angle = 0; angle < range; angle+=increment)
{
float cardAngle = initialAngle + angle;
Vector2 cardOrigin = Vector2.Lerp(rightCorner, leftCorner, angle / range);
spriteBatch.Draw(texture, fanPosition, null, Color.White, cardAngle, cardOrigin, 1f, SpriteEffects.None, 0f);
}
spriteBatch.End();
And the result: