Accumulation of transformations

UPDATE: I’ve heavily edited the following based on feedback from Dr. Hoffmann.

One implementation issue I discovered with regards to <animateTransform> is how to accumulate repeated transformations.

Consider the following example:

<svg xmlns="http://www.w3.org/2000/svg">
  <path d="M-2 50h4v -90h4l -6 -10 -6 10h4z" fill="blue">
    <animateTransform attributeName="transform" attributeType="XML"
      type="skewX" fill="freeze" from="0" to="22" dur="0.3s"
      repeatCount="3" accumulate="sum"/>
  </path>
</svg>

A skew operation produces a transformation matrix with one element set to tan(angle), so here it would be tan(22) at the end of the simple duration. After 3 repetitions, what would be the value of this element? If we just accumulate the animation parameters (i.e. angle=22), then we’d get tan(3 * 22), i.e. tan(66). However, if we accumulate using post-multiplication of matrices the answer is not tan(3 * 22) but 3 * tan(22).

In the graphic below the black outline represents the result if we just add up the animation parameters (i.e. skew by 66 degrees), whilst the red outline represents the result when we use matrix multiplication.

In my testing, in Opera 9.62 the arrow ends up inside the black outline whereas in Batik 1.7 it ends up inside the red outline.

So which is correct? SVG 1.1 says that for additive animation (additive="sum") with <animateTransform> we should post-multiply matrices.

However, is the addition used when performing additive animation the same as the addition used when accumulating repetitions? SMILANIM 3.3.1 seems to suggest some relationship between the two when it says:

[The cumulative attribute] is ignored if the target attribute value does not support addition

However, in the SVG Tiny 1.2 Test Suite a different view has been taken. See Dr. Hoffmann’s comments below for a proper explanation. My understanding is that different addition is to be used at different stages of the compositing.

When we are calculating cumulative values, SMIL3 gives us the formula:

fi(t) = (f(d) * i) + f(t - (i*d))

This simply operates on the animation parameters. So in the example at the beginning, it means tan(3 * 22). However, when we come to composite with underlying values in the animation sandwich, a different kind of addition is used. For this, SMIL3 gives the following formula:

F(t,u) = u + ff(t)

Here, for <animateTransform> we should use matrix post-multiplication, i.e. 3 * tan(22).

Comments

Olaf

No, clearly tan(3 * 22) is correct, because there is no specific rule for accumulation in SVG, therefore it applies what is defined in SMIL and this is the addition of the values of the animated attribute and not some multiplication of some abstract effect.

How to calculate the animation effect, is much better described in SMIL2 and SMIL3. This results in a clear procedure and leads clearly to the correct result, simply because the effect of cumulation is calculated much earlier than that of the relation to the underlying value, what is (only) modified for animateTransform by SVG.

I provided exhaustive test for this issues about additive and cumulative behaviour for the SVGT 1.2 test suite, testing all combinations for from-to, from-by, by and values animations.

Brian

What you say makes sense here, I think I’m wrong about this.

Brian

I think I finally understand this, so to clarify, in this formula for additive animation from SMIL3:

F(t,u) = u + fᶠ(t)

the ”+” operation is matrix post-multiplication for <animateTransform>. BUT, in the formula for cumulative animation in SMIL3:

fᵢ(t) = (f(d) * i) + f(t - (i*d))

the ”+” operation is just addition of the animation parameters. Likewise the multiplication operator.

Brian

And yet, SMILANIM 3.3.1 suggests that the types of addition are related when it says:

[The cumulative attribute] is ignored if the target attribute value does not support addition

Olaf

SMIL does not care about animateTransform, therefore there is no reason to reinterprete formulas in SMIL, if this is not noted in SVG, where animateTransform is defined. And there is only the postmultiplication noted for additive behaviour. This means simply, that the SMIL formula for additive=“sum” is not applicable, because it is overwritten by a special SVG rule. Cumulative behaviour is not overwritten, therefore there is no reason to believe, that ’+’ is not ’+‘.

I noted already to the SVG WG, that if there is a need for a specific behaviour for animateTransform, this has to be defined completely in SVG. Except from to-animateTransform maybe, I think, there is no need to do this. Alternatively SMIL could adopt completely animateTransform and to care about it, but all this should have happend several years before. And there is no advantage in having yet another specific rule for cumulative behaviour for animateTransform ;o)

Leave a reply

Most markdown like **bold** and _italic_ is supported.

Never shown. Only used for looking up your gravatar.

Optional
https://