vector - java 3D rotations not working -


i've had old graphics project laying around (written in oberon) , since wrote 1 of first projects looks kinda chaotic. descided that, since i'm bored anyway, rewrite in java.

everything far seems work... until try rotate and/or eye-point transformation. if ignore said operations image comes out fine moment try of operations require me multiply point transformation matrix goes bad.

  1. the eye point transformation generates stupidly small numbers end coördinates [-0.002027571306540029, 0.05938634628270456, -123.30022583847628] causes resulting image empty if multiply each point 1000 turns out it's very, small and, in stead of being rotated, has been translated in (seemingly) random direction.

if ignore eye point , focus on rotations results pretty strange (note: image auto scales depending on range of coordinates):

  1. setting xrotation 90° makes image narrow , way high (resolution should 1000x1000 , 138x1000
  2. setting yrotation 90° makes wide (1000x138)
  3. setting zrotation 90° seems translate image way right side of screen.

what have checked far:

  1. i have checked , re-checked rotation matrices @ least 15 times (probably) correct
  2. doing test multiplication vector , identity matrix return original vector
  3. my matrices initialized identity matrices prior being used rotation matrices
  4. the angles in files in degrees converted radian when read.

having said have 2 more notes:

  1. a vector in case simple 3 value array of doubles (representing x, y , z values)
  2. a matrix 4x4 array of doubles initialized identity matrix

when trying rotate them in order:

  1. scale (multiplying scale factor)
  2. rotate along x-axis
  3. rotate along y-axis
  4. rotate along z-axis
  5. translate
  6. do eye-point transformation
  7. then, if point isn't on z-plane, project it

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.z() != 0)             {                 point.setx(point.x()/(-point.z()));                 point.sety(point.y()/(-point.z()));             }              checkminmax(point);         }     } 

here's code initializes rotation matrices if you're interested:

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;     } 

and actual method multiplies point rotation matrix

note: nr_dims defined 3.

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 borked");          vector3d ret = new vector3d();         double[] vec = new double[nr_dims];          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;          (int = 0; < nr_dims; i++)         {                 vec[i] = 0;                  // multiply original vector i-th column of matrix.                 (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;     } 

i've checked , re-checked code old code (note: old code works) , it's identical when comes operations.

so i'm @ loss here, did around similar questions didn't provide useful information.

thanks :)

small addition:

if ignore both eye-point , rotations (so project image) comes out fine. can see image complete apart rotations.

any more suggestions?

a few possible mistakes can think of:

  • in constructor of matrix, not loading identity matrix.
  • you passing angles in degrees instead of radians.
  • your eye-projection matrix projects in range think? mean, in opengl projection matrixes should projection onto rectangle [(-1,-1),(1,1)]. rectangle represents screen.
  • mixing premultiply , postmultiply. id est: do: matrix*vector, in code, seem doing vector*matrix, if i'm not mistaken.
  • mixing columns , rows in matrix?

i'm going take @ question tomorrow. hopefully, 1 of these suggestions helps you.

edit: overlooked checked first 2 items.


Comments

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

Function that returns a formatted array in VBA -