File: Vector.hs

package info (click to toggle)
haskell-gloss 1.13.2.2-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 344 kB
  • sloc: haskell: 2,903; makefile: 2
file content (88 lines) | stat: -rw-r--r-- 1,999 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{-# OPTIONS -fno-warn-missing-methods #-}
{-# LANGUAGE TypeSynonymInstances #-}

-- | Geometric functions concerning vectors.
module Graphics.Gloss.Data.Vector
        ( Vector
        , magV
        , argV
        , dotV
        , detV
        , mulSV
        , rotateV
        , angleVV
        , normalizeV
        , unitVectorAtAngle )
where
import Graphics.Gloss.Data.Picture
import Graphics.Gloss.Geometry.Angle


-- | The magnitude of a vector.
magV :: Vector -> Float
magV (x, y)
        = sqrt (x * x + y * y)
{-# INLINE magV #-}


-- | The angle of this vector, relative to the +ve x-axis.
argV :: Vector -> Float
argV (x, y)
        = normalizeAngle $ atan2 y x
{-# INLINE argV #-}


-- | The dot product of two vectors.
dotV :: Vector -> Vector -> Float
dotV (x1, x2) (y1, y2)
        = x1 * y1 + x2 * y2
{-# INLINE dotV #-}


-- | The determinant of two vectors.
detV :: Vector -> Vector -> Float
detV (x1, y1) (x2, y2)
        = x1 * y2 - y1 * x2
{-# INLINE detV #-}


-- | Multiply a vector by a scalar.
mulSV :: Float -> Vector -> Vector
mulSV s (x, y)
        = (s * x, s * y)
{-# INLINE mulSV #-}


-- | Rotate a vector by an angle (in radians). +ve angle is counter-clockwise.
rotateV :: Float -> Vector -> Vector
rotateV r (x, y)
 =      (  x * cos r - y * sin r
        ,  x * sin r + y * cos r)
{-# INLINE rotateV #-}


-- | Compute the inner angle (in radians) between two vectors.
angleVV :: Vector -> Vector -> Float
angleVV p1 p2
 = let  m1      = magV p1
        m2      = magV p2
        d       = p1 `dotV` p2
        aDiff   = acos $ d / (m1 * m2)

   in   aDiff
{-# INLINE angleVV #-}


-- | Normalise a vector, so it has a magnitude of 1.
normalizeV :: Vector -> Vector
normalizeV v    = mulSV (1 / magV v) v
{-# INLINE normalizeV #-}


-- | Produce a unit vector at a given angle relative to the +ve x-axis.
--      The provided angle is in radians.
unitVectorAtAngle :: Float -> Vector
unitVectorAtAngle r
        = (cos r, sin r)
{-# INLINE unitVectorAtAngle #-}