Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
 Summary Activity SCM

# SCM Repository

[sml3d] View of /src/common/float-onb.sml
 [sml3d] / src / common / float-onb.sml

# View of /src/common/float-onb.sml

Mon Apr 7 13:35:25 2008 UTC (11 years, 8 months ago) by jhr
File size: 2911 byte(s)
```  Various bug fixes / feature enhancements.
```
```(* onb-sig.sml
*
* COPYRIGHT (c) 2008 John Reppy (http://www.cs.uchicago.edu/~jhr)
*
* Ortho-normal basis and frames.
*
* NOTE: this code doesn't do any error checking; it probably should!
*)

structure FloatONB : ONB =
struct

structure V3 = Vec3f

type flt = SML3dTypes.float
type vec3 = flt SML3dTypes.vec3

type onb = {u : vec3, v : vec3, w : vec3}

type frame = {origin : vec3, onb : onb}

(* the standard ONB *)
val xyz : onb = {u = V3.e1, v = V3.e2, w = V3.e3}

fun fromU u = let
val u = V3.normalize u
val (vLen, v) = V3.lengthAndDir (V3.cross(u, V3.e1))
val v = if (vLen < 0.01) then V3.cross(u, V3.e2) else v
val w = V3.cross(u, v)
in
{u = u, v = v, w = w}
end

fun fromV v = let
val v = V3.normalize v
val (uLen, u) = V3.lengthAndDir (V3.cross(v, V3.e1))
val u = if (uLen < 0.01) then V3.cross(v, V3.e2) else u
val w = V3.cross(u, v)
in
{u = u, v = v, w = w}
end

fun fromW w = let
val w = V3.normalize w
val (uLen, u) = V3.lengthAndDir (V3.cross(w, V3.e1))
val u = if (uLen < 0.01) then V3.cross(w, V3.e2) else u
val v = V3.cross(w, u)
in
{u = u, v = v, w = w}
end

(* construct an ONB where u is parallel to a, v lies in the ab plane
* and w is parallel to a cross b.
*)
fun fromUV (a, b) = let
val u = V3.normalize a
val w = V3.normalize(V3.cross(a, b))
val v = V3.cross(w, u)
in
{u = u, v = v, w = w}
end

(* construct an ONB where v is parallel to a, u lies in the ab plane
* and w is parallel to b cross a.
*)
fun fromVU (a, b) = let
val v = V3.normalize a
val w = V3.normalize(V3.cross(b, a))
val u = V3.cross(v, w)
in
{u = u, v = v, w = w}
end

fun fromUW (a, b) = let
val u = V3.normalize a
val v = V3.normalize (V3.cross (b, a))
val w = V3.cross (u, v)
in
{u = u, v = v, w = w}
end

fun fromWU (a, b) = let
val w = V3.normalize a
val v = V3.normalize (V3.cross(a, b))
val u = V3.cross(v, w)
in
{u = u, v = v, w = w}
end

fun fromVW (a, b) = let
val v = V3.normalize a
val u = V3.normalize (V3.cross(a, b))
val w = V3.cross(u, v)
in
{u = u, v = v, w = w}
end

fun fromWV (a, b) = let
val w = V3.normalize a
val u = V3.normalize (V3.cross(b, a))
val v = V3.cross(w, u)
in
{u = u, v = v, w = w}
end

(* transform a world vector to the ONB *)
fun toONB {u, v, w} a = {x = V3.dot(a, u), y = V3.dot(a, v), z = V3.dot(a, w)}

(* transform a vector from the ONB to the world coordinates *)
fun fromONB {u, v, w} {x, y, z} =