1

I'm trying to implement transform.Rotate on the y axis in Unity using rotation matrix, is it possible? I wrote this function but it doesn't seems to work, pos is the position of the object to rotate and theta is the angle

public static MyQuaternion Rotate(Vector3 pos, float theta)
 {
         pos = pos.normalized;
         pos -= pos;
         float[,] m = new float[3, 3];

         m[0, 0] = Mathf.Cos(theta); 
         m[0, 1] = 0; 
         m[0, 2] = Mathf.Sin(theta);
         m[1, 0] = 0; 
         m[1, 1] = 1; 
         m[1, 2] = 0;
         m[2, 0] = -Mathf.Sin(theta); 
         m[2, 1] = 0; 
         m[2, 2] = Mathf.Cos(theta);

         Vector3 newPos = new Vector3();
         float temp;

         for (int i = 0; i < 3; ++i)
         {
             temp = 0;
             for (int j = 0; j < 3; ++j)
             {
                 temp += m[i, j] * pos[j];
             }
             newPos[i] = temp;
         }

         newPos += pos;

         return new MyQuaternion(newPos.x, newPos.y, newPos.z, 0);
 }

Do you have any idea? Thanks

Keyr
  • 11
  • 3
  • `but it doesn't seems to work` - in what way? Is the end result incorrect? Where did you get this equation from? And are you trying to rotate the point `pos` itself, or create a matrix which rotates objects around `pos`? – meowgoesthedog Dec 16 '18 at 23:12
  • you seem to be rotating the vector sort of all right, but then at the end you take the rotated vector and shove it into a quaternion - this is clrearly wrong. Your method returns a Vector3, not a rotation. if you need a rotation there's already a few methods that generate a quaternion from direction built into Quaternion class – zambari Dec 17 '18 at 08:11
  • @meowgoesthedog I want to rotate the object itself of 90 degrees so i take its coordinates and use it to translate to the origin and apply the basic rotation matrix for the y axis, then i convert the position of the object to a Quaternion (not sure about the conversion) that will be applied to the object. The problem is that the object doesn't rotate, it just remains stationary. – Keyr Dec 17 '18 at 16:49
  • For this you need to return a **4x4** (not 3x3) transformation matrix, i.e. an *affine* transformation in 3-D. Simply returning a quaternion isn't enough, not to mention that you are constructing it in the wrong way as mentioned by `@zambari`. – meowgoesthedog Dec 17 '18 at 16:51
  • @zambari So the wrong part is the convertion to Quaternion? Do you have any idea of how can I generate the quaternion from the resulting vector3? Because I'm rewriting Quaternion class into MyQuaternion so I have to implement that function in my class. Thanks for the answer – Keyr Dec 17 '18 at 16:56
  • @Keyr before you proceed it's worth noting that quaternions cannot store translations, i.e. all rotations will be around the origin. – meowgoesthedog Dec 17 '18 at 18:33
  • @meowgoesthedog But I don't want to translate the object, i just translate it to the origin to rotate it, then i translate it back to its original position. I forgot to explain this last step, sorry. – Keyr Dec 17 '18 at 20:41
  • @Keyr I know, that's what I understood your intention to be. The 2 translations involved (to origin and back) are implicit, and a 3x3 matrix in 3D space cannot include the translational components. You can perform the translations separately on each point before and after the rotation, but it would be significantly less efficient (espcially since many matrix libraries are written with vectorization in mind). – meowgoesthedog Dec 17 '18 at 22:42
  • 1
    Why are you doing this: `pos -= pos;` ? – Ruzihm Dec 17 '18 at 23:15
  • @meowgoesthedog Oh ok, i think i get it, so for a 4x4 matrix I have to add, to my 3x3 matrix, [pos, 0] as last column and [0,0,0,0] as last row and then multiply it to pos? Another solution that just came to my mind is to convert actual quaternion of the object in a matrix and multiply it to my 3x3 matrix, then just reconvert it to quaternion and assign it to the object, could it be right too? – Keyr Dec 18 '18 at 14:42
  • @Keyr For rotation *around* a point, making the last column `[pos, 0]` is not enough – remember that you have to translate by **`-pos`** first, perform the rotation and translate *back* (think about how you would construct this matrix). Also it's odd that you keep wanting to convert back to a quaternion, because direct matrix transformations are more natural and efficient. – meowgoesthedog Dec 18 '18 at 14:51

1 Answers1

0

If you want to get deeply into rotating a vector by hand, you are sort of doing it all right, however I am not sure about the type MyQuaternion you are returning.

If you just want to rotate a vector by an arbitrary angle you can just use Unity's build in Quaternion class. The mutliplication by Vector3 is defined as rotation of that vector so you can just do

Quaternion q=Quaternion.Euler(theta,0,0); // or however you want to map it
Vector3 rotatedVector=q*inputVector;
return rotatedVector;

Rotation in unity is generally done via Quaternion multiplication. To apply it to a gameobject, simply multiply its transform by a rotation you want to perform.

transform.rotation*=Quaternion.Euler(0,0,theta);

Position of an object does not have any play in rotation.

zambari
  • 4,797
  • 1
  • 12
  • 22
  • I saw this implementation of Rotate and I also tried to implement Euler in MyQuaternion. The one i find at http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm give wrong results, resulting in a wrong rotation of my object, while the one i find at https://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine seems to work exactly like Quaternion.Euler, but I don't understand why there's a mismatch between the two methods. – Keyr Dec 18 '18 at 15:44
  • is there a reason you need to re-invent the wheel? Unity has decent support for lots of rotations out of the box, rolling your own methods means handling a lot of strange edge cases – zambari Dec 21 '18 at 21:14
  • I know what you mean, but I'm doing an university project and I need to implement myself this kind of function – Keyr Dec 24 '18 at 17:29