A tail that actually swims

Five frames a fifth of a second apart, camera following the head, spine joints drawn on top.

What changed

  • Before: the sideways wave was sized as 30% of the body's width. A koi is about five times longer than it is wide, so the tail moved only about 6% of the body length, and a koi swimming straight looked rigid.

  • After: the wave is sized as 14% of the body's length at full effort (half that when drifting), and concentrated on the tail: the head moves 6% as much as the tail tip. After the wave is applied, the joints are pulled back to their normal spacing, so a big sway bends the body instead of stretching it.

Why

Koi swim mostly with the back half of the body: the head stays steady and the tail sweeps a fifth to a third of the body length side to side when swimming hard. Tying the wave to length keeps that true for long and short koi.

The code

Before: the wave was a share of the body's width.

public float WaveAmplitude = 0.3f; // fraction of body width

float amplitude = maxWidth * WaveAmplitude * Mathf.Lerp(0.45f, 1f, Mathf.Clamp01(effort));
...
// along: 0 at the head, 1 at the tail
float falloff = 0.1f + 0.9f * Mathf.Pow(along, 1.6f);
Points[i] = joints[i] + side * (Mathf.Sin(wavePhase - i * WaveLength) * amplitude * falloff);

After: the wave is a share of the body's length, falls off faster toward the head, and the joints are re-spaced afterwards.

// Tail-tip sway as a fraction of total length at full effort.
public float WaveAmplitude = 0.14f;

float amplitude = totalLength * WaveAmplitude * Mathf.Lerp(0.5f, 1f, Mathf.Clamp01(effort));
...
float falloff = 0.06f + 0.94f * along * along;
Points[i] = joints[i] + side * (Mathf.Sin(wavePhase - i * WaveLength) * amplitude * falloff);

// Re-chain at the segment length so a big sway bends the body instead of stretching it.
for (int i = 1; i <= last; i++)
{
    Vector2 link = Points[i] - Points[i - 1];
    if (link.sqrMagnitude > 1e-8f) Points[i] = Points[i - 1] + link.normalized * segmentLength;
}

The numbers: with a body five times longer than wide, 0.3 × width is about 6% of the length; 0.14 × length is 14%, so the tail sweeps more than twice as far.

Previous
Previous

Light on the scales: metallic, Ginrin and Doitsu

Next
Next

A thicker tail root