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.