{-# 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 (+.+.+) #-} (+.+.+) = (+) --(x1, y1, z1) +.+.+ (x2, y2, z2) = -- let -- !x = x1 + x2 -- !y = y1 + y2 -- !z = z1 + z2 -- in (x, y, z) {- | 3D coordinate-wise subtraction. -} (-.-.-) :: Point3 -> Point3 -> Point3 {-# INLINE (-.-.-) #-} (-.-.-) = (-) --(x1, y1, z1) -.-.- (x2, y2, z2) = -- let -- !x = x1 - x2 -- !y = y1 - y2 -- !z = z1 - z2 -- in (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 magV3 (V3 x y z) = sqrt $ x^i + y^i + z^i where i = 2 :: Int normalizeV3 :: Point3 -> Point3 normalizeV3 (V3 0 0 0) = V3 0 0 0 normalizeV3 p = (1 / magV3 p) *.*.* p addZ :: Float -> Point2 -> Point3 addZ z (V2 x y) = V3 x y z 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