Skip to content

Instantly share code, notes, and snippets.

@porglezomp
Last active December 3, 2019 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porglezomp/b37ecc15e2a313096637be59bc8aed40 to your computer and use it in GitHub Desktop.
Save porglezomp/b37ecc15e2a313096637be59bc8aed40 to your computer and use it in GitHub Desktop.
Lets do some proofs about how transforms should behave

Proving some stuff about Andi's transform code at https://github.com/mcclure/lovr/commit/0fe0751fccca7e6c2f3c0046a03f1806a78c8e11

This applies a transform to a vector:

function Loc:apply(v)
    return self.rotate * (v * self.scale) + self.at
end

And this lets you compose two transforms together:

function Loc:compose(v) -- Return Loc equivalent to "apply self, then v"
    return Loc(self:apply(v.at), v.rotate * self.rotate, self.scale * v.scale)
end

If it's supposed to be equivalent to "apply self, then v", then we should have a law that

a:compose(b):apply(v) = b:apply(a:apply(v))

Let a = (x1, r1, s1) and b = (x2, r2, s2). Direct composition of apply is:

b:apply(a:apply(v))
= b:apply(r1 * (v * s1) + x1)
= r2 * ((r1 * (v * s1) + x1) * s2) + x2
= r2 * (r1 * (v * s1) * s2 + x1*s2) + x2
= r2 * (r1 * (v * s1) * s2 + x1*s2 + r2i * x2)
= (r2 * r1) * (v * (s1 * s2)) + (r2 * x1 * s2) + x2

With the compose approach:

a:compose(b):apply(v)

Loc(x, r, s) = a:compose(b)
 where
  x = (r1 * (x2 * s1) + x1)
  r = r2 * r1
  s = s1 * s2


a:compose(b):apply(v)
= Loc(x, r, s):apply(v)
= r * (v * s) + x
= (r2 * r1) * (v * (s1 * s2)) + (r1 * x2 * s1) + x1

These are not equal, the former is + (r2 * x1 * s2) + x2, the latter is + (r1 * x2 * s1) + x1.

If we change the transform code from self:apply(v.at), to v:apply(self.at) then I believe they should match.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment