problem with transformations

Started by
5 comments, last by Zakwayda 16 years, 1 month ago
I'm wondering if this is a correct way to multiply a 3d vector by a 4x4 matrix

   r->x = (v->x * matrix[0]) +
          (v->y * matrix[4]) +
          (v->z * matrix[8]) +
                  matrix[12];

   r->y = (v->x * matrix[1]) +
          (v->y * matrix[5]) +
          (v->z * matrix[9]) +
                  matrix[13];

   r->z = (v->x * matrix[2]) +
          (v->y * matrix[6]) +
          (v->z * matrix[10]) +
                  matrix[14];

where r would be the result, v would be the vector and matrix would be the 4x4 matrix (float matrix[16]). This seems to work on most transformations, but not all, giving weird results. I'm using this on the FrameTransformMatrix of a certain mesh in a directx file, and exporting the models from blender.
Advertisement
That will give you the correct results when the transformation is an affine transformation, and when the elements of the matrix basis vectors are contiguous in memory (that is, you're using either row-vector notation and row-major storage, or column-vector notation and column-major storage).
I see the problem now, I was passing the two pointers to the function like:

Vector v;

function (&v, &v);

so v.x would have been modified, then used when caluculating r.y etc.
In addition to jyk's answer, the code snippet is correct only for position vectors (e.g. vertex positions, the most probable use case). For direction vectors (e.g. normals), you have to drop the summands marix[12], marix[13], and marix[14].
Quote:Original post by haegarr
In addition to jyk's answer, the code snippet is correct only for position vectors (e.g. vertex positions, the most probable use case). For direction vectors (e.g. normals), you have to drop the summands marix[12], marix[13], and marix[14].
Oops, forgot to mention that :-|

@The OP: It looks like you're implementing these functions 'DX-style' (e.g. named functions taking pointers as arguments).

Have you thought about using operator overloading instead? (It would be more idiomatic to do so, IMO - assuming, of course, that you're using a language that supports operator overloading.)
Quote:
Have you thought about using operator overloading instead? (It would be more idiomatic to do so, IMO - assuming, of course, that you're using a language that supports operator overloading.)


Is it really worth coding a matrix and/or vector class? I've atually been thinking about doing this but since im only using 3x3 and 4x4 matrices I never saw any benefits.
Quote:Is it really worth coding a matrix and/or vector class?
I assume you mean as opposed to just using (e.g.) float[16] and so forth? I'd say so. Among other things, using a matrix class will allow you to use proper 2-d indexing, which will make your code clearer and less bug-prone (I suppose you could just use float[4][4], but I'd still go with the class if I were you).

Using classes (or structs) also means you can use operator overloading, which means you can write:
v1 = M * (v1-v2/2);
Instead of:
v1 = multiply(M, subtract(v1, divide(v2, 2)));
Classes provide a lot of other advantages as well, such as member functions (where appropriate), value semantics, and the option of range-checking.

So, I'd say it's definitely worth it (but that's just MHO).

This topic is closed to new replies.

Advertisement