Thank for looking into this Benoit, This is not something I am knowledgeable on with so, taking you're word that "vec * matrix" is wrong (why didn't anyone notice this???), heres the upgrade path Sergy and I have agreed on that will not break scripts.
1) deprecate "vec * matrix" immediately. print a warning which includes the python line number, add support for "mat * vec". 2) after some weeks/months, drop support for "vec * matrix", print an error instead, to ensure scripts are not using it and its developers ignoring the warning. 3) for 2.60 release, add in "vec * matrix" which works correctly and not like it does currently, leaving enough time that scripts from 2.58 will have time to switch the multiplication order. On Fri, Jul 22, 2011 at 7:09 PM, Benoit Bolsee <[email protected]> wrote: > Hi, > > I changed the Matrix multiplication order beween 2.49 and 2.5 because it > was simply incorrect in 2.49, in the sense that it was not matching the > way you write matrix math on paper. > > In your example, > >>>> print (m1 * m2) > Matrix((0.0, 0.0, 1.0, 0.0), > (-1.0, 0.0, 0.0, 0.0), > (0.0, -1.0, 0.0, 0.0), > (0.62, 0.1, -0.05, 1.0)) > > is actually the correct answer if you remember that the matrix are > column major. The order should not be changed again. I see Campbell > reverted the patch, so that's ok. > > @Campbell: the reason why numpy returns a different result than Blender > is because numpy matrix are row-major by default. The fact that Blender > uses column major matrix may be confusing when the matrix is printed > (columns are printed horizontally) but it's very convenient to extract > vectors from the matrix (e.g. the position vector). > > While playing around I found something else that still doesn't work: in > the scientific literature, vectors are single column matrix, this means > that the only correct way to multiply a vector with a matrix is to put > it on the right side of the matrix: > v2 = m1 * v1 > However, this doesn't work in Blender > >>>> m > Matrix((1.0, 0.0, 0.0, 0.0), > (0.0, 1.0, 0.0, 0.0), > (1.0, 0.0, -1.0, 0.0), > (0.0, 0.0, 0.0, 1.0)) > >>>> v > Vector((0.5, 0.0, 0.5, 1.0)) > >>>> m*v > Traceback (most recent call last): > File "<blender_console>", line 1, in <module> > TypeError: Matrix multiplication: not supported between > 'mathutils.Matrix' and 'mathutils.Vector' types > > But the reverse expression gives the correct result (i.e the result of m > * v) > >>>> v*m > Vector((1.0, 0.0, -0.5, 1.0)) > > which is illogical and should be fixed. Note that this incorrect form > has one benefit: it allows the use the shortcut expression "v*=m" to > apply a transformation matrix on a vector. > > I pretty certain that I set the matrix*vector multiplication order > correct at the same time I fixed the matrix*matrix multiplication order, > so I don't know where this new error is coming from. Note that v*m is an > acceptable expression if one considers that it turns v into a row > vector, but then the result of the multiplication is different of > course. > In 2.49 it was possible to use both expressions m*v and v*m and they > were producing different results, except that there were the exact > opposite of what you should be by conventional matrix math. > > Campbell, can you trace back what happened with vector multiplication in > Mathutils? > > /Benoit > > On Wed, 20 Jul 2011 20:12:50 -0500, "Scott Giese" > <[email protected]> wrote: >> >> My reasoning for assuming this was a bug: >> >> 1. Previously working scripts (2.49) broke. >> >> 2. m1 *= m2 is equivalent to m1 = m1 * m2, where m1 >> represents the Base matrix and m2 represents the Influencing >> matrix. This is more intuitive to me. >> There is no equivalent shorthand for m1 = m2 * m1. >> >> e.g. Apply a series of transforms to produce a single >> transformation matrix >> contextMatrix = mathutils.Matrix() >> for part in parts: >> contextMatrix *= >> data.tran.matrix[part.matrix_index] >> contextMatrix *= >> data.tran.matrix[part.parent.matrix_index] >> ... >> newObject.matrix_basis = contextMatrix >> >> 3. Treating leftMatrix as the Base and rightMatrix as the >> Influencing facilitates a hypothetical method of varying >> argument counts. >> e.g. resultMatrix = Matrix.Combine(baseMatrix, >> translateMatrix, rotationMatrix, scaleMatrix, ...) >> >> The above outlines my thought process. I was not aware that >> the change was intentional. In light of the "... stop >> breaking APIs?" discussion, we may be better served by >> leaving it as-is. >> >> Scott >> >> -----Original Message----- >> From: Campbell Barton [mailto:[email protected]] >> Sent: Wednesday, July 20, 2011 2:16 AM >> To: bf-blender developers >> Subject: Re: [Bf-committers] Patches Submitted >> >> On Wed, Jul 20, 2011 at 3:37 PM, Scott Giese <[email protected]> >> wrote: >> > Hi Gang, >> > >> > >> > >> > FYI. I submitted 3 patches for your review. ?I'm new to the >> list and I >> > wanted to give back to the Blender community. >> > >> > >> > >> > 28030 ?SCONS Build: Build Date reflects >> > >> <http://projects.blender.org/tracker/index.php?func=detail&aid >> =28030&group_i >> > d=9&atid=127> "1" instead of actual date of build >> > >> > 28031 ?Minor typo in Blenlib >> > >> <http://projects.blender.org/tracker/index.php?func=detail&aid >> =28031&group_i >> > d=9&atid=127> >> > >> > 28032 ?Python Mathutils: Matrix Multiplication Error >> > >> <http://projects.blender.org/tracker/index.php?func=detail&aid >> =28032&group_i >> > d=9&atid=127> >> > >> > >> > >> > Great work guys! ?Appreciate the great product. >> > >> > >> > >> > Scott >> >> Thanks for the fixes, committed all patches however you're >> changes to mathutils effectively only change the order of >> multiplication, >> >> http://projects.blender.org/tracker/index.php?func=detail&aid= >> 28032&group_id >> =9&atid=127 >> >> In you're example >> >>> print (m1 * m2) >> >> Change to... >> >>> print (m2 * m1) >> >> This is a bit confusing because in C we have >> mul_m4_m4m4(m1, m2); >> which is the equivalent to "m2 * m1" in python. >> >> A while back Benoit Bolsee was concerned our matrix >> multiplication order was wrong so we switched it (between >> 2.4x and 2.5x) >> >> What makes you think the order in blender is wrong? what's >> you're reference? >> >> Just checked and we're currently doing matrix multiplication >> differently to numpy which doesn't bode well :S - test: >> >> # --- snip >> m1 = ((0.0, 0.0, 1.0, 0.0), (-1.0, 0.0, 0.0, 0.0), (0.0, >> -1.0, 0.0, 0.0), (0.6, 0.0, -0.05, 1.0)) m2 = ((1.0, 0.0, >> 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, >> -0.02, -0.1, 1.0)) >> >> from numpy import matrix >> n_m1 = matrix(m1) >> n_m2 = matrix(m2) >> print("\nnumpy\n%r" % (n_m1 * n_m2)) >> >> from mathutils import Matrix >> b_m1 = Matrix(m1) >> b_m2 = Matrix(m2) >> print("\nmathutils\n%r" % (b_m1 * b_m2)) >> >> # --- output >> >> numpy >> matrix([[ 0. , 0. , 1. , 0. ], >> [-1. , 0. , 0. , 0. ], >> [ 0. , -1. , 0. , 0. ], >> [ 0.6 , -0.02, -0.15, 1. ]]) >> >> mathutils >> Matrix((0.0, 0.0, 1.0, 0.0), >> (-1.0, 0.0, 0.0, 0.0), >> (0.0, -1.0, 0.0, 0.0), >> (0.62, 0.1, -0.05, 1.0)) >> >> >> # --- switch m1/m2 order for both mathutils and numpy. re-run >> >> numpy >> matrix([[ 0. , 0. , 1. , 0. ], >> [-1. , 0. , 0. , 0. ], >> [ 0. , -1. , 0. , 0. ], >> [ 0.62, 0.1 , -0.05, 1. ]]) >> >> mathutils >> Matrix((0.0, 0.0, 1.0, 0.0), >> (-1.0, 0.0, 0.0, 0.0), >> (0.0, -1.0, 0.0, 0.0), >> (0.6, -0.0, -0.15, 1.0)) > > > _______________________________________________ > Bf-committers mailing list > [email protected] > http://lists.blender.org/mailman/listinfo/bf-committers > -- - Campbell _______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
