Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Given a set of playing cards (rectangle images with a width and height) how can I rotate and position each one so that they appear in a 'fan' pattern, much like you would hold a hand of cards in real life. What math is needed to do this?

UPDATE

Here is the final, in browser implementation in JavaScript: http://jsfiddle.net/tyyvk/108/

share|improve this question
9  
Sir, you seem to have too many aces in your hand. Please step away from the table. –  TomA Jan 14 '12 at 18:53

1 Answer 1

up vote 23 down vote accepted

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:

  1. First stack every card on top of each other by giving them the same initial position.
  2. 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).
  3. 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:

enter image description here


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:

enter image description here

share|improve this answer
7  
I'd add that the look can be tweaked by using a different centre of rotation, if you want to span a smaller arc you should use a rotation point that lies below the card. –  eBusiness Jan 9 '12 at 21:24
    
@eBusiness You're right, I'll add that in. –  David Gouveia Jan 9 '12 at 21:44
    
Thanks a lot David! I've implemented the code you've shown in JavaScript here: jsfiddle.net/tyyvk/7 –  Sembiance Jan 14 '12 at 21:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.