open Point open Vector type t = { xx: float; xy: float; xz: float; xt: float; yx: float; yy: float; yz: float; yt: float; zx: float; zy: float; zz: float; zt: float; } (* let zero = { xx = 0.0; xy = 0.0; xz = 0.0; xt = 0.0; yx = 0.0; yy = 0.0; yz = 0.0; yt = 0.0; zx = 0.0; zy = 0.0; zz = 0.0; zt = 0.0; } *) let id = { xx = 1.0; xy = 0.0; xz = 0.0; xt = 0.0; yx = 0.0; yy = 1.0; yz = 0.0; yt = 0.0; zx = 0.0; zy = 0.0; zz = 1.0; zt = 0.0; } let translate sx sy sz = { xx = 1.0; xy = 0.0; xz = 0.0; xt = sx; yx = 0.0; yy = 1.0; yz = 0.0; yt = sy; zx = 0.0; zy = 0.0; zz = 1.0; zt = sz; } let scale sx sy sz = { xx = sx; xy = 0.0; xz = 0.0; xt = 0.0; yx = 0.0; yy = sy ; yz = 0.0; yt = 0.0; zx = 0.0; zy = 0.0; zz = sz ; zt = 0.0; } let rotatex a = let c = cos a and s = sin a in { xx = 1.0; xy = 0.0; xz = 0.0; xt = 0.0; yx = 0.0; yy = c; yz = -. s; yt = 0.0; zx = 0.0; zy = s; zz = c; zt = 0.0; } let rotatey a = let c = cos a and s = sin a in { xx = c; xy = 0.0; xz = s; xt = 0.0; yx = 0.0; yy = 1.0; yz = 0.0; yt = 0.0; zx = -. s; zy = 0.0; zz = c; zt = 0.0; } let rotatez a = let c = cos a and s = sin a in { xx = c; xy = -. s; xz = 0.0; xt = 0.0; yx = s; yy = c; yz = 0.0; yt = 0.0; zx = 0.0; zy = 0.0; zz = 1.0; zt = 0.0; } let compose m n = { xx = m.xx *. n.xx +. m.xy *. n.yx +. m.xz *. n.zx; xy = m.xx *. n.xy +. m.xy *. n.yy +. m.xz *. n.zy; xz = m.xx *. n.xz +. m.xy *. n.yz +. m.xz *. n.zz; xt = m.xx *. n.xt +. m.xy *. n.yt +. m.xz *. n.zt +. m.xt; yx = m.yx *. n.xx +. m.yy *. n.yx +. m.yz *. n.zx; yy = m.yx *. n.xy +. m.yy *. n.yy +. m.yz *. n.zy; yz = m.yx *. n.xz +. m.yy *. n.yz +. m.yz *. n.zz; yt = m.yx *. n.xt +. m.yy *. n.yt +. m.yz *. n.zt +. m.yt; zx = m.zx *. n.xx +. m.zy *. n.yx +. m.zz *. n.zx; zy = m.zx *. n.xy +. m.zy *. n.yy +. m.zz *. n.zy; zz = m.zx *. n.xz +. m.zy *. n.yz +. m.zz *. n.zz; zt = m.zx *. n.xt +. m.zy *. n.yt +. m.zz *. n.zt +. m.zt; } let apply_to_point m p = { x = m.xx *. p.x +. m.xy *. p.y +. m.xz *. p.z +. m.xt; y = m.yx *. p.x +. m.yy *. p.y +. m.yz *. p.z +. m.yt; z = m.zx *. p.x +. m.zy *. p.y +. m.zz *. p.z +. m.zt } let apply_to_vect m v = { dx = m.xx *. v.dx +. m.xy *. v.dy +. m.xz *. v.dz; dy = m.yx *. v.dx +. m.yy *. v.dy +. m.yz *. v.dz; dz = m.zx *. v.dx +. m.zy *. v.dy +. m.zz *. v.dz } let fudge_id () = if !Misc.fudge_factor = 0.0 then (id, id) else let ff = !Misc.fudge_factor and ff2 = !Misc.fudge_factor /. 2. in let dx = Random.float ff -. ff2 and dy = Random.float ff -. ff2 and dz = Random.float ff -. ff2 and rx = Random.float ff -. ff2 and ry = Random.float ff -. ff2 in compose (rotatex rx) (compose (rotatey ry) (translate dx dy dz)), compose (translate (-. dx) (-. dy) (-. dz)) (compose (rotatey (-. ry)) (rotatex (-. rx))) ;;