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

# SCM Repository

[sml3d] View of /src/common/vec3f.sml
 [sml3d] / src / common / vec3f.sml

# View of /src/common/vec3f.sml

Sat Feb 16 22:59:07 2008 UTC (11 years, 11 months ago) by jhr
Original Path: src/math/vec3f.sml
File size: 3788 byte(s)
```  Adding 4D homogeneous vectors
```
```(* vec3f.sml
*
* COPYRIGHT (c) 2006 John Reppy (http://www.cs.uchicago.edu/~jhr)
*
* Operations on vectors in R^3 (float version).
*)

structure Vec3f : sig

type float = FP.float

type vec3f = {x : float, y : float, z : float}
type vec4f = {x : float, y : float, z : float, w : float}

val unpack : vec3f -> (float * float * float)
val pack   : (float * float * float) -> vec3f
val toList : vec3f -> float list

(* functional update *)
val setX : vec3f * float -> vec3f
val setY : vec3f * float -> vec3f
val setZ : vec3f * float -> vec3f

(* lift a 3D vector into homogeneous space *)
val vector : vec3f -> vec4f
val point : vec3f -> vec4f

val nth : vec3f * int -> float

val zero : vec3f

(* standard basis vectors *)
val e1 : vec3f
val e2 : vec3f
val e3 : vec3f

val toString : vec3f -> string

val neg : vec3f -> vec3f
val add : (vec3f * vec3f) -> vec3f
val sub : (vec3f * vec3f) -> vec3f
val mul : (vec3f * vec3f) -> vec3f

val scale : (float * vec3f) -> vec3f

(* adds (u, s, v) = u + s*v *)
val adds : (vec3f * float * vec3f) -> vec3f

(* lerp (u, t, v) = (1-t)*u + t*v; we assume that 0 <= t <= 1 *)
val lerp : (vec3f * float * vec3f) -> vec3f

val dot : (vec3f * vec3f) -> float
val cross : (vec3f * vec3f) -> vec3f
val normalize : vec3f -> vec3f
val length : vec3f -> float
val lengthSq : vec3f -> float		(* length squared *)
val lengthAndDir : vec3f -> (float * vec3f)	(* length and normal vector *)
val distanceSq : (vec3f * vec3f) -> float	(* distance squared *)

(* iterators *)
val map : (float -> 'a) -> vec3f -> {x : 'a, y : 'a, z : 'a}
val app : (float -> unit) -> vec3f -> unit

(* rays *)
type rayf = {orig : vec3f, dir : vec3f}

val rayToPoint : (rayf * float) -> vec3f

end  = struct

structure Math = Real32.Math

type float = FP.float

val epsilon : float = 1.0e~5

type vec3f = float Vec3.vec3
type vec4f = float Vec4.vec4

open Vec3

(* lift a 3D vector into homogeneous space *)
fun vector {x, y, z} : vec4f = {x=x, y=y, z=z, w=0.0}
fun point {x, y, z} : vec4f = {x=x, y=y, z=z, w=1.0}

val zero : vec3f = {x=0.0, y = 0.0, z = 0.0}

val e1 : vec3f = {x = 1.0, y = 0.0, z = 0.0}
val e2 : vec3f = {x = 0.0, y = 1.0, z = 0.0}
val e3 : vec3f = {x = 0.0, y = 0.0, z = 1.0}

fun toString ({x, y, z} : vec3f) = concat[
"<", Real32.toString x, ",", Real32.toString y, ",", Real32.toString z, ">"
]

fun neg ({x, y, z} : vec3f) = {x = ~x, y = ~y, z = ~z}

fun add ({x=x1, y=y1, z=z1} : vec3f, {x=x2, y=y2, z=z2}) =
{x=x1+x2, y=y1+y2, z=z1+z2}

fun sub ({x=x1, y=y1, z=z1} : vec3f, {x=x2, y=y2, z=z2}) =
{x=x1-x2, y=y1-y2, z=z1-z2}

fun mul ({x=x1, y=y1, z=z1} : vec3f, {x=x2, y=y2, z=z2}) =
{x=x1*x2, y=y1*y2, z=z1*z2}

fun scale (s, {x, y, z} : vec3f) = {x = s*x, y = s*y, z = s*z}

fun lerp (v1, t, v2) = add(scale(1.0-t, v1), scale(t, v2))

fun dot ({x=x1, y=y1, z=z1} : vec3f, {x=x2, y=y2, z=z2}) =
(x1*x2 + y1*y2 +z1*z2)

fun cross ({x=x1, y=y1, z=z1} : vec3f, {x=x2, y=y2, z=z2}) = {
x = y1*z2 - z1*y2,
y = z1*x2 - x1*z2,
z = x1*y1 - y1*x2
}

fun lengthSq (v : vec3f) = dot(v, v)

fun length v = Math.sqrt(lengthSq v)

fun distanceSq (u : vec3f, v) = lengthSq (sub (u, v))

fun lengthAndDir (v as {x, y, z}) = let
val l = length v
in
if (l < epsilon)
then (l, v)
else (l, scale(1.0 / l, v))
end

fun normalize v = #2(lengthAndDir v)

(* rays *)
type rayf = {orig : vec3f, dir : vec3f}

fun rayToPoint ({orig, dir}, s) = adds(orig, s, dir)

end
```