Search code examples
c++algorithmmathtrigonometryunreal-engine4

Fanning out an "arc" of card meshes


I have n number of cards. Each card is a units in width.
Many popular card games display a hand of cards in the "fanned out" position (see images below), and I would like to do the same. By utilizing the following formula, I'm able to place cards in an arc:

// NOTE: UE4 uses a left-handed, Z-up coordinate system.
//  (+X = Forward, +Y = Right, and +Z = Up)

// NOTE: Card meshes have their pivot points in the center of the mesh
//  (meshSize * 0.5f = local origin of mesh)

// n = Number of card meshes
// a = Width of each card mesh

const auto arcWidth = 0.8f;
const auto arcHeight = 0.15f;
const auto rotationAngle = 30.f;
const auto deltaAngle = 180.f;
const auto delta = FMath::DegreesToRadians(deltaAngle) / (float)(n);
const auto halfDelta = delta * 0.5f;
const auto halfMeshWidth = a * 0.5f;
const auto radius = halfMeshWidth + (rotationAngle / FMath::Tan(halfDelta));

for (unsigned y = 0; y < n; y++)
{
    auto ArcX = (radius * arcWidth) * FMath::Cos(((float)y * delta) + halfDelta);
    auto ArcY = (radius * arcHeight) * FMath::Sin(((float)y * delta) + halfDelta);
    auto ArcVector = FVector(0.f, ArcX, ArcY);

    // Draw a line from the world origin to the card origin
    DrawDebugLine(GetWorld(), FVector::ZeroVector, ArcVector, FColor::Magenta, true, -1.f, 0, 2.5f);
}

Here's a 5-Card example from Hearthstone: 5-Card hand in Hearthstone

Here's a 5-Card example from Slay The Spire: 5-Card hand in Slay The Spire

But the results I'm producing are, well... Suboptimal: enter image description here

No matter how I tweak the variables, the cards on the far left and far right side are getting squashed together into the hand. I imagine this has to do with how the points of a circle are distributed, and then squashed downwards (via arcHeight) to form an ellipse? In any case, you can see that the results are far from similar, even though if you look closely at the example references, you can see that an arc exists from the center of each card (before those cards are rotated in local space).

What can I do to achieve a more evenly spaced arc?


Solution

  • Your distribution does look like an ellipse. What you need is a very large circle, where the center of the circle is way off the bottom of the screen. Something like the circle below, where the black rectangle is the screen area where you're drawing the cards, and the green dots are the card locations. Note that the radius of the circle is large, and the angles between the cards are small.

    enter image description here