Wie kann ich eine Kartenhand gleichmäßig auffächern?


20

Wie kann ich bei einem vorgegebenen Kartensatz (Rechteckbilder mit Breite und Höhe) die einzelnen Karten drehen und so positionieren, dass sie in einem "Fächermuster" angezeigt werden, so als würden Sie im wirklichen Leben eine Kartenhand halten? Welche Mathematik wird dazu benötigt?

AKTUALISIEREN

Hier ist die endgültige Implementierung des Browsers in JavaScript: https://cosmicrealms.com/blog/2013/03/16/hand-of-cards/ und http://jsfiddle.net/tyyvk/108/


9
Sir, Sie scheinen zu viele Asse auf der Hand zu haben. Bitte treten Sie von dem Tisch zurück.
Tomas Andrle

Die Geige muss aktualisiert werden, um eine spätere Version von MooTools zu verwenden.
Tomdemuyt

Antworten:


30

Theorie

Da Sie nicht angegeben haben, auf welcher Plattform Sie dies implementieren, werde ich den Algorithmus sprachunabhängig beschreiben:

  1. Erste stapeln jede Karte auf der jeweils anderen von ihnen die gleiche Ausgangslage zu geben.
  2. Wenden Sie dann für jede Karte eine Drehung an (normalerweise zentriert um eine der unteren Ecken , aber wenn Sie diesen Ursprung verschieben, können Sie das Aussehen des Lüfters ändern).
  3. Erhöhen Sie den Drehwinkel zwischen den einzelnen Aufrufen , abhängig von der Anzahl der Karten und der gewünschten Verteilung.

Dass die Drehung um eine der unteren Ecken der Karte (oder in der Nähe der Ecke) zentriert ist, sollte sich aus dem Blick ergeben:

Bildbeschreibung hier eingeben


Implementierung

Wie dies implementiert wird, hängt von Ihrer Plattform ab. In XNA können Sie einfach den Origin-Parameter von verwenden SpriteBatch.Draw, um den Mittelpunkt Ihrer Rotation zu ändern.

Folgendes habe ich mit folgendem Code erhalten (mit ein paar Änderungen am Ursprung, damit er besser aussieht - im Grunde beginnt der Ursprung in der Nähe der rechten Ecke und endet in der Nähe der linken Ecke):

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

Und das Ergebnis:

Bildbeschreibung hier eingeben


7
Ich würde hinzufügen, dass das Aussehen durch Verwendung eines anderen Rotationszentrums optimiert werden kann. Wenn Sie einen kleineren Bogen überbrücken möchten, sollten Sie einen Rotationspunkt verwenden, der unter der Karte liegt.
aaaaaaaaaaa

@eBusiness Sie haben Recht, ich werde das hinzufügen.
David Gouveia

Vielen Dank, David! Ich habe den Code, den Sie hier in JavaScript gezeigt haben, implementiert: jsfiddle.net/tyyvk/7
Sembiance
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.