-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGeometry.hs
More file actions
50 lines (40 loc) · 1.3 KB
/
Geometry.hs
File metadata and controls
50 lines (40 loc) · 1.3 KB
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
module Geometry (
Point,
Vector,
(<.>), (</>),
dirVec,
fixAngle,
rotateVec,
reflectVectorAgainst
) where
import Data.SG (VectorNum(..), dotProduct, Point2', Rel2', makeRel2, unitVector)
type Point = Point2' Double
type Vector = Rel2' Double
-- | Scale vector by the given value
(<.>) :: VectorNum v => v Double -> Double -> v Double
v <.> s = (*s) `fmapNum1` v
-- | Scale vector by the reciprocal of the given value
(</>) :: VectorNum v => v Double -> Double -> v Double
v </> s = (/s) `fmapNum1` v
infixl 7 <.>, </>
-- | Gets direction angle (in radians) and produces a vector pointing in that direction
dirVec :: Double -> Vector
dirVec a = makeRel2 (cos a, sin a)
-- | Rotates the vector by the given angle
-- TODO: use rotateZaxis & multMatrix
rotateVec :: Double -> Vector -> Vector
rotateVec a v = makeRel2 (t `dotProduct` v, tp `dotProduct` v)
where
t = makeRel2 (cos a, -sin a)
tp = makeRel2 (sin a, cos a)
-- | Converts an angle to the equivalent angle in (-pi,pi] range
fixAngle :: Double -> Double
fixAngle a | a <= -pi = fixAngle (a+2*pi)
| a > pi = fixAngle (a-2*pi)
| otherwise = a
reflectVectorAgainst :: Vector -> Vector -> Vector
reflectVectorAgainst a b = c <.> 2 - a
where
au = unitVector a
bu = unitVector b
c = bu <.> (a `dotProduct` bu)