cga/Algebra/Vector.hs

92 lines
2.0 KiB
Haskell
Raw Normal View History

2014-10-07 17:12:07 +00:00
{-# OPTIONS_HADDOCK ignore-exports #-}
2014-10-10 15:40:08 +00:00
module Algebra.Vector where
2014-10-07 17:12:07 +00:00
2014-10-10 15:40:08 +00:00
import Algebra.VectorTypes
import Diagrams.TwoD.Types
2014-10-07 17:12:07 +00:00
-- |Checks whether the Point is in a given dimension.
inRange :: Coord -- ^ X dimension
-> Coord -- ^ Y dimension
-> PT -- ^ Coordinates
-> Bool -- ^ result
2014-10-09 22:19:05 +00:00
inRange (xlD, xuD) (ylD, yuD) p = x <= xuD && x >= xlD && y <= yuD && y >= ylD
where
(x, y) = unp2 p
2014-10-07 17:12:07 +00:00
2014-10-09 01:15:27 +00:00
-- |Get the angle between two vectors.
getAngle :: Vec -> Vec -> Double
2014-10-09 22:19:05 +00:00
getAngle a b =
acos .
flip (/) (vecLength a * vecLength b) .
scalarProd a $
b
-- |Get the length of a vector.
vecLength :: Vec -> Double
vecLength v = sqrt (x^2 + y^2)
where
(x, y) = unr2 v
-- |Compute the scalar product of two vectors.
scalarProd :: Vec -> Vec -> Double
scalarProd v1 v2 = a1 * b1 + a2 * b2
where
(a1, a2) = unr2 v1
(b1, b2) = unr2 v2
-- |Construct a vector that points to a point from the origin.
pt2Vec :: PT -> Vec
pt2Vec = r2 . unp2
-- |Give the point which is at the coordinates the vector
-- points to from the origin.
vec2Pt :: Vec -> PT
vec2Pt = p2 . unr2
-- |Construct a vector between two points.
vp2 :: PT -- ^ vector origin
-> PT -- ^ vector points here
-> Vec
vp2 a b = (pt2Vec b) - (pt2Vec a)
-- |Computes the determinant of 3 points.
det :: PT -> PT -> PT -> Double
det a b c =
(bx - ax) *
2014-10-09 22:19:05 +00:00
(cy - ay) -
(by - ay) *
(cx - ax)
where
(ax, ay) = unp2 a
(bx, by) = unp2 b
(cx, cy) = unp2 c
-- |Get the orientation of 3 points which can either be
-- * clock-wise
-- * counter-clock-wise
-- * collinear
getOrient :: PT -> PT -> PT -> Alignment
getOrient a b c = case compare (det a b c) 0 of
2014-10-13 00:30:11 +00:00
LT -> CW
GT -> CCW
EQ -> CL
--- |Checks if 3 points a,b,c do not build a clockwise triangle by
--- connecting a-b-c. This is done by computing the determinant and
--- checking the algebraic sign.
notcw :: PT -> PT -> PT -> Bool
notcw a b c = case getOrient a b c of
CW -> False
_ -> True