我怎样才能平均分配出几张纸牌?


20

给定一组纸牌(带有宽度和高度的矩形图像),我该如何旋转和定位每张纸牌,使它们以“扇形”模式出现,就像您在现实生活中握住一手纸牌一样。为此需要什么数学运算?

更新

这是最终的JavaScript浏览器实现:https : //cosmicrealms.com/blog/2013/03/16/hand-of-cards/http://jsfiddle.net/tyyvk/108/


9
先生,您手中似乎有太多ace。请离开桌子。
Tomas Andrle'1

需要更新小提琴以使用更高版本的MooTools。
tomdemuyt

Answers:


30

理论

由于您未指定要在哪个平台上实现此功能,因此我将以与语言无关的方式来描述算法:

  1. 首先,给每张卡相同的初始位置,使其相互堆叠
  2. 然后,对每张卡进行旋转(通常以底角之一为中心,但是移动该原点将使您可以微调风扇的外观)。
  3. 根据卡的数量和您希望散布的数量,增加每次通话之间的旋转角度

旋转卡的底部角落之一为中心(或近角),应该看它是明显的:

在此处输入图片说明


实作

至于如何实现,则取决于您的平台。在XNA上,您可以简单地使用Origin参数SpriteBatch.Draw来更改旋转中心。

这是我使用以下代码得到的(对原点进行一些调整以使其看起来更好-基本上,原点在右角附近开始,并在左角附近结束):

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();

结果:

在此处输入图片说明


7
我要补充一点,可以通过使用不同的旋转中心来调整外观,如果要跨越较小的弧线,则应使用位于卡片下方的旋转点。
aaaaaaaaaaaaaa,2012年

@eBusiness您是对的,我将其加入。–
David Gouveia

非常感谢David!我已经实现了您在JavaScript中显示的代码:jsfiddle.net/tyyvk/7
Sembiance,2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.