Browse Source

Quaternion: minor tweaks, opt-out unclear functions from SemVer with Obsolete attribute

Some of the functions of the Quaternion module have not been finalized
yet. In order to unblock a release, these functions are now marked with
the Obsolete attribute with a warning that they opt-out from semantic
versioning. They may change in breaking ways between minor versions.
netstandard
Christoph Ruegg 11 years ago
parent
commit
b1cfcb5f85
  1. 58
      src/FSharp/Quaternion.fs

58
src/FSharp/Quaternion.fs

@ -39,32 +39,31 @@ type Quaternion =
} with
static member (+) (r: Quaternion, q: Quaternion) =
{w=r.w+q.w;x=r.x+q.x;y=r.y+q.y;z=r.z+q.z}
{ w=r.w+q.w; x=r.x+q.x; y=r.y+q.y; z=r.z+q.z }
static member (-) (r: Quaternion, q: Quaternion) =
{w=r.w-q.w;x=r.x-q.x;y=r.y-q.y;z=r.z-q.z}
{ w=r.w-q.w; x=r.x-q.x; y=r.y-q.y; z=r.z-q.z }
static member (*) (r: Quaternion, q: Quaternion) =
let w = r.w*q.w - r.x*q.x - r.y*q.y - r.z*q.z
let x = r.w*q.x + r.x*q.w - r.y*q.z + r.z*q.y
let y = r.w*q.y + r.x*q.z + r.y*q.w - r.z*q.x
let z = r.w*q.z - r.x*q.y + r.y*q.x + r.z*q.w
{w=w;x=x;y=y;z=z}
{ w=w; x=x; y=y; z=z }
static member (/) (r: Quaternion, q: Quaternion) =
let d = (r.w**2.0 + r.x**2.0 + r.y**2.0 + r.z**2.0)
let w = (r.w*q.w + r.x*q.x + r.y*q.y + r.z*q.z) / d
let x = (r.w*q.x - r.x*q.w - r.y*q.z + r.z*q.y) / d
let y = (r.w*q.y + r.x*q.z - r.y*q.w - r.z*q.x) / d
let z = (r.w*q.z - r.x*q.y + r.y*q.x - r.z*q.w) / d
{w=w;x=x;y=y;z=z}
{ w=w; x=x; y=y; z=z }
static member (/) (q:Quaternion, a) =
{w=q.w/a; x=q.x/a;y=q.y/a;z=q.z/a}
{ w=q.w/a; x=q.x/a; y=q.y/a; z=q.z/a }
[<RequireQualifiedAccess; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Quaternion =
//Reference:
@ -74,21 +73,27 @@ module Quaternion =
//https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#The_conjugation_operation
let normSquared q =
q.w**2.0 + q.x**2.0 + q.y**2.0 + q.z**2.0
q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z
/// Euclidean Norm
let norm q =
normSquared q |> sqrt
/// Normalize a quaternion to unit quaternion with norm 1.
let normalize q =
let invNorm = 1.0 / (norm q)
{w=q.w*invNorm;x=q.x*invNorm;y=q.y*invNorm;z=q.z*invNorm}
{ w=q.w*invNorm; x=q.x*invNorm; y=q.y*invNorm; z=q.z*invNorm }
let conjugate q =
{w=q.w; x= -q.x; y= -q.y; z= -q.z}
{ w=q.w; x= -q.x; y= -q.y; z= -q.z }
let inverse q =
conjugate q / normSquared q
/// Dot product
let dot q1 q2 =
q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z*q2.z
//create a new quaternion
//angle in radians
//http://www.astro.rug.nl/software/kapteyn/_downloads/attitude.pdf
@ -96,28 +101,26 @@ module Quaternion =
// _ _
// qa (α, n) := | cos α/2 |
// | n sin α/2 |
// - -
//
[<System.Obsolete("Semantic Version Opt-Out: this routine has not been finalized yet and may change in breaking ways within minor versions.")>]
let create (angle:float) (x:float) (y:float) (z:float) =
//axis needs to be unit vector
let vNorm = x**2.0+y**2.0+z**2.0
let invNorm = 1.0 / (vNorm |> sqrt)
let vNorm = x*x + y*y + z*z
let invNorm = 1.0 / (sqrt vNorm)
let x' = x*invNorm
let y' = y*invNorm
let z' = z*invNorm
let halfAngle = angle * 0.5
let s = halfAngle |> sin
let c = halfAngle |> cos
{w=c; x=x'*s; y=y'*s; z=z'*s}
//dot product
let dot q1 q2 =
q1.w*q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z
//rotate a vector(x,y,z) by a quaternion
// p is a pure quaternion(i.e w=0.0)
// p' = qpq**-1.0
// https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#The_conjugation_operation
let s = sin halfAngle
let c = cos halfAngle
{ w=c; x=x'*s; y=y'*s; z=z'*s }
/// rotate a vector(x,y,z) by a quaternion
/// p is a pure quaternion(i.e w=0.0)
/// p' = qpq**-1.0
/// https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#The_conjugation_operation
[<System.Obsolete("Semantic Version Opt-Out: this routine has not been finalized yet and may change in breaking ways within minor versions.")>]
let rotate q1 x y z =
let q = normalize q1 //ensure unit quaternion
let p = {w=0.0; x=x; y=y; z=z}
@ -129,4 +132,7 @@ module Quaternion =
/// <param name="value1">The first Quaternion rotation in the series.</param>
/// <param name="value2">The second Quaternion rotation in the series.</param>
/// <returns>A new Quaternion representing the concatenation of the value1 rotation followed by the value2 rotation.</returns>
let concat (q:Quaternion) (q':Quaternion) = q' * q //concat rotation is actually q' * q instead of q * q'.
[<System.Obsolete("Semantic Version Opt-Out: this routine has not been finalized yet and may change in breaking ways within minor versions.")>]
let concat (q:Quaternion) (q':Quaternion) =
//concat rotation is q' * q instead of q * q'.
q' * q

Loading…
Cancel
Save