{-# LANGUAGE BangPatterns #-} module Geometry.Vector3D where import Geometry.Vector import Geometry.Data import Data.List infixl 6 +.+.+, -.-.- infixl 7 *.*.* {- | 3D coordinate-wise addition. -} (+.+.+) :: Point3 -> Point3 -> Point3 {-# INLINE (+.+.+) #-} V3 x1 y1 z1 +.+.+ V3 x2 y2 z2 = let !x = x1 + x2 !y = y1 + y2 !z = z1 + z2 in V3 x y z {- | 3D coordinate-wise subtraction. -} (-.-.-) :: Point3 -> Point3 -> Point3 {-# INLINE (-.-.-) #-} V3 x1 y1 z1 -.-.- V3 x2 y2 z2 = let !x = x1 - x2 !y = y1 - y2 !z = z1 - z2 in V3 x y z {- | 3D scalar multiplication. -} (*.*.*) :: Float -> Point3 -> Point3 {-# INLINE (*.*.*) #-} a *.*.* (V3 x2 y2 z2) = let !x = a * x2 !y = a * y2 !z = a * z2 in V3 x y z crossProd :: Point3 -> Point3 -> Point3 crossProd (V3 x y z) (V3 a b c) = V3 ( y * c - z * b) ( z * a - x * c) ( x * b - y * a) rotate3 :: Float -> Point3 -> Point3 {-# INLINE rotate3 #-} rotate3 a (V3 x y z) = V3 x' y' z where (V2 x' y') = rotateV a (V2 x y) magV3 :: Point3 -> Float {-# INLINE magV3 #-} magV3 (V3 x y z) = sqrt $ x^i + y^i + z^i where i = 2 :: Int normalizeV3 :: Point3 -> Point3 {-# INLINE normalizeV3 #-} normalizeV3 (V3 0 0 0) = V3 0 0 0 normalizeV3 p = (1 / magV3 p) *.*.* p addZ :: Float -> Point2 -> Point3 {-# INLINE addZ #-} addZ z (V2 x y) = V3 x y z stripZ :: Point3 -> Point2 {-# INLINE stripZ #-} stripZ (V3 x y _) = V2 x y dist3 :: Point3 -> Point3 -> Float {-# INLINE dist3 #-} dist3 !p1 !p2 = magV3 (p2 -.-.- p1) orderAround3 :: Point3 -- ^ Vector to order around -> [Point3] -> [Point3] orderAround3 v ps = sortOn (argV . prj) ps where xdir = crossProd v (head ps) ydir = crossProd v xdir prj p = V2 (dotV3 xdir p) (dotV3 ydir p) vCen3 :: [Point3] -> Point3 vCen3 ps = (1 / fromIntegral (length ps)) *.*.* foldr (+.+.+) (V3 0 0 0) ps dotV3 :: Point3 -> Point3 -> Float dotV3 (V3 x y z) (V3 a b c) = x*a + y*b + z*c projV3 :: Point3 -> Point3 -> Point3 projV3 = undefined