{-# LANGUAGE NamedFieldPuns #-}
module Geometry
( Point(..)
, Line(..)
, Angle(..)
, intersectLineLine
, distanceFromOrigin
, distanceLineFromOrigin
, perpendicularThroughPoint
, angleFromOrigin
, normalizeAngle
, lengthOfRayUntilIntersect
) where
import Data.Fixed (mod')
data Point =
Point Double
Double
data Line = Line
{ slope :: Double
, intercept :: Double
}
newtype Angle =
Radians Double
intersectLineLine :: Line -> Line -> Point
intersectLineLine a b =
let x = (intercept a - intercept b) / (slope b - slope a)
y = slope a * x + intercept a
in Point x y
distanceFromOrigin :: Point -> Double
distanceFromOrigin (Point x y) = sqrt (x * x + y * y)
distanceLineFromOrigin :: Line -> Double
distanceLineFromOrigin Line {slope, intercept} =
abs intercept / sqrt (slope * slope + 1)
perpendicularThroughPoint :: Line -> Point -> Line
perpendicularThroughPoint Line {slope} (Point x y) =
let slope' = -1 / slope
intercept' = y - slope' * x
in Line {slope = slope', intercept = intercept'}
angleFromOrigin :: Point -> Angle
angleFromOrigin (Point x y) = Radians $ atan2 y x
normalizeAngle :: Angle -> Angle
normalizeAngle (Radians theta) = Radians $ mod' theta (2 * pi)
lengthOfRayUntilIntersect :: Angle -> Line -> Double
lengthOfRayUntilIntersect (Radians theta) Line {slope, intercept} =
intercept / (sin theta - slope * cos theta)