Library for vectors
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Most people just use (Int,Int)
or similar for a 2-vector. However, if you find yourself wanting to do lots of vector arithmetic, that becomes annoying quite quickly. Below is what I use; feel free to adapt it to your needs.
module Vector where
type Scalar = Double
class Vector v where
vmap :: (Scalar -> Scalar) -> v -> v
vzip :: (Scalar -> Scalar -> Scalar) -> v -> v -> v
vfold :: (x -> Scalar -> x) -> x -> v -> x
vdot :: Vector v => v -> v -> Scalar
vdot v0 v1 = vfold (+) 0 $ vzip (*) v0 v1
vmag_sqr :: Vector v => v -> Scalar
vmag_sqr v = v `vdot` v
vmag :: Vector v => v -> Scalar
vmag = sqrt . vmag_sqr
vscale :: Vector v => Scalar -> v -> v
vscale s = vmap (s*)
vunit :: Vector v => v -> v
vunit v =
if vmag v == 0
then v
else vscale (1 / vmag v) v
data Vector2 = Vector2 {v2x, v2y :: Scalar} deriving (Eq)
instance Show Vector2 where
show (Vector2 x y) = "<" ++ (show x) ++ ", " ++ (show y) ++ ">"
instance Vector Vector2 where
vmap f (Vector2 x y) = Vector2 (f x) (f y)
vfold f i (Vector2 x y) = (i `f` x) `f` y
vzip f (Vector2 x0 y0) (Vector2 x1 y1) = Vector2 (f x0 x1) (f y0 y1)
instance Num Vector2 where
(+) = vzip (+)
(-) = vzip (-)
(*) = vzip (*)
negate = vmap negate
fromInteger s = Vector2 (fromInteger s) (fromInteger s)
instance Fractional Vector2 where
(/) = vzip (/)
fromDouble s = Vector2 s s
data Vector3 = Vector3 {v3x, v3y, v3z :: Scalar} deriving (Eq)
instance Show Vector3 where
show (Vector3 x y z) = "<" ++ (show x) ++ ", " ++ (show y) ++ ", " ++ (show z) ++ ">"
instance Vector Vector3 where
vmap f (Vector3 x y z) = Vector3 (f x) (f y) (f z)
vfold f i (Vector3 x y z) = ((i `f` x) `f` y) `f` z
vzip f (Vector3 x0 y0 z0) (Vector3 x1 y1 z1) = Vector3 (f x0 x1) (f y0 y1) (f z0 z1)
instance Num Vector3 where
(+) = vzip (+)
(-) = vzip (-)
(*) = vzip (*)
negate = vmap negate
fromInteger s = Vector3 (fromInteger s) (fromInteger s) (fromInteger s)
instance Fractional Vector3 where
(/) = vzip (/)
fromDouble s = Vector3 s s s
v3cross (Vector3 x0 y0 z0) (Vector3 x1 y1 z1) = Vector3 (y0*z1 - y1*z0) (x0*z1 - x1*z0) (x0*y1 - x1*y0)
PS. If anybody knows a way to make every instance of Vector
automatically become an instance of Num
, etc., let me know!