{-# LANGUAGE MagicHash #-} module Data.Geometry.Point where import Data.Geometry.Angle data Point = Point {-# UNPACK #-} !Double {-# UNPACK #-} !Double deriving (Eq, Ord, Read, Show) type Vector = Point instance Num Point where (Point x1 y1) + (Point x2 y2) = Point (x1 + x2) (y1 + y2) (Point x1 y1) * (Point x2 y2) = Point (x1 * x2) (y1 * y2) abs = error "abs not defined for points" signum = error "signum not defined for points" fromInteger = error "fromInteger not defined for points" negate (Point x y) = Point (-x) (-y) vecTo :: Point -> Point -> Vector vecTo p1 p2 = p2 - p1 direction :: Vector -> Double direction (Point x y) = atan2 y x sqrDist :: Point -> Point -> Double sqrDist (Point x1 y1) (Point x2 y2) = (x2 - x1) ** 2 + (y2 - y1) ** 2 sqrMag :: Vector -> Double sqrMag (Point x y) = x * x + y * y cross :: Vector -> Vector -> Double cross (Point x1 y1) (Point x2 y2) = x1 * y2 - y1 * x2 scale :: Double -> Vector -> Vector scale a (Point x y) = Point (a * x) (a * y) rotate :: Vector -> Double -> Vector rotate (Point x y) a = Point (cos a * x - sin a * y) (sin a * x + cos a * y) jitter :: Vector -> [Vector] jitter v = [rotate v (-0.0001), v, rotate v 0.0001] magnitude :: Vector -> Double magnitude = sqrt . sqrMag normalize :: Vector -> Vector normalize vec = (1 / magnitude vec) `scale` vec polarAngle :: Point -> Point -> Angle polarAngle (Point x0 y0) (Point x y) = mkAngle $ atan2 (y - y0) (x - x0)