diff options
-rw-r--r-- | Spear/Math/Vector3.hs | 346 |
1 files changed, 173 insertions, 173 deletions
diff --git a/Spear/Math/Vector3.hs b/Spear/Math/Vector3.hs index 79cdcdd..7ac0f7a 100644 --- a/Spear/Math/Vector3.hs +++ b/Spear/Math/Vector3.hs | |||
@@ -1,130 +1,130 @@ | |||
1 | module Spear.Math.Vector3 | 1 | module Spear.Math.Vector3 |
2 | ( | 2 | ( |
3 | Vector3 | 3 | Vector3 |
4 | -- * Accessors | 4 | -- * Accessors |
5 | , x | 5 | , x |
6 | , y | 6 | , y |
7 | , z | 7 | , z |
8 | -- * Construction | 8 | -- * Construction |
9 | , unitx | 9 | , unitx |
10 | , unity | 10 | , unity |
11 | , unitz | 11 | , unitz |
12 | , zero | 12 | , zero |
13 | , fromList | 13 | , fromList |
14 | , vec3 | 14 | , vec3 |
15 | , orbit | 15 | , orbit |
16 | -- * Operations | 16 | -- * Operations |
17 | , Spear.Math.Vector3.min | 17 | , Spear.Math.Vector3.min |
18 | , Spear.Math.Vector3.max | 18 | , Spear.Math.Vector3.max |
19 | , dot | 19 | , dot |
20 | , cross | 20 | , cross |
21 | , normSq | 21 | , normSq |
22 | , norm | 22 | , norm |
23 | , scale | 23 | , scale |
24 | , normalise | 24 | , normalise |
25 | , neg | 25 | , neg |
26 | ) | 26 | ) |
27 | where | 27 | where |
28 | 28 | ||
29 | import Foreign.C.Types (CFloat) | 29 | import Foreign.C.Types (CFloat) |
30 | import Foreign.Storable | 30 | import Foreign.Storable |
31 | 31 | ||
32 | 32 | ||
33 | -- | Represents a vector in 3D. | 33 | -- | Represents a vector in 3D. |
34 | data Vector3 = Vector3 | 34 | data Vector3 = Vector3 |
35 | {-# UNPACK #-} !Float | 35 | {-# UNPACK #-} !Float |
36 | {-# UNPACK #-} !Float | 36 | {-# UNPACK #-} !Float |
37 | {-# UNPACK #-} !Float | 37 | {-# UNPACK #-} !Float |
38 | deriving (Eq, Show) | 38 | deriving (Eq, Show) |
39 | 39 | ||
40 | 40 | ||
41 | instance Num Vector3 where | 41 | instance Num Vector3 where |
42 | Vector3 ax ay az + Vector3 bx by bz = Vector3 (ax + bx) (ay + by) (az + bz) | 42 | Vector3 ax ay az + Vector3 bx by bz = Vector3 (ax + bx) (ay + by) (az + bz) |
43 | Vector3 ax ay az - Vector3 bx by bz = Vector3 (ax - bx) (ay - by) (az - bz) | 43 | Vector3 ax ay az - Vector3 bx by bz = Vector3 (ax - bx) (ay - by) (az - bz) |
44 | Vector3 ax ay az * Vector3 bx by bz = Vector3 (ax * bx) (ay * by) (az * bz) | 44 | Vector3 ax ay az * Vector3 bx by bz = Vector3 (ax * bx) (ay * by) (az * bz) |
45 | abs (Vector3 ax ay az) = Vector3 (abs ax) (abs ay) (abs az) | 45 | abs (Vector3 ax ay az) = Vector3 (abs ax) (abs ay) (abs az) |
46 | signum (Vector3 ax ay az) = Vector3 (signum ax) (signum ay) (signum az) | 46 | signum (Vector3 ax ay az) = Vector3 (signum ax) (signum ay) (signum az) |
47 | fromInteger i = Vector3 i' i' i' where i' = fromInteger i | 47 | fromInteger i = Vector3 i' i' i' where i' = fromInteger i |
48 | 48 | ||
49 | 49 | ||
50 | instance Fractional Vector3 where | 50 | instance Fractional Vector3 where |
51 | Vector3 ax ay az / Vector3 bx by bz = Vector3 (ax / bx) (ay / by) (az / bz) | 51 | Vector3 ax ay az / Vector3 bx by bz = Vector3 (ax / bx) (ay / by) (az / bz) |
52 | fromRational r = Vector3 r' r' r' where r' = fromRational r | 52 | fromRational r = Vector3 r' r' r' where r' = fromRational r |
53 | 53 | ||
54 | 54 | ||
55 | instance Ord Vector3 where | 55 | instance Ord Vector3 where |
56 | Vector3 ax ay az <= Vector3 bx by bz | 56 | Vector3 ax ay az <= Vector3 bx by bz |
57 | = (ax <= bx) | 57 | = (ax <= bx) |
58 | || (az == bx && ay <= by) | 58 | || (az == bx && ay <= by) |
59 | || (ax == bx && ay == by && az <= bz) | 59 | || (ax == bx && ay == by && az <= bz) |
60 | 60 | ||
61 | Vector3 ax ay az >= Vector3 bx by bz | 61 | Vector3 ax ay az >= Vector3 bx by bz |
62 | = (ax >= bx) | 62 | = (ax >= bx) |
63 | || (ax == bx && ay >= by) | 63 | || (ax == bx && ay >= by) |
64 | || (ax == bx && ay == by && az >= bz) | 64 | || (ax == bx && ay == by && az >= bz) |
65 | 65 | ||
66 | Vector3 ax ay az < Vector3 bx by bz | 66 | Vector3 ax ay az < Vector3 bx by bz |
67 | = (ax < bx) | 67 | = (ax < bx) |
68 | || (az == bx && ay < by) | 68 | || (az == bx && ay < by) |
69 | || (ax == bx && ay == by && az < bz) | 69 | || (ax == bx && ay == by && az < bz) |
70 | 70 | ||
71 | Vector3 ax ay az > Vector3 bx by bz | 71 | Vector3 ax ay az > Vector3 bx by bz |
72 | = (ax > bx) | 72 | = (ax > bx) |
73 | || (ax == bx && ay > by) | 73 | || (ax == bx && ay > by) |
74 | || (ax == bx && ay == by && az > bz) | 74 | || (ax == bx && ay == by && az > bz) |
75 | 75 | ||
76 | 76 | ||
77 | sizeFloat = sizeOf (undefined :: CFloat) | 77 | sizeFloat = sizeOf (undefined :: CFloat) |
78 | 78 | ||
79 | 79 | ||
80 | instance Storable Vector3 where | 80 | instance Storable Vector3 where |
81 | sizeOf _ = 3*sizeFloat | 81 | sizeOf _ = 3*sizeFloat |
82 | alignment _ = alignment (undefined :: CFloat) | 82 | alignment _ = alignment (undefined :: CFloat) |
83 | 83 | ||
84 | peek ptr = do | 84 | peek ptr = do |
85 | ax <- peekByteOff ptr 0 | 85 | ax <- peekByteOff ptr 0 |
86 | ay <- peekByteOff ptr $ 1*sizeFloat | 86 | ay <- peekByteOff ptr $ 1*sizeFloat |
87 | az <- peekByteOff ptr $ 2*sizeFloat | 87 | az <- peekByteOff ptr $ 2*sizeFloat |
88 | return (Vector3 ax ay az) | 88 | return (Vector3 ax ay az) |
89 | 89 | ||
90 | poke ptr (Vector3 ax ay az) = do | 90 | poke ptr (Vector3 ax ay az) = do |
91 | pokeByteOff ptr 0 ax | 91 | pokeByteOff ptr 0 ax |
92 | pokeByteOff ptr (1*sizeFloat) ay | 92 | pokeByteOff ptr (1*sizeFloat) ay |
93 | pokeByteOff ptr (2*sizeFloat) az | 93 | pokeByteOff ptr (2*sizeFloat) az |
94 | 94 | ||
95 | 95 | ||
96 | x (Vector3 ax _ _ ) = ax | 96 | x (Vector3 ax _ _ ) = ax |
97 | y (Vector3 _ ay _ ) = ay | 97 | y (Vector3 _ ay _ ) = ay |
98 | z (Vector3 _ _ az) = az | 98 | z (Vector3 _ _ az) = az |
99 | 99 | ||
100 | 100 | ||
101 | -- | Unit vector along the X axis. | 101 | -- | Unit vector along the X axis. |
102 | unitx :: Vector3 | 102 | unitx :: Vector3 |
103 | unitx = Vector3 1 0 0 | 103 | unitx = Vector3 1 0 0 |
104 | 104 | ||
105 | 105 | ||
106 | -- | Unit vector along the Y axis. | 106 | -- | Unit vector along the Y axis. |
107 | unity :: Vector3 | 107 | unity :: Vector3 |
108 | unity = Vector3 0 1 0 | 108 | unity = Vector3 0 1 0 |
109 | 109 | ||
110 | 110 | ||
111 | -- | Unit vector along the Z axis. | 111 | -- | Unit vector along the Z axis. |
112 | unitz :: Vector3 | 112 | unitz :: Vector3 |
113 | unitz = Vector3 0 0 1 | 113 | unitz = Vector3 0 0 1 |
114 | 114 | ||
115 | 115 | ||
116 | -- | Zero vector. | 116 | -- | Zero vector. |
117 | zero :: Vector3 | 117 | zero :: Vector3 |
118 | zero = Vector3 0 0 0 | 118 | zero = Vector3 0 0 0 |
119 | 119 | ||
120 | 120 | ||
121 | -- | Create a vector from the given list. | 121 | -- | Create a vector from the given list. |
122 | fromList :: [Float] -> Vector3 | 122 | fromList :: [Float] -> Vector3 |
123 | fromList (ax:ay:az:_) = Vector3 ax ay az | 123 | fromList (ax:ay:az:_) = Vector3 ax ay az |
124 | 124 | ||
125 | 125 | ||
126 | -- | Create a 3D vector from the given values. | 126 | -- | Create a 3D vector from the given values. |
127 | vec3 :: Float -> Float -> Float -> Vector3 | 127 | vec3 :: Float -> Float -> Float -> Vector3 |
128 | vec3 ax ay az = Vector3 ax ay az | 128 | vec3 ax ay az = Vector3 ax ay az |
129 | 129 | ||
130 | 130 | ||
@@ -146,54 +146,54 @@ orbit center radius anglex angley = | |||
146 | py = y center + radius*sy | 146 | py = y center + radius*sy |
147 | pz = z center + radius*cx*cy | 147 | pz = z center + radius*cx*cy |
148 | in | 148 | in |
149 | vec3 px py pz | 149 | vec3 px py pz |
150 | 150 | ||
151 | 151 | ||
152 | -- | Create a vector with components set to the minimum of each of the given vectors'. | 152 | -- | Create a vector with components set to the minimum of each of the given vectors'. |
153 | min :: Vector3 -> Vector3 -> Vector3 | 153 | min :: Vector3 -> Vector3 -> Vector3 |
154 | min (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) | 154 | min (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) |
155 | 155 | ||
156 | 156 | ||
157 | -- | Create a vector with components set to the maximum of each of the given vectors'. | 157 | -- | Create a vector with components set to the maximum of each of the given vectors'. |
158 | max :: Vector3 -> Vector3 -> Vector3 | 158 | max :: Vector3 -> Vector3 -> Vector3 |
159 | max (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) | 159 | max (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) |
160 | 160 | ||
161 | 161 | ||
162 | -- | Compute the given vectors' dot product. | 162 | -- | Compute the given vectors' dot product. |
163 | dot :: Vector3 -> Vector3 -> Float | 163 | dot :: Vector3 -> Vector3 -> Float |
164 | Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz | 164 | Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz |
165 | 165 | ||
166 | 166 | ||
167 | -- | Compute the given vectors' cross product. | 167 | -- | Compute the given vectors' cross product. |
168 | cross :: Vector3 -> Vector3 -> Vector3 | 168 | cross :: Vector3 -> Vector3 -> Vector3 |
169 | (Vector3 ax ay az) `cross` (Vector3 bx by bz) = | 169 | (Vector3 ax ay az) `cross` (Vector3 bx by bz) = |
170 | Vector3 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) | 170 | Vector3 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) |
171 | 171 | ||
172 | 172 | ||
173 | -- | Compute the given vector's squared norm. | 173 | -- | Compute the given vector's squared norm. |
174 | normSq :: Vector3 -> Float | 174 | normSq :: Vector3 -> Float |
175 | normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az | 175 | normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az |
176 | 176 | ||
177 | 177 | ||
178 | -- | Compute the given vector's norm. | 178 | -- | Compute the given vector's norm. |
179 | norm :: Vector3 -> Float | 179 | norm :: Vector3 -> Float |
180 | norm = sqrt . normSq | 180 | norm = sqrt . normSq |
181 | 181 | ||
182 | 182 | ||
183 | -- | Multiply the given vector with the given scalar. | 183 | -- | Multiply the given vector with the given scalar. |
184 | scale :: Float -> Vector3 -> Vector3 | 184 | scale :: Float -> Vector3 -> Vector3 |
185 | scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) | 185 | scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) |
186 | 186 | ||
187 | 187 | ||
188 | -- | Normalise the given vector. | 188 | -- | Normalise the given vector. |
189 | normalise :: Vector3 -> Vector3 | 189 | normalise :: Vector3 -> Vector3 |
190 | normalise v = | 190 | normalise v = |
191 | let n' = norm v | 191 | let n' = norm v |
192 | n = if n' == 0 then 1 else n' | 192 | n = if n' == 0 then 1 else n' |
193 | in | 193 | in |
194 | scale (1.0 / n) v | 194 | scale (1.0 / n) v |
195 | 195 | ||
196 | 196 | ||
197 | -- | Negate the given vector. | 197 | -- | Negate the given vector. |
198 | neg :: Vector3 -> Vector3 | 198 | neg :: Vector3 -> Vector3 |
199 | neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az) | 199 | neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az) |