mathnet / mathnet-spatial

Math.NET Spatial
http://spatial.mathdotnet.com
MIT License
378 stars 132 forks source link

Quaternion as Roll, Pitch And Yaw. #36

Open djowatts opened 8 years ago

djowatts commented 8 years ago

Whilst playing with quaternions, I have found this incredibly useful. Would being able to convert a quaternion to, and create a quaternion from RPY be useful for this library? The code I have for this is using the System.Numerics quaternions, but with some tweaks could slide nicely in here.

JohanLarsson commented 8 years ago

Sounds interesting, thanks for creating the issue. @MaLiN2223 what do you think?

MaLiN2223 commented 8 years ago

Yeah, why not? Expanding is mostly a good idea especially if one have need. @djowatts could you provide example or some related books? It's very interesting. How can I help you with it?

djowatts commented 8 years ago

The code I have using the .Net Numerics stuff is as follows

var roty = Quaternion.Normalize(new Quaternion(0.0f, 0.0f, (float)Math.Sin(rpy.Z / 2.0), (float)Math.Cos(rpy.Z / 2.0))); // yaw is rotation around Z axis
            var rotp = Quaternion.Normalize(new Quaternion(0.0f, (float)Math.Sin(rpy.Y / 2.0), 0.0f, (float)Math.Cos(rpy.Y / 2.0))); // pitch is rotation around Y axis
            var rotr = Quaternion.Normalize(new Quaternion((float)Math.Sin(rpy.X / 2.0), 0.0f, 0.0f, (float)Math.Cos(rpy.X / 2.0))); // roll is rotation around X axis

            //apply in order of roll, pitch, then yaw        
            var first = rotp.RotateRotationQuat(rotr);
            var second = roty.RotateRotationQuat(first);
            return second;

And here is some test data to help you verify

 yield return new object[]
            {
                new Vector3(2.1114570353895603f, -2.585985022981525f, 0.6664081165354347f), // rpy
                new Quaternion(0.3804738214831853f, -0.3695932081905471f, 0.8350484129621588f, -0.14606395734328323f) // expected quat
            };
            yield return new object[]
            {
                new Vector3(1.2221363972810417f, 2.7458063901769885f, -1.1425980259781825f),
                new Quaternion(0.5291170318308547f, 0.6145316070072362f, -0.5602830425963242f, -0.16872754011902086f)
            };
            yield return new object[]
            {
                new Vector3(-1.1211016954494437f, -0.004126944712585345f, 1.9222979397169384f),
                new Quaternion(-0.30297942912094916f, -0.4368753181928898f, 0.6937524685292732f, 0.4858507325228037f)
            };

I'll have a root around and see if I can find the materials we used when writing this and get back to you

rubenvb commented 8 years ago

If you think quaternions are the sh*t, check out geometric algebra ;)!

MaLiN2223 commented 7 years ago

I did some research and in my opinion this is no good idea to put any euler angles (a.k.a. roll, pitch, yaw) to this library - the reason for it is that there at least two possible representations for the same rotation see: this link
I have implemented this approach already and I am ready to make a pull request however it will not be compatibile with already written method (ToEulerAngles()) because (as it appears) I am using different algorithm.

and since it would be suprise to users if they would start getting different results after library update I do not think that is recommended.

Ofcourse for sake of compatibility I can implement a wikipedia's version of the algorithm however I cannot vouch if it is a propper one.

Furthermore I would advise to remove ToEulerAngles() method entirely just to avoid confusion.