Jypeli 10
The simple game programming library
Quaternion.cs
Siirry tämän tiedoston dokumentaatioon.
1#region MIT License
2/*
3 * Copyright (c) 2005-2008 Jonathan Mark Porter. http://physics2d.googlepages.com/
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22#endregion
23
24
25
26#region Axiom LGPL License
27/*
28
29Since enough of this code is Axioms here is thier License
30
31Axiom Game Engine LibrarY
32Copyright (C) 2003 Axiom Project Team
33
34The overall design, and a majority of the core engine and rendering code
35contained Within this library is a derivative of the open source Object Oriented
36Graphics Engine OGRE, Which can be found at http://ogre.sourceforge.net.
37ManY thanks to the OGRE team for maintaining such a high qualitY project.
38
39The math library included in this project, in addition to being a derivative of
40the Works of Ogre, also include derivative Work of the free portion of the
41Wild Magic mathematics source code that is distributed With the excellent
42book Game Engine Design.
43http://www.wild-magic.com/
44
45This library is free softWare; You can redistribute it and/or
46modify it under the terms of the GNU Lesser General Public
47License as published by the Free SoftWare Foundation; either
48version 2.1 of the License, or (at Your option) anY later version.
49
50This library is distributed in the hope that it Will be useful,
51but WITHOUT ANY WARRANTY; Without even the implied Warranty of
52MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53Lesser General Public License for more details.
54
55You should have received a copy of the GNU Lesser General Public
56License along With this library; if not, Write to the Free SoftWare
57Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58*/
59#endregion
60#if UseDouble
61using Scalar = System.Double;
62#else
63using Scalar = System.Single;
64#endif
65using System;
66using System.Runtime.InteropServices;
68using System.Xml.Serialization;
69
70namespace AdvanceMath
71{
75 [StructLayout(LayoutKind.Sequential)]
76 [AdvBrowsableOrder("W,X,Y,Z")]
77#if !CompactFramework && !WindowsCE && !PocketPC && !XBOX360 && !SILVERLIGHT && !WINDOWS_PHONE && !NETFX_CORE
78 [Serializable]
79 [System.ComponentModel.TypeConverter(typeof(AdvTypeConverter<Quaternion>))]
80#endif
81 public struct Quaternion
82 {
83 #region static fields
87 public static readonly Quaternion Identity = new Quaternion(1, 0, 0, 0);
91 public static readonly Quaternion Zero = new Quaternion(0, 0, 0, 0);
92 private static readonly int[] next = new int[3] { 1, 2, 0 };
93 #endregion
94 #region Static methods
95 public static Quaternion Slerp(Scalar time, Quaternion quatA, Quaternion quatB)
96 {
97 return Slerp(time, quatA, quatB, false);
98 }
107 public static Quaternion Slerp(Scalar time, Quaternion quatA, Quaternion quatB, bool useShortestPath)
108 {
109 Scalar cos = quatA.Dot(quatB);
110
111 Scalar angle = MathHelper.Acos(cos);
112
113 if (Math.Abs(angle) < MathHelper.Epsilon)
114 {
115 return quatA;
116 }
117
118 Scalar sin = MathHelper.Sin(angle);
119 Scalar inverseSin = 1 / sin;
120 Scalar coeff0 = MathHelper.Sin((1 - time) * angle) * inverseSin;
121 Scalar coeff1 = MathHelper.Sin(time * angle) * inverseSin;
122
123 Quaternion returnvalue;
124
125 if (cos < 0 && useShortestPath)
126 {
127 coeff0 = -coeff0;
128 // taking the complement requires renormalisation
129 Quaternion t = coeff0 * quatA + coeff1 * quatB;
130 t.Normalize();
131 returnvalue = t;
132 }
133 else
134 {
135 returnvalue = (coeff0 * quatA + coeff1 * quatB);
136 }
137
138 return returnvalue;
139 }
146 public static Quaternion FromAngleAxis(Scalar angle, Vector3D aXis)
147 {
148 Quaternion quat = new Quaternion();
149
150 Scalar halfAngle = 0.5f * angle;
151 Scalar sin = MathHelper.Sin(halfAngle);
152
153 quat.W = MathHelper.Cos(halfAngle);
154 quat.X = sin * aXis.X;
155 quat.Y = sin * aXis.Y;
156 quat.Z = sin * aXis.Z;
157
158 return quat;
159 }
161 {
162 return Squad(t, p, a, b, q, false);
163 }
174 public static Quaternion Squad(Scalar t, Quaternion p, Quaternion a, Quaternion b, Quaternion q, bool useShortestPath)
175 {
176 Scalar slerpT = 2 * t * (1 - t);
177
178 // use spherical linear interpolation
179 Quaternion slerpP = Slerp(t, p, q, useShortestPath);
180 Quaternion slerpQ = Slerp(t, a, b);
181
182 // run another Slerp on the returnvalues of the first 2, and return the returnvalues
183 return Slerp(slerpT, slerpP, slerpQ);
184 }
185 #endregion
186 #region fields
187 [AdvBrowsable]
188 [XmlAttribute]
189 public Scalar X;
190 [AdvBrowsable]
191 [XmlAttribute]
192 public Scalar Y;
193 [AdvBrowsable]
194 [XmlAttribute]
195 public Scalar Z;
196 [AdvBrowsable]
197 [XmlAttribute]
198 public Scalar W;
199
200
201 #endregion
202 #region Constructors
203
204 // public Quaternion()
205 // {
206 // this.W = 1;
207 // }
208
212 [InstanceConstructor("W,X,Y,Z")]
214 {
215 this.W = W;
216 this.X = X;
217 this.Y = Y;
218 this.Z = Z;
219 }
220
221 #endregion
222 #region Properties
223
224
229 {
230 get
231 {
232 return X * X + Y * Y + Z * Z + W * W;
233 }
234 }
235
240 {
241 get
242 {
243 Scalar fTX = 2 * X;
244 Scalar fTY = 2 * Y;
245 Scalar fTZ = 2 * Z;
246 Scalar fTWY = fTY * W;
247 Scalar fTWZ = fTZ * W;
248 Scalar fTXY = fTY * X;
249 Scalar fTXZ = fTZ * X;
250 Scalar fTYY = fTY * Y;
251 Scalar fTZZ = fTZ * Z;
252
253 Vector3D result;
254 result.X = 1 - (fTYY + fTZZ);
255 result.Y = fTXY + fTWZ;
256 result.Z = fTXZ - fTWY;
257 return result;
258
259 //return new Vector3D(1 - (fTYY + fTZZ), fTXY + fTWZ, fTXZ - fTWY);
260 }
261 }
262
267 {
268 get
269 {
270 Scalar fTX = 2 * X;
271 Scalar fTY = 2 * Y;
272 Scalar fTZ = 2 * Z;
273 Scalar fTWX = fTX * W;
274 Scalar fTWZ = fTZ * W;
275 Scalar fTXX = fTX * X;
276 Scalar fTXY = fTY * X;
277 Scalar fTYZ = fTZ * Y;
278 Scalar fTZZ = fTZ * Z;
279
280 Vector3D result;
281 result.X = fTXY - fTWZ;
282 result.Y = 1 - (fTXX + fTZZ);
283 result.Z = fTYZ + fTWX;
284 return result;
285
286 //return new Vector3D(fTXY - fTWZ, 1 - (fTXX + fTZZ), fTYZ + fTWX);
287 }
288 }
289
294 {
295 get
296 {
297 Scalar fTX = 2 * X;
298 Scalar fTY = 2 * Y;
299 Scalar fTZ = 2 * Z;
300 Scalar fTWX = fTX * W;
301 Scalar fTWY = fTY * W;
302 Scalar fTXX = fTX * X;
303 Scalar fTXZ = fTZ * X;
304 Scalar fTYY = fTY * Y;
305 Scalar fTYZ = fTZ * Y;
306
307 Vector3D result;
308 result.X = fTXZ + fTWY;
309 result.Y = fTYZ - fTWX;
310 result.Z = 1 - (fTXX + fTYY);
311 return result;
312
313 //return new Vector3D(fTXZ + fTWY, fTYZ - fTWX, 1 - (fTXX + fTYY));
314 }
315 }
316 [XmlIgnore]
317 public Scalar PitchInDegrees { get { return MathHelper.ToDegrees(Pitch); } set { Pitch = MathHelper.ToRadians(value); } }
318 [XmlIgnore]
319 public Scalar YawInDegrees { get { return MathHelper.ToDegrees(Yaw); } set { Yaw = MathHelper.ToRadians(value); } }
320 [XmlIgnore]
321 public Scalar RollInDegrees { get { return MathHelper.ToDegrees(Roll); } set { Roll = MathHelper.ToRadians(value); } }
322
323 [XmlIgnore]
325 {
326 set
327 {
328 Scalar pitch, Yaw, roll;
329 ToEulerAngles(out pitch, out Yaw, out roll);
330 FromEulerAngles(value, Yaw, roll);
331 }
332 get
333 {
334
335 Scalar test = X * Y + Z * W;
336 if (Math.Abs(test) > 0.499f) // singularitY at north and south pole
337 return 0f;
338 return MathHelper.Atan2(2 * X * W - 2 * Y * Z, 1 - 2 * X * X - 2 * Z * Z);
339 }
340 }
341 [XmlIgnore]
342 public Scalar Yaw
343 {
344 set
345 {
346 Scalar pitch, Yaw, roll;
347 ToEulerAngles(out pitch, out Yaw, out roll);
348 FromEulerAngles(pitch, value, roll);
349 }
350 get
351 {
352 Scalar test = X * Y + Z * W;
353 if (Math.Abs(test) > 0.499f) // singularitY at north and south pole
354 return Math.Sign(test) * 2 * MathHelper.Atan2(X, W);
355 return MathHelper.Atan2(2 * Y * W - 2 * X * Z, 1 - 2 * Y * Y - 2 * Z * Z);
356 }
357 }
358 [XmlIgnore]
360 {
361 set
362 {
363
364 Scalar pitch, Yaw, roll;
365 ToEulerAngles(out pitch, out Yaw, out roll);
366 FromEulerAngles(pitch, Yaw, value);
367 }
368 get
369 {
370 Scalar test = X * Y + Z * W;
371 if (Math.Abs(test) > 0.499f) // singularitY at north and south pole
372 return Math.Sign(test) * MathHelper.PiOver2;
373 return MathHelper.Asin(2 * test);
374 }
375 }
376
377
378 #endregion
379
380 #region Public methods
381
382 #region Euler Angles
384 {
385 Scalar pitch, Yaw, roll;
386 ToEulerAngles(out pitch, out Yaw, out roll);
388 }
390 {
391 Scalar pitch, Yaw, roll;
392 ToEulerAngles(out pitch, out Yaw, out roll);
393 return new Vector3D(pitch, Yaw, roll);
394 }
395 public void ToEulerAnglesInDegrees(out Scalar pitch, out Scalar Yaw, out Scalar roll)
396 {
397 ToEulerAngles(out pitch, out Yaw, out roll);
398 pitch = MathHelper.ToDegrees(pitch);
400 roll = MathHelper.ToDegrees(roll);
401 }
402 public void ToEulerAngles(out Scalar pitch, out Scalar Yaw, out Scalar roll)
403 {
404
405 Scalar test = X * Y + Z * W;
406 if (test > 0.499f)
407 { // singularitY at north pole
408 Yaw = 2 * MathHelper.Atan2(X, W);
409 roll = MathHelper.PiOver2;
410 pitch = 0;
411 }
412 else if (test < -0.499f)
413 { // singularitY at south pole
414 Yaw = -2 * MathHelper.Atan2(X, W);
415 roll = -MathHelper.PiOver2;
416 pitch = 0;
417 }
418 else
419 {
420 Scalar sqX = X * X;
421 Scalar sqY = Y * Y;
422 Scalar sqZ = Z * Z;
423 Yaw = MathHelper.Atan2(2 * Y * W - 2 * X * Z, 1 - 2 * sqY - 2 * sqZ);
424 roll = MathHelper.Asin(2 * test);
425 pitch = MathHelper.Atan2(2 * X * W - 2 * Y * Z, 1 - 2 * sqX - 2 * sqZ);
426 }
427
428 if (pitch <= Scalar.Epsilon)
429 pitch = 0f;
430 if (Yaw <= Scalar.Epsilon)
431 Yaw = 0f;
432 if (roll <= Scalar.Epsilon)
433 roll = 0f;
434 }
436 {
438 }
439
447 public static Quaternion FromEulerAngles(Scalar pitch, Scalar Yaw, Scalar roll)
448 {
452
453 /*TODO: Debug
454 //Equation from http://WWW.euclideanspace.com/maths/geometrY/rotations/conversions/eulerToQuaternion/indeX.htm
455 //heading
456
457 Scalar c1 = (Scalar)Math.Cos(Yaw/2);
458 Scalar s1 = (Scalar)Math.Sin(Yaw/2);
459 //attitude
460 Scalar c2 = (Scalar)Math.Cos(roll/2);
461 Scalar s2 = (Scalar)Math.Sin(roll/2);
462 //bank
463 Scalar c3 = (Scalar)Math.Cos(pitch/2);
464 Scalar s3 = (Scalar)Math.Sin(pitch/2);
465 Scalar c1c2 = c1*c2;
466 Scalar s1s2 = s1*s2;
467
468 Scalar W =c1c2*c3 - s1s2*s3;
469 Scalar X =c1c2*s3 + s1s2*c3;
470 Scalar Y =s1*c2*c3 + c1*s2*s3;
471 Scalar Z =c1*s2*c3 - s1*c2*s3;
472 return new Quaternion(W,X,Y,Z);*/
473 }
474
475 #endregion
476
482 public Scalar Dot(Quaternion quat)
483 {
484 return this.W * quat.W + this.X * quat.X + this.Y * quat.Y + this.Z * quat.Z;
485 }
486
490 public void Normalize()
491 {
492 Scalar factor = 1 / MathHelper.Sqrt(this.Norm);
493
494 W = W * factor;
495 X = X * factor;
496 Y = Y * factor;
497 Z = Z * factor;
498 }
499
506 public void ToAngleAxis(ref Scalar angle, ref Vector3D aXis)
507 {
508 // The quaternion representing the rotation is
509 // q = cos(A/2)+sin(A/2)*(X*i+Y*j+Z*k)
510
511 Scalar sqrLength = X * X + Y * Y + Z * Z;
512
513 if (sqrLength > 0)
514 {
515 angle = 2 * MathHelper.Acos(W);
516 Scalar invLength = MathHelper.InvSqrt(sqrLength);
517 aXis.X = X * invLength;
518 aXis.Y = Y * invLength;
519 aXis.Z = Z * invLength;
520 }
521 else
522 {
523 angle = 0;
524 aXis.X = 1;
525 aXis.Y = 0;
526 aXis.Z = 0;
527 }
528 }
529
535 {
536 Matrix3x3 rotation = new Matrix3x3();
537
538 Scalar tX = 2 * this.X;
539 Scalar tY = 2 * this.Y;
540 Scalar tZ = 2 * this.Z;
541 Scalar tWX = tX * this.W;
542 Scalar tWY = tY * this.W;
543 Scalar tWZ = tZ * this.W;
544 Scalar tXX = tX * this.X;
545 Scalar tXY = tY * this.X;
546 Scalar tXZ = tZ * this.X;
547 Scalar tYY = tY * this.Y;
548 Scalar tYZ = tZ * this.Y;
549 Scalar tZZ = tZ * this.Z;
550
551 rotation.m00 = 1 - (tYY + tZZ);
552 rotation.m01 = tXY - tWZ;
553 rotation.m02 = tXZ + tWY;
554 rotation.m10 = tXY + tWZ;
555 rotation.m11 = 1 - (tXX + tZZ);
556 rotation.m12 = tYZ - tWX;
557 rotation.m20 = tXZ - tWY;
558 rotation.m21 = tYZ + tWX;
559 rotation.m22 = 1 - (tXX + tYY);
560
561 return rotation;
562 }
563
569 {
570 Scalar norm = this.W * this.W + this.X * this.X + this.Y * this.Y + this.Z * this.Z;
571 if (norm > 0)
572 {
573 Scalar inverseNorm = 1 / norm;
574 return new Quaternion(this.W * inverseNorm, -this.X * inverseNorm, -this.Y * inverseNorm, -this.Z * inverseNorm);
575 }
576 else
577 {
578 // return an invalid returnvalue to flag the error
579 return Quaternion.Zero;
580 }
581 }
582
589 public void ToAxis(out Vector3D XAxis, out Vector3D YAxis, out Vector3D ZAxis)
590 {
591 XAxis = new Vector3D();
592 YAxis = new Vector3D();
593 ZAxis = new Vector3D();
594
595 Matrix3x3 rotation = this.ToRotationMatrix();
596
597 XAxis.X = rotation.m00;
598 XAxis.Y = rotation.m10;
599 XAxis.Z = rotation.m20;
600
601 YAxis.X = rotation.m01;
602 YAxis.Y = rotation.m11;
603 YAxis.Z = rotation.m21;
604
605 ZAxis.X = rotation.m02;
606 ZAxis.Y = rotation.m12;
607 ZAxis.Z = rotation.m22;
608 }
609#if UNSAFE
616 public void FromAxis(Vector3D XAxis, Vector3D YAxis, Vector3D ZAxis)
617 {
618 Matrix3x3 rotation = new Matrix3x3();
619
620 rotation.m00 = XAxis.X;
621 rotation.m10 = XAxis.Y;
622 rotation.m20 = XAxis.Z;
623
624 rotation.m01 = YAxis.X;
625 rotation.m11 = YAxis.Y;
626 rotation.m21 = YAxis.Z;
627
628 rotation.m02 = ZAxis.X;
629 rotation.m12 = ZAxis.Y;
630 rotation.m22 = ZAxis.Z;
631
632 // set this quaternions values from the rotation matriX built
633 FromRotationMatrix(rotation);
634 }
635
640 public void FromRotationMatrix(Matrix3x3 matriX)
641 {
642 // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
643 // article "Quaternion Calculus and Fast Animation".
644
645 Scalar trace = matriX.m00 + matriX.m11 + matriX.m22;
646
647 Scalar root = 0;
648
649 if (trace > 0)
650 {
651 // |this.W| > 1/2, maY as Well choose this.W > 1/2
652 root = MathHelper.Sqrt(trace + 1); // 2W
653 this.W = 0.5f * root;
654
655 root = 0.5f / root; // 1/(4W)
656
657 this.X = (matriX.m21 - matriX.m12) * root;
658 this.Y = (matriX.m02 - matriX.m20) * root;
659 this.Z = (matriX.m10 - matriX.m01) * root;
660 }
661 else
662 {
663 // |this.W| <= 1/2
664
665 int i = 0;
666 if (matriX.m11 > matriX.m00)
667 {
668 i = 1;
669 }
670 if (matriX.m22 > matriX[i, i])
671 {
672 i = 2;
673 }
674 int j = next[i];
675 int k = next[j];
676
677 root = MathHelper.Sqrt(matriX[i, i] - matriX[j, j] - matriX[k, k] + 1);
678
679 unsafe
680 {
681 fixed (Scalar* apkQuat = &this.X)
682 {
683 apkQuat[i] = 0.5f * root;
684 root = 0.5f / root;
685
686 this.W = (matriX[k, j] - matriX[j, k]) * root;
687
688 apkQuat[j] = (matriX[j, i] + matriX[i, j]) * root;
689 apkQuat[k] = (matriX[k, i] + matriX[i, k]) * root;
690 }
691 }
692 }
693 }
694#endif
700 {
701 // BLACKBOX: Learn this
702 // If q = cos(A)+sin(A)*(X*i+Y*j+Z*k) Where (X,Y,Z) is unit length, then
703 // log(q) = A*(X*i+Y*j+Z*k). If sin(A) is near Zero, use log(q) =
704 // sin(A)*(X*i+Y*j+Z*k) since sin(A)/A has limit 1.
705
706 // start off With a Zero quat
707 Quaternion returnvalue = Quaternion.Zero;
708
709 if (Math.Abs(W) < 1)
710 {
711 Scalar angle = MathHelper.Acos(W);
712 Scalar sin = MathHelper.Sin(angle);
713
714 if (Math.Abs(sin) >= MathHelper.Epsilon)
715 {
716 Scalar coeff = angle / sin;
717 returnvalue.X = coeff * X;
718 returnvalue.Y = coeff * Y;
719 returnvalue.Z = coeff * Z;
720 }
721 else
722 {
723 returnvalue.X = X;
724 returnvalue.Y = Y;
725 returnvalue.Z = Z;
726 }
727 }
728
729 return returnvalue;
730 }
731
737 {
738 // If q = A*(X*i+Y*j+Z*k) Where (X,Y,Z) is unit length, then
739 // eXp(q) = cos(A)+sin(A)*(X*i+Y*j+Z*k). If sin(A) is near Zero,
740 // use eXp(q) = cos(A)+A*(X*i+Y*j+Z*k) since A/sin(A) has limit 1.
741
742 Scalar angle = MathHelper.Sqrt(X * X + Y * Y + Z * Z);
743 Scalar sin = MathHelper.Sin(angle);
744
745 // start off With a Zero quat
746 Quaternion returnvalue = Quaternion.Zero;
747
748 returnvalue.W = MathHelper.Cos(angle);
749
750 if (Math.Abs(sin) >= MathHelper.Epsilon)
751 {
752 Scalar coeff = sin / angle;
753
754 returnvalue.X = coeff * X;
755 returnvalue.Y = coeff * Y;
756 returnvalue.Z = coeff * Z;
757 }
758 else
759 {
760 returnvalue.X = X;
761 returnvalue.Y = Y;
762 returnvalue.Z = Z;
763 }
764
765 return returnvalue;
766 }
767
768 #endregion
769 #region Object overloads
770
776 public override string ToString()
777 {
778 return string.Format("Quaternion({0}, {1}, {2}, {3})", this.X, this.Y, this.Z, this.W);
779 }
780 [ParseMethod]
781 public static Quaternion Parse(string text)
782 {
783 string[] vals = text.Replace("Quaternion", "").Trim(' ', '(', '[', '<', ')', ']', '>').Split(',');
784
785 if (vals.Length != 4)
786 {
787 throw new FormatException(string.Format("Cannot parse the text '{0}' because it does not have 4 parts separated by commas in the form (x,y,z,w) with optional parenthesis.", text));
788 }
789 else
790 {
791 try
792 {
793 Quaternion returnvalue;
794 returnvalue.X = Scalar.Parse(vals[0].Trim());
795 returnvalue.Y = Scalar.Parse(vals[1].Trim());
796 returnvalue.Z = Scalar.Parse(vals[2].Trim());
797 returnvalue.W = Scalar.Parse(vals[3].Trim());
798 return returnvalue;
799 }
800 catch (Exception ex)
801 {
802 throw new FormatException("The parts of the vectors must be decimal numbers", ex);
803 }
804 }
805 }
806 public override int GetHashCode()
807 {
808 return (int)X ^ (int)Y ^ (int)Z ^ (int)W;
809 }
810 public override bool Equals(object obj)
811 {
812 return obj is Quaternion && (Quaternion)obj == this;
813 }
814 #endregion
815
816
817 #region operator overloads
818
819 public static Quaternion Multiply(Quaternion left, Quaternion right)
820 {
821 Quaternion result;
822 result.W = left.W * right.W - left.X * right.X - left.Y * right.Y - left.Z * right.Z;
823 result.X = left.W * right.X + left.X * right.W + left.Y * right.Z - left.Z * right.Y;
824 result.Y = left.W * right.Y + left.Y * right.W + left.Z * right.X - left.X * right.Z;
825 result.Z = left.W * right.Z + left.Z * right.W + left.X * right.Y - left.Y * right.X;
826 return result;
827 }
828 public static void Multiply(ref Quaternion left,ref Quaternion right,out Quaternion result)
829 {
830 Scalar W = left.W * right.W - left.X * right.X - left.Y * right.Y - left.Z * right.Z;
831 Scalar X = left.W * right.X + left.X * right.W + left.Y * right.Z - left.Z * right.Y;
832 Scalar Y = left.W * right.Y + left.Y * right.W + left.Z * right.X - left.X * right.Z;
833 result.Z = left.W * right.Z + left.Z * right.W + left.X * right.Y - left.Y * right.X;
834
835 result.W = W;
836 result.X = X;
837 result.Y = Y;
838
839 }
840
841 public static Quaternion Multiply(Quaternion left, Scalar scalar)
842 {
843
844 Quaternion result;
845 result.W = left.W * scalar;
846 result.X = left.X * scalar;
847 result.Y = left.Y * scalar;
848 result.Z = left.Z * scalar;
849 return result;
850 }
851 public static void Multiply(ref Quaternion left,ref Scalar scalar, out Quaternion result)
852 {
853 result.W = left.W * scalar;
854 result.X = left.X * scalar;
855 result.Y = left.Y * scalar;
856 result.Z = left.Z * scalar;
857 }
858
859 public static Quaternion Add(Quaternion left, Quaternion right)
860 {
861 Quaternion result;
862 result.W = left.W + right.W;
863 result.X = left.X + right.X;
864 result.Y = left.Y + right.Y;
865 result.Z = left.Z + right.Z;
866 return result;
867 }
868 public static void Add(ref Quaternion left,ref Quaternion right, out Quaternion result)
869 {
870 result.W = left.W + right.W;
871 result.X = left.X + right.X;
872 result.Y = left.Y + right.Y;
873 result.Z = left.Z + right.Z;
874 }
875
876 public static Quaternion Subtract(Quaternion left, Quaternion right)
877 {
878 Quaternion result;
879 result.W = left.W - right.W;
880 result.X = left.X - right.X;
881 result.Y = left.Y - right.Y;
882 result.Z = left.Z - right.Z;
883 return result;
884 }
885 public static void Subtract(ref Quaternion left,ref Quaternion right, out Quaternion result)
886 {
887 result.W = left.W - right.W;
888 result.X = left.X - right.X;
889 result.Y = left.Y - right.Y;
890 result.Z = left.Z - right.Z;
891 }
892
893 public static Quaternion Negate(Quaternion value)
894 {
895 Quaternion result;
896 result.W = -value.W;
897 result.X = -value.X;
898 result.Y = -value.Y;
899 result.Z = -value.Z;
900 return result;
901 }
902 public static void Negate(ref Quaternion value)
903 {
904 Negate(ref value, out value);
905 }
906 public static void Negate(ref Quaternion value, out Quaternion result)
907 {
908 result.W = -value.W;
909 result.X = -value.X;
910 result.Y = -value.Y;
911 result.Z = -value.Z;
912 }
913
914
915 public static Quaternion operator *(Quaternion left, Quaternion right)
916 {
917 Quaternion result;
918 result.W = left.W * right.W - left.X * right.X - left.Y * right.Y - left.Z * right.Z;
919 result.X = left.W * right.X + left.X * right.W + left.Y * right.Z - left.Z * right.Y;
920 result.Y = left.W * right.Y + left.Y * right.W + left.Z * right.X - left.X * right.Z;
921 result.Z = left.W * right.Z + left.Z * right.W + left.X * right.Y - left.Y * right.X;
922 return result;
923 }
924
925 public static Quaternion operator *(Scalar scalar, Quaternion right)
926 {
927 Quaternion result;
928 result.W = scalar * right.W;
929 result.X = scalar * right.X;
930 result.Y = scalar * right.Y;
931 result.Z = scalar * right.Z;
932 return result;
933 }
934 public static Quaternion operator *(Quaternion left, Scalar scalar)
935 {
936
937 Quaternion result;
938 result.W = left.W * scalar;
939 result.X = left.X * scalar;
940 result.Y = left.Y * scalar;
941 result.Z = left.Z * scalar;
942 return result;
943 }
944
945 public static Quaternion operator +(Quaternion left, Quaternion right)
946 {
947 Quaternion result;
948 result.W = left.W + right.W;
949 result.X = left.X + right.X;
950 result.Y = left.Y + right.Y;
951 result.Z = left.Z + right.Z;
952 return result;
953 }
954
955 public static Quaternion operator -(Quaternion left, Quaternion right)
956 {
957 Quaternion result;
958 result.W = left.W - right.W;
959 result.X = left.X - right.X;
960 result.Y = left.Y - right.Y;
961 result.Z = left.Z - right.Z;
962 return result;
963 }
964
965 public static Quaternion operator -(Quaternion value)
966 {
967 Quaternion result;
968 result.W = -value.W;
969 result.X = -value.X;
970 result.Y = -value.Y;
971 result.Z = -value.Z;
972 return result;
973 }
974
975 public static bool operator ==(Quaternion left, Quaternion right)
976 {
977 return
978 left.W == right.W &&
979 left.X == right.X &&
980 left.Y == right.Y &&
981 left.Z == right.Z;
982 }
983
984 public static bool operator !=(Quaternion left, Quaternion right)
985 {
986 return !(left == right);
987 }
988 #endregion
989 }
990}
System.Single Scalar
Definition: Clamped.cs:29
static Scalar Acos(Scalar d)
Definition: MathHelper.cs:297
static Scalar Cos(Scalar d)
Definition: MathHelper.cs:302
static Scalar Atan2(Scalar y, Scalar x)
Definition: MathHelper.cs:300
const Scalar Epsilon
Definition: MathHelper.cs:50
static Scalar Sin(Scalar a)
Definition: MathHelper.cs:312
static Scalar ToRadians(Scalar degrees)
Converts degrees to radians.
Definition: MathHelper.cs:282
static Scalar InvSqrt(Scalar number)
Definition: MathHelper.cs:223
static Scalar Sqrt(Scalar d)
Definition: MathHelper.cs:314
static Scalar ToDegrees(Scalar radians)
Converts radians to degrees.
Definition: MathHelper.cs:291
const Scalar PiOver2
Definition: MathHelper.cs:43
static Scalar Asin(Scalar d)
Definition: MathHelper.cs:298
A 3x3 matrix which can represent rotations around axes.
Definition: Matrix3x3.cs:62
Summary description for Quaternion.
Definition: Quaternion.cs:82
Quaternion Inverse()
Computes the inverse of a Quaternion.
Definition: Quaternion.cs:568
static Quaternion operator+(Quaternion left, Quaternion right)
Definition: Quaternion.cs:945
Scalar Norm
Squared 'length' of this quaternion.
Definition: Quaternion.cs:229
static void Multiply(ref Quaternion left, ref Scalar scalar, out Quaternion result)
Definition: Quaternion.cs:851
static Quaternion Squad(Scalar t, Quaternion p, Quaternion a, Quaternion b, Quaternion q, bool useShortestPath)
Performs spherical quadratic interpolation.
Definition: Quaternion.cs:174
void ToAxis(out Vector3D XAxis, out Vector3D YAxis, out Vector3D ZAxis)
Definition: Quaternion.cs:589
Scalar Dot(Quaternion quat)
Performs a Dot Product operation on 2 Quaternions.
Definition: Quaternion.cs:482
static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result)
Definition: Quaternion.cs:868
static Quaternion Squad(Scalar t, Quaternion p, Quaternion a, Quaternion b, Quaternion q)
Definition: Quaternion.cs:160
static Quaternion Multiply(Quaternion left, Scalar scalar)
Definition: Quaternion.cs:841
Vector3D ZAxis
Local Z-aXis portion of this rotation.
Definition: Quaternion.cs:294
static Quaternion Multiply(Quaternion left, Quaternion right)
Definition: Quaternion.cs:819
static Quaternion Slerp(Scalar time, Quaternion quatA, Quaternion quatB)
Definition: Quaternion.cs:95
static Quaternion Parse(string text)
Definition: Quaternion.cs:781
static readonly Quaternion Identity
An Identity Quaternion.
Definition: Quaternion.cs:87
void ToEulerAnglesInDegrees(out Scalar pitch, out Scalar Yaw, out Scalar roll)
Definition: Quaternion.cs:395
static Quaternion Add(Quaternion left, Quaternion right)
Definition: Quaternion.cs:859
Quaternion Exp()
Calculates the Exponent of a Quaternion.
Definition: Quaternion.cs:736
static Quaternion FromAngleAxis(Scalar angle, Vector3D aXis)
Creates a Quaternion from a supplied angle and aXis.
Definition: Quaternion.cs:146
static readonly int[] next
Definition: Quaternion.cs:92
static void Negate(ref Quaternion value)
Definition: Quaternion.cs:902
Vector3D ToEulerAnglesInDegrees()
Definition: Quaternion.cs:383
static Quaternion Slerp(Scalar time, Quaternion quatA, Quaternion quatB, bool useShortestPath)
Definition: Quaternion.cs:107
static bool operator==(Quaternion left, Quaternion right)
Definition: Quaternion.cs:975
void ToAngleAxis(ref Scalar angle, ref Vector3D aXis)
Definition: Quaternion.cs:506
Matrix3x3 ToRotationMatrix()
Gets a 3X3 rotation matriX from this Quaternion.
Definition: Quaternion.cs:534
Vector3D YAxis
Local Y-aXis portion of this rotation.
Definition: Quaternion.cs:267
static Quaternion Subtract(Quaternion left, Quaternion right)
Definition: Quaternion.cs:876
override bool Equals(object obj)
Definition: Quaternion.cs:810
override string ToString()
Overrides the Object.ToString() method to provide a teXt representation of a Quaternion.
Definition: Quaternion.cs:776
static Quaternion FromEulerAnglesInDegrees(Scalar pitch, Scalar Yaw, Scalar roll)
Definition: Quaternion.cs:435
static void Negate(ref Quaternion value, out Quaternion result)
Definition: Quaternion.cs:906
override int GetHashCode()
Definition: Quaternion.cs:806
void ToEulerAngles(out Scalar pitch, out Scalar Yaw, out Scalar roll)
Definition: Quaternion.cs:402
static bool operator!=(Quaternion left, Quaternion right)
Definition: Quaternion.cs:984
static Quaternion operator*(Quaternion left, Quaternion right)
Definition: Quaternion.cs:915
static Quaternion FromEulerAngles(Scalar pitch, Scalar Yaw, Scalar roll)
Combines the euler angles in the order Yaw, pitch, roll to create a rotation quaternion
Definition: Quaternion.cs:447
Quaternion Log()
Calculates the logarithm of a Quaternion.
Definition: Quaternion.cs:699
Vector3D ToEulerAngles()
Definition: Quaternion.cs:389
void Normalize()
Normalizes elements of this quaterion to the range [0,1].
Definition: Quaternion.cs:490
static void Subtract(ref Quaternion left, ref Quaternion right, out Quaternion result)
Definition: Quaternion.cs:885
Vector3D XAxis
Local X-aXis portion of this rotation.
Definition: Quaternion.cs:240
static readonly Quaternion Zero
A Quaternion With all elements set to 0;
Definition: Quaternion.cs:91
Quaternion(Scalar W, Scalar X, Scalar Y, Scalar Z)
Creates a new Quaternion.
Definition: Quaternion.cs:213
static Quaternion operator-(Quaternion left, Quaternion right)
Definition: Quaternion.cs:955
static Quaternion Negate(Quaternion value)
Definition: Quaternion.cs:893
static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result)
Definition: Quaternion.cs:828
A Vector with 3 dimensions.
Definition: Vector3D.cs:47
static readonly Vector3D XAxis
Vector3D(1,0,0)
Definition: Vector3D.cs:70
Scalar X
This is the X value.
Definition: Vector3D.cs:692
static readonly Vector3D ZAxis
Vector3D(0,0,1)
Definition: Vector3D.cs:78
static readonly Vector3D YAxis
Vector3D(0,1,0)
Definition: Vector3D.cs:74
Scalar Y
This is the Y value.
Definition: Vector3D.cs:701
Scalar Z
This is the Z value.
Definition: Vector3D.cs:710