# How to position a sprite in a 2D animation skeleton?

Given two joints that define a bone, I would like to know how to decide where, between those two joints, I should draw the sprite. This should be a fairly simple thing to solve, but there is one thing that I am not sure about.

After I've determined the rotation of the sprite (which is the absolute angle the joints form with the x-axis), I also need to determine the origin point from where I need to start drawing the transformed image.

So how should I position the sprite between the two joints? Should I make the center of the image be the midpoint between the two joints, or should I make one the of the joints be the origin? Do these things matter that much (could the wrong positioning make the sprite move oddly during the animation)?

• Are you using the "render a node/scene graph while concatenating matrices" approach or something else? – Torious Jun 9 '12 at 20:56

My 2D animation skeleton looks like this:

The large hollow circles represent constraints that the nodes (filled circles) have to other nodes. For example, I make sure that the elbow stays within some given distance of the shoulder.

To actually draw a sprite between nodes n1 and n2, this is the function call I use in Love2D:

love.graphics.draw(sprite.img -- image
, n1.pos.x -- x coordinate
, n1.pos.y -- y coordinate
, (math.pi/2)-v.dir(n1.pos, n2.pos) -- orientation (radians)
, (n2.pos - n1.pos):len() / len -- x scale
, 1 -- y scale
, sprite.orig.x -- x offset
, sprite.orig.y -- y offset
)


Your framework likely has a similar function.

I use the two nodes' positions to figure out the rotation and scale that the sprite should have. The vector library I use implements these with simple trigonometric functions and Pythagoras' theorem, respectively.

It's quite simple, you calc

vec2 dir = vec2_end_joint - vec2_start_joint
angle = dir.Angle();
//set origin of sprite if required here.
sprite.draw(vec2_start_joint, angle, calculated_scale_if_required);


calculated_scale_if_required - is sprite size and your dir.Magnitude ratio

Or you can use matrix multiplication, like glRotate glScale, to make direct kinematics calculations and use your bones hierarchy.

It sounds like for each bone you are currently defining the texture to be rendered - you might as well allow for more flexibility and include a texture origin offset in your bone structure as well (relative to either of the joints you choose). That way you can be sure the rendered texture will be consistently placed.