pmoule
pmoule

Reputation: 4352

Does concatenation of AffineTransform instances require a specific order in Java?

I have a collection of AffineTranform instances. Depending on specific conditions I need to concatenate any of these - the conditions are not important here. When doing so, I discovered that the order of concatenation seems to be of some importance. Looking at the example, I have:

  1. one original tranformation 'original' which scales and translates2. one identity matrix 'one'
  2. one identity matrix 'two'
  3. one tranformation 'scale' which scales
  4. one tranformation 'translate' which translates

In the example I create the following combinations: 1. one x scale x translate 2. two x translatex scale

Following the Java documentation the matrices should be multiplied when concatenated, but looking at the output of the example code shows different results.

Java version: Java 6 SE Update 30

Example:

package affinetransformationtest;

import java.awt.geom.AffineTransform;

public class AffineTransformationTest {

    public static void main(String[] args) {
        AffineTransform original = new AffineTransform(10, 0.0, 0.0, 100, 2, 3);
        System.out.println("original: " + original);
        System.out.println("");

        AffineTransform scale = AffineTransform.getScaleInstance(10, 100);
        AffineTransform translate= AffineTransform.getTranslateInstance(2, 3);

        AffineTransform one = new AffineTransform();
        System.out.println("one: " + one);
        one.concatenate(scale);
        System.out.println("one + scale: " + one);
        one.concatenate(translate);
        System.out.println("one + scale + translate: " + one);
        System.out.println("Is one equal to original: " + original.equals(one)); //is false
        System.out.println("");

        AffineTransform two = new AffineTransform();
        System.out.println("two: " + two);
        two.concatenate(translate);
        System.out.println("two + translate: " + two);
        two.concatenate(scale);
        System.out.println("two + translate + scale: " + two);
        System.out.println("Is two equal to original: " + original.equals(two)); //is true
        System.out.println("");
    }
}

Output:

original: AffineTransform[[10.0, 0.0, 2.0], [0.0, 100.0, 3.0]]

one: AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
one + scale: AffineTransform[[10.0, 0.0, 0.0], [0.0, 100.0, 0.0]]
one + scale + translate: AffineTransform[[10.0, 0.0, 20.0], [0.0, 100.0, 300.0]]
Is one equal to original: false

two: AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
two + translate: AffineTransform[[1.0, 0.0, 2.0], [0.0, 1.0, 3.0]]
two + translate + scale: AffineTransform[[10.0, 0.0, 2.0], [0.0, 100.0, 3.0]]
Is two equal to original: true

Is there an issue with Java or do I have a mistake in my code?
Thanks for any hint.

Upvotes: 4

Views: 2383

Answers (3)

Babak Naffas
Babak Naffas

Reputation: 12561

Linear algebra (the mathematical model for matrices) is different from basic algebra. One of the simplest differences is that multiplication is not commutative. So A x B will give a different result than B x A.

Upvotes: 0

Sören Titze
Sören Titze

Reputation: 1005

Yes the order of matrix multiplication is important. Check out those simple Examples in which the same matrices are multiplied in different order:

Example1

Example2

Upvotes: 1

stryba
stryba

Reputation: 2027

Order does matter. Look at your second concatenation, you are actually scaling your translation as well since it is applied before.

Upvotes: 1

Related Questions