Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matrix3 / 4 multiplier order #11

Closed
naan opened this issue Mar 14, 2017 · 2 comments
Closed

Matrix3 / 4 multiplier order #11

naan opened this issue Mar 14, 2017 · 2 comments

Comments

@naan
Copy link

naan commented Mar 14, 2017

Correct me if I'm wrong or midunderstangind something, but I think the order of matrix multiplication of VectorMath library seems reversed.

    public static func *(lhs: Matrix3, rhs: Matrix3) -> Matrix3 {
        
        return Matrix3(
            lhs.m11 * rhs.m11 + lhs.m21 * rhs.m12 + lhs.m31 * rhs.m13,
            .....
    }

    public static func *(lhs: Matrix4, rhs: Matrix4) -> Matrix4 {
        
        var m = Matrix4.identity
        
        m.m11 = lhs.m11 * rhs.m11 + lhs.m21 * rhs.m12
        m.m11 += lhs.m31 * rhs.m13 + lhs.m41 * rhs.m14
       ....
    }

According to this, algorithm of two matrices is something like this:

screen shot 2017-03-13 at 9 22 22 pm

where I believe VectorMath's * operator represents ABin this equation. (meaning you can write A * B in swift to do same calculation.) If so, the function's lhs and rhs is reversed and since Matrix multiplication is not commutative, it'll produce different results.

I did write a simple Matrix4 <-> CATransform3D conversion code and check something like this:

    let m1 = Matrix4( /* init with some values */)
    let m2 = Matrix4( /* init with some other values */)

    let con1 = CATransform3DConcat(CATransform3D(m1), CATransform3D(m2) )
    let con2 = m1 * m2
    XCTAssertTrue(Matrix4(con1) == con2)  // this should pass, but fails

    let con3 = m2 * m1
    XCTAssertFalse(Matrix4(con1) == con3)  // this should pass, but fails

Here's what CATransform3DConcats document says:

Concatenate 'b' to 'a' and return the result: t' = a * b.

I think it would be better to have reversed order for those methods.

@naan
Copy link
Author

naan commented Mar 14, 2017

Sorry, I think I misunderstood this. If you want to keep apply transform, order of function parameter is better, like those cases:

let m = Matrix4(rotation: ....)
let t = Matrix4(translation: ...)
let s = Matrix4(scale: ...)
let result = t * r * s

Just a bit confusing when you communicate with CATransform3D.

@naan naan closed this as completed Mar 14, 2017
@nicklockwood
Copy link
Owner

Yeah CATransform works the opposite way round to what you'd expect. I think that's because it's view-centric or something, so it transforms objects from the PoV of the camera rather than the layer's own coordinate space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants