Jump to content


vector matrix multiplication not working?


  • Please log in to reply
12 replies to this topic

#1 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 05 August 2013 - 06:44 PM

it's either that or my eye-point transformation matrix isn't set up correctly...

Either way I'm rewriting my old graphics project (which was done in oberon...) in java and for some reason I can't get the rotations 'n stuff to work.
If i leave em out it works just fine, the image scales and draws just fine.

So this means that i have either:
1. set my rotation matrices wrong (i have checked them litterally 10 times so i think it's quite safe to assume it's not that) OR
2. my vector - matrix multiplication method isn't working properly.

So a little info.

A matrix in this case is simply a 2-dimensional 4 by 4 array of doubles
and a vector is a 1 dimensional array of 3 double values and a boolean to denote if it's a point or a vector.

The reason i gave each of them their own class is so it would make the code more readable and easier to do operations on.

Here's the code responsible for multiplying the 2 values:

public static Vector3D mult(Vector3D lhs, Matrix rhs) throws ParseException
{
if(rhs.get(0, 3)!=0 || rhs.get(1, 3)!=0 || rhs.get(2, 3)!=0 || rhs.get(3, 3)!=1)
throw new ParseException("the matrix multiplificiation thingy just borked");

Vector3D ret = new Vector3D();

double[] temp = new double[NR_DIMS+1]; 
temp[0] = lhs.x;
temp[1] = lhs.y;
temp[2] = lhs.z;
temp[3] = lhs.infty? 0:1; //is it a point or a vector?

double[] vec = lhs.asArray();

for (int i = 0; i < NR_DIMS; i++)
		{
				vec[i] = 0;

				// Multiply the original vector with the i-th column of the matrix.
				for (int j = 0; j <= NR_DIMS; j++)
				{
						vec[i] += temp[j] * rhs.get(j,i);
				}
		}

ret.x = vec[0];
ret.y = vec[1];
ret.z = vec[2];
ret.infty = lhs.infty;

return ret;
}

the code might look a little weird because i have tried all kinds of things but none seem to have worked.
I've been looking at this chunk of code for quite a while so i might just be missing the error.

Are there any smart people willing to help?
ooh shiny

#2 DeCoolJB

DeCoolJB

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 976 posts
  • Joined October 8, 2011
334
  • Male
  • LocationÉrd

Posted 05 August 2013 - 08:08 PM

What is the outcome behavior?  Does the image not rotate?  Does it rotate incorrectly?

for (int j = 0; j <= NR_DIMS; j++)
}
In this statement, j will reach 4 (if I'm correct, NR_DIMS is defined as 4) and therefore, the program will try to access the 5th element of temp and the 5th row of the matrix.  You might want to fix that.
Te vagy egy ostoba

#3 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 06 August 2013 - 07:27 AM

NR_DIMS is a constant set at 3 (because of the vector) and the Matrix is initialised using NR_DIMS + 1 so that should work just fine :)

1. setting my rotations to 0 (or simply not doing them) and ignoring the eye point means the image comes out just fine
2. setting xRotation to 90° only makes the image very narrow and way too high (resolution should be 1000x1000 and is then 138x1000
3. setting yRotation to 90° makes it very wide (1000x138)
4. setting zRotation 90° simply seems to translate the image all the way to the right side of the screen.

(note: all the above are done without the eye point transformation)

5. trying to do the eye point transformation makes for stupidly small coördinates (as in coördinates that look like [-0.002027571306540029, 0.05938634628270456, -123.30022583847628]) and causes an exception because now the program will try to resize the image to have a resolution of 0x0 which obviously isn't allowed.
So there's no way for me to tell if it actually happens correctly or not.

edit: i simiply multiplied all coördinates by 1000 and the image does generate but retardedly small as i thought. The image is also just translated around on the screen seemingly at random in stead of being rotated and such.

Edited by killernerd, 06 August 2013 - 07:32 AM.

ooh shiny

#4 DeCoolJB

DeCoolJB

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 976 posts
  • Joined October 8, 2011
334
  • Male
  • LocationÉrd

Posted 06 August 2013 - 02:00 PM

Could you paste the code for your rotation matrix, just in case?  That sounds like the behavior for an incorrect matrix, although you did say you checked it a lot.
Te vagy egy ostoba

#5 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 06 August 2013 - 02:22 PM

these are the matrices for each rotation:

public static Matrix eye_transformation(Vector3D eye)throws ParseException
{
double r = eye.length();
double teta = Math.atan2(eye.y(), eye.x());
double zr = eye.z()/r;
double fi = Math.acos(zr);

Matrix v = new Matrix();

v.set(0, 0, -Math.sin(teta));
v.set(0, 1, -Math.cos(teta) * Math.cos(fi));
v.set(0, 2, Math.cos(teta) * Math.sin(fi));
v.set(1, 0, Math.cos(teta));
v.set(1, 1, -Math.sin(teta) * Math.cos(fi));
v.set(1, 2, Math.sin(teta) * Math.sin(fi));
v.set(2, 1, Math.sin(fi));
v.set(2, 2, Math.cos(fi));
v.set(3, 2, -r);

return v;
}

public static Matrix z_rotation(double angle) throws ParseException
{
Matrix v = new Matrix();;

v.set(0, 0, Math.cos(angle));
v.set(0, 1, Math.sin(angle));
v.set(1, 0, -Math.sin(angle));
v.set(1, 1, Math.cos(angle));

return v;
}

public static Matrix x_rotation(double angle) throws ParseException
{
Matrix v = new Matrix();;

v.set(1, 1, Math.cos(angle));
v.set(1, 2, Math.sin(angle));
v.set(2, 1, -Math.sin(angle));
v.set(2, 2, Math.cos(angle));

return v;
}

public static Matrix y_rotation(double angle) throws ParseException
{
Matrix v = new Matrix();

v.set(0, 0, Math.cos(angle));
v.set(0, 2, -Math.sin(angle));
v.set(2, 0, Math.sin(angle));
v.set(2, 2, Math.cos(angle));

return v;
}

public static Matrix translation(double a, double b, double c) throws ParseException
{
Matrix v = new Matrix();;

v.set(3, 0, a);
v.set(3, 1, b);
v.set(3, 2, c);

return v;
}

source for these is my old graphics project and unless i made a typo when copying they should be correct.

the idea is that you take each point from your list and multiply them with each rotation matrix like so:

protected void rotate() throws ParseException
{
Matrix rotate_x = Transformations.x_rotation(rotateX);
Matrix rotate_y = Transformations.y_rotation(rotateY);
Matrix rotate_z = Transformations.z_rotation(rotateZ);
Matrix translate = Transformations.translation(center.x(), center.y(), center.z());

for(Vector3D point : points)
{
point = Vector3D.mult(point, scale);
point = Vector3D.mult(point, rotate_x);
point = Vector3D.mult(point, rotate_y);
point = Vector3D.mult(point, rotate_z);
point = Vector3D.mult(point, translate);
point = Vector3D.mult(point, eye);

// if point isn't already on the z-plane project it
if(point.z() != 0)
{
point.setX(point.x()/(-point.z()));
point.setY(point.y()/(-point.z()));
}

//does what it says, checks the "range" of our image lowest x y and highest x y
checkMinMax(point);
}
}

Edited by killernerd, 06 August 2013 - 02:28 PM.

ooh shiny

#6 Phlyrox

Phlyrox

    Newly Christened


  • 2113 posts
  • Joined May 7, 2012
1053

Posted 06 August 2013 - 02:59 PM

idk what you're trying to accomplish, but as for just the multiplication this is what i noticed.
the range for i is 0, 1, and 2. the third last column has to be 0s. and what it looks like from the loop is that you are multiplying a [1x4](x,y,z,&infty) by [4x3](for which the last column is 0s..)
the last column is never considered. is it supposed to? if not just have i for 0 and 1. because vec[2] will just be 0.
other than that the multiplication looks fine.

EDIT: uhhh. looking at the other code now.

EDIT2: are the rotation matrices supposed to be same as these? http://en.wikipedia....Basic_rotations
wow im dumb

Edited by Phlyrox, 06 August 2013 - 03:27 PM.

What about BONER PATROL? #CultBanRefrence also #NeverForget #CelebrityLazerPolice; thanks scout #NeverForget ht p://i.imgur.com/43beiru.png
<Touma> on a scale of phi to pi, how high are you
<Kasen> e

#7 DeCoolJB

DeCoolJB

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 976 posts
  • Joined October 8, 2011
334
  • Male
  • LocationÉrd

Posted 06 August 2013 - 03:35 PM

One problem I can see is that your matrices probably aren't being initialized as identity matrices
Unless your code automatically does so, your 4x4 rotation matrices have to start out as
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
So that multiplication with a vector will result in the same vector.
[1 0 0 0] [z] = [ 1x + 0y + 0z + 0w ]
[0 1 0 0] [y] = [ 0x + 1y + 0z + 0w ]
[0 0 1 0] [z] = [ 0x + 0y + 1z + 0w ]
[0 0 0 1] [w] = [ 0x + 0y + 0z + 1w ]

Then you modify the specific values for an axis rotation, which you do correctly:
Example: X axis
[1 0 0 0]
[0 cos(a) -sin(a) 0]
[0 sin(a) cos(a) 0]
[0 0 0 1]


Also, make sure your vertices are rotated before they are transformed.

Edited by DeCoolJB, 06 August 2013 - 04:54 PM.

Te vagy egy ostoba

#8 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 06 August 2013 - 06:10 PM

View PostPhlyrox, on 06 August 2013 - 02:59 PM, said:

idk what you're trying to accomplish, but as for just the multiplication this is what i noticed.
the range for i is 0, 1, and 2. the third last column has to be 0s. and what it looks like from the loop is that you are multiplying a [1x4](x,y,z,&infty) by [4x3](for which the last column is 0s..)
the last column is never considered. is it supposed to? if not just have i for 0 and 1. because vec[2] will just be 0.
other than that the multiplication looks fine.

EDIT: uhhh. looking at the other code now.

EDIT2: are the rotation matrices supposed to be same as these? http://en.wikipedia....Basic_rotations
wow im dumb

In order to multiply a 3 value vector it's given an additional 1 (if it's a point) or 0 (if it's a vector) to the end so that we can multiply our 4x4 matrix with it.
However, everything is then "projected" onto a return vector with 3 values.

at edit 2: yes those are the ones :)

View PostDeCoolJB, on 06 August 2013 - 03:35 PM, said:

One problem I can see is that your matrices probably aren't being initialized as identity matrices
Unless your code automatically does so, your 4x4 rotation matrices have to start out as
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
So that multiplication with a vector will result in the same vector.
[1 0 0 0] [z] = [ 1x + 0y + 0z + 0w ]
[0 1 0 0] [y] = [ 0x + 1y + 0z + 0w ]
[0 0 1 0] [z] = [ 0x + 0y + 1z + 0w ]
[0 0 0 1] [w] = [ 0x + 0y + 0z + 1w ]

Then you modify the specific values for an axis rotation, which you do correctly:
Example: X axis
[1 0 0 0]
[0 cos(a) -sin(a) 0]
[0 sin(a) cos(a) 0]
[0 0 0 1]


Also, make sure your vertices are rotated before they are transformed.

the constructor takes care of that, i have checked it and they are initialized as the identity matrix.

Normally the order in which i do my operations is always the same (as you can see in my previous post).
scale -> rotateX -> rotateY -> rotateZ -> translate -> eye-point
Nothing happens prior to the rotate method other than the file being read and parsed.

I will do a little test with your suggestion (muliplying a vector with the identity matrix) and report back with the findings.


EDIT: alright, that seems to be working. Multiplying the vector with values [5.0, 6.0, 7.0] with the identity matrix simply returns the same vector...

EDIT2: i have cross-referenced all my transformation matrices with the ones i have in my book and they all check out so i'm pretty much at a loss here. The thing is the problem can't be anywhere else it has everything to do with those rotations...

Edited by killernerd, 06 August 2013 - 06:36 PM.

ooh shiny

#9 DeCoolJB

DeCoolJB

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 976 posts
  • Joined October 8, 2011
334
  • Male
  • LocationÉrd

Posted 06 August 2013 - 07:00 PM

Is angle in radians or degrees?
Te vagy egy ostoba

#10 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 06 August 2013 - 07:08 PM

it's in degrees in the file but converted to radian prior to using.

rotateX = (pi/180)*conf.as_double_or_die(figNr, "rotateX");
rotateY = (pi/180)*conf.as_double_or_die(figNr, "rotateY");
rotateZ = (pi/180)*conf.as_double_or_die(figNr, "rotateZ");

edit: i'm going to sleep now, tomorrow i'll do a line by line comparison of my old code vs my new code. See how that works out.

Edited by killernerd, 06 August 2013 - 07:10 PM.

ooh shiny

#11 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 07 August 2013 - 08:36 AM

Frustrating... I know it's the rotations because the program works fine if i don't do them. But everything checks out so I don't know...
just... dafuq?
ooh shiny

#12 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 08 August 2013 - 03:19 PM

no more suggestions? :c
ooh shiny

#13 killernerd

killernerd

    Servant of Chuck Knoblock the one armed long arm of the Law


  • 257 posts
  • Joined June 10, 2012
18
  • Male
  • Locationunder a bridge

Posted 16 August 2013 - 05:18 PM

shocking development:

soooo I managed to find an old compiler for my code (inside a backup of a backup of my laptop) and i got it to run too... Dem magics.

In any case, it turns out that my transformation magic was working all along.

Soooooo, i'm feeling like a retard right now and I'm going to start debugging parts of my old gibberish code and see what i can dig up.


quick edit:

I found it and I'm feeling increasingly stupid for not seeing it.

So the issue was with the rotations but not in the way you think. I simply forgot that when you use the "for-each" loop you don't get a reference to the object but rather a new copy of it.

Modifying the values of that copy does not affect the original inside the list.

Simple solution: use a list iterator or remove old entry and replace with new one.

Edited by killernerd, 16 August 2013 - 06:03 PM.

ooh shiny


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Welcome to our forum! We would like to encourage you to contribute to our community by posting and talking in the shoutbox.

Please consider joining us by logging in or registering.