9 people like it.

XNA's Vector3 with units of measure

A vector type with units of measure built on top of XNA's Vector3. Not complete, the point is mainly to show how to use generic units of measure to adapt an existing type.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
Fake definition of Vector3

/// A three-dimensional vector with a unit of measure. Built on top of Xna's Vector3.
type TypedVector3<[<Measure>] 'M> =
    struct
        val v : Vector3
        new(x : float32<'M>, y : float32<'M>, z : float32<'M>) =
            { v = Vector3(float32 x, float32 y, float32 z) }
        new(V) = { v = V }
    end

[<RequireQualifiedAccessAttribute>]
module TypedVector =
    let add3 (U : TypedVector3<'M>, V : TypedVector3<'M>) =
        new TypedVector3<'M>(U.v + V.v)

    let sub3 (U : TypedVector3<'M>, V : TypedVector3<'M>) =
        new TypedVector3<'M>(U.v - V.v)

    let dot3 (U : TypedVector3<'M>, V : TypedVector3<'N>) =
        Vector3.Dot(U.v, V.v)
        |> LanguagePrimitives.Float32WithMeasure<'M 'N>

    let len3 (U : TypedVector3<'M>) =
        LanguagePrimitives.Float32WithMeasure<'M> (U.v.Length())

    let scale3 (k : float32<'K>, U : TypedVector3<'M>) : TypedVector3<'K 'M> =
        let conv = LanguagePrimitives.Float32WithMeasure<'K 'M>
        let v = Vector3.Multiply(U.v, float32 k)
        new TypedVector3<_>(conv v.X, conv v.Y, conv v.Z)

    let normalize3 (U : TypedVector3<'M>) =
        let len = len3 U
        scale3 ((1.0f / len), U)

type TypedVector3<[<Measure>] 'M>
with
    static member public (*) (k, U) = TypedVector.scale3 (k, U)
    static member public (+) (U, V) = TypedVector.add3 (U, V)
    static member public (-) (U, V) = TypedVector.sub3 (U, V)
    member public this.Length = this |> TypedVector.len3

// Example
[<Measure>] type m
[<Measure>] type s

let speed = new TypedVector3<m/s>(1.0f<_>, 0.0f<_>, 0.0f<_>)
let time = 10.0f<s>
let movement = time * speed
type Vector3 =
    struct
        val X : float32
        val Y : float32
        val Z : float32

        new(x, y, z) = { X = x; Y = y; Z = z }

        static member public (+) (U : Vector3, V : Vector3) : Vector3 = failwith ""
        static member public (-) (U : Vector3, V : Vector3) : Vector3 = failwith ""
        static member public Dot (U : Vector3, V : Vector3) : float32 = failwith ""
        static member public (*) (k : float32, V : Vector3) : Vector3 = failwith ""
        static member public Multiply (V : Vector3, k : float32) : Vector3 = failwith ""
        member public this.Length() : float32 = failwith ""
    end
Multiple items
type TypedVector3<'M> =
  struct
    new : V:Vector3 -> TypedVector3<'M>
    new : x:float32<'M> * y:float32<'M> * z:float32<'M> -> TypedVector3<'M>
    val v: Vector3
    member Length : float32<'M>
    static member ( + ) : U:TypedVector3<'u> * V:TypedVector3<'u> -> TypedVector3<'u>
    static member ( * ) : k:float32<'u> * U:TypedVector3<'v> -> TypedVector3<'u 'v>
    static member ( - ) : U:TypedVector3<'u> * V:TypedVector3<'u> -> TypedVector3<'u>
  end

Full name: Script.TypedVector3<_>


 A three-dimensional vector with a unit of measure. Built on top of Xna's Vector3.


--------------------
TypedVector3()
new : V:Vector3 -> TypedVector3<'M>
new : x:float32<'M> * y:float32<'M> * z:float32<'M> -> TypedVector3<'M>
Multiple items
type MeasureAttribute =
  inherit Attribute
  new : unit -> MeasureAttribute

Full name: Microsoft.FSharp.Core.MeasureAttribute

--------------------
new : unit -> MeasureAttribute
TypedVector3.v: Vector3
Multiple items
type Vector3 =
  struct
    new : x:float32 * y:float32 * z:float32 -> Vector3
    val X: float32
    val Y: float32
    val Z: float32
    member Length : unit -> float32
    static member Dot : U:Vector3 * V:Vector3 -> float32
    static member Multiply : V:Vector3 * k:float32 -> Vector3
    static member ( + ) : U:Vector3 * V:Vector3 -> Vector3
    static member ( * ) : k:float32 * V:Vector3 -> Vector3
    static member ( - ) : U:Vector3 * V:Vector3 -> Vector3
  end

Full name: Script.Vector3

--------------------
Vector3()
new : x:float32 * y:float32 * z:float32 -> Vector3
val x : float32<'M>
Multiple items
val float32 : value:'T -> float32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float32

--------------------
type float32 = System.Single

Full name: Microsoft.FSharp.Core.float32

--------------------
type float32<'Measure> = float32

Full name: Microsoft.FSharp.Core.float32<_>
val y : float32<'M>
val z : float32<'M>
val V : Vector3
Multiple items
type RequireQualifiedAccessAttribute =
  inherit Attribute
  new : unit -> RequireQualifiedAccessAttribute

Full name: Microsoft.FSharp.Core.RequireQualifiedAccessAttribute

--------------------
new : unit -> RequireQualifiedAccessAttribute
val add3 : U:TypedVector3<'M> * V:TypedVector3<'M> -> TypedVector3<'M>

Full name: Script.TypedVector.add3
val U : TypedVector3<'M>
val V : TypedVector3<'M>
val sub3 : U:TypedVector3<'M> * V:TypedVector3<'M> -> TypedVector3<'M>

Full name: Script.TypedVector.sub3
val dot3 : U:TypedVector3<'M> * V:TypedVector3<'N> -> float32<'M 'N>

Full name: Script.TypedVector.dot3
val V : TypedVector3<'N>
static member Vector3.Dot : U:Vector3 * V:Vector3 -> float32
module LanguagePrimitives

from Microsoft.FSharp.Core
val Float32WithMeasure : float32 -> float32<'Measure>

Full name: Microsoft.FSharp.Core.LanguagePrimitives.Float32WithMeasure
val len3 : U:TypedVector3<'M> -> float32<'M>

Full name: Script.TypedVector.len3
member Vector3.Length : unit -> float32
val scale3 : k:float32<'K> * U:TypedVector3<'M> -> TypedVector3<'K 'M>

Full name: Script.TypedVector.scale3
val k : float32<'K>
val conv : (float32 -> float32<'K 'M>)
val v : Vector3
static member Vector3.Multiply : V:Vector3 * k:float32 -> Vector3
Vector3.X: float32
Vector3.Y: float32
Vector3.Z: float32
val normalize3 : U:TypedVector3<'M> -> TypedVector3<1>

Full name: Script.TypedVector.normalize3
val len : float32<'M>
val k : float32<'u>
val U : TypedVector3<'v>
module TypedVector

from Script
val U : TypedVector3<'u>
val V : TypedVector3<'u>
val this : byref<TypedVector3<'M>>
member TypedVector3.Length : float32<'M>

Full name: Script.TypedVector3.Length
[<Measure>]
type m

Full name: Script.m
[<Measure>]
type s

Full name: Script.s
val speed : TypedVector3<m/s>

Full name: Script.speed
val time : float32<s>

Full name: Script.time
val movement : TypedVector3<m>

Full name: Script.movement

More information

Link:http://fssnip.net/9H
Posted:5 years ago
Author:Johann Deneux
Tags: math , xna , units of measure