{-# LANGUAGE NoImplicitPrelude #-}
module Imj.Geo.Continuous
(
Vec2(..)
, module Imj.Geo.Continuous.Conversion
, translatedFullCircle
, translatedFullCircleFromQuarterArc
, parabola
, polyExtremities
, sumVec2d
, scalarProd
, rotateByQuarters
, Pos, Vel, Acc
) where
import Imj.Prelude
import Imj.Geo.Continuous.Types
import Imj.Geo.Continuous.Conversion
import Imj.Iteration
rotateByQuarters :: Vec2 Pos -> [Vec2 Pos]
rotateByQuarters v@(Vec2 x y) =
[v,
Vec2 x $ -y,
Vec2 (-x) $ -y,
Vec2 (-x) y]
{-# INLINE sumVec2d #-}
sumVec2d :: Vec2 a -> Vec2 a -> Vec2 a
sumVec2d (Vec2 vx vy) (Vec2 wx wy) = Vec2 (vx+wx) (vy+wy)
scalarProd :: Float -> Vec2 a -> Vec2 a
scalarProd f (Vec2 x y) = Vec2 (f*x) (f*y)
{-# INLINE integrateAcceleration2 #-}
integrateAcceleration2 :: Frame -> Vec2 Acc -> Vec2 Pos
integrateAcceleration2 (Frame time) (Vec2 vx vy) =
let factor = 0.5 * fromIntegral (time * time)
in Vec2 (vx * factor) (vy * factor)
{-# INLINE integrateVelocity #-}
integrateVelocity :: Frame -> Vec2 Vel -> Vec2 Pos
integrateVelocity (Frame time) (Vec2 vx vy) =
let factor = fromIntegral time
in Vec2 (vx * factor) (vy * factor)
gravity :: Vec2 Acc
gravity = Vec2 0 0.032
parabola :: Vec2 Pos -> Vec2 Vel -> Frame -> Vec2 Pos
parabola r0 v0 time =
let iv = integrateVelocity time v0
ia = integrateAcceleration2 time gravity
in sumVec2d r0 $ sumVec2d iv ia
mkPointOnCircle :: Float -> Float -> Vec2 Pos
mkPointOnCircle radius angle =
let x = radius * sin angle
y = radius * cos angle
in Vec2 x y
discretizeArcOfCircle :: Float -> Float -> Float -> Int -> [Vec2 Pos]
discretizeArcOfCircle radius arcAngle firstAngle resolution =
let angleIncrement = arcAngle / (fromIntegral resolution :: Float)
in map (\i ->
let angle = firstAngle + angleIncrement * (fromIntegral i :: Float)
in mkPointOnCircle radius angle) [0..resolution]
fullCircleFromQuarterArc :: Float -> Float -> Int -> [Vec2 Pos]
fullCircleFromQuarterArc radius firstAngle quarterArcResolution =
let quarterArcAngle = pi/2
quarterCircle = discretizeArcOfCircle radius quarterArcAngle firstAngle quarterArcResolution
in concatMap rotateByQuarters quarterCircle
fullCircle :: Float -> Float -> Int -> [Vec2 Pos]
fullCircle radius firstAngle resolution =
let totalAngle = 2*pi
in discretizeArcOfCircle radius totalAngle firstAngle resolution
translatedFullCircleFromQuarterArc :: Vec2 Pos
-> Float
-> Float
-> Int
-> [Vec2 Pos]
translatedFullCircleFromQuarterArc center radius firstAngle resolution =
let circle = fullCircleFromQuarterArc radius firstAngle resolution
in map (sumVec2d center) circle
translatedFullCircle :: Vec2 Pos
-> Float
-> Float
-> Int
-> [Vec2 Pos]
translatedFullCircle center radius firstAngle resolution =
let circle = fullCircle radius firstAngle resolution
in map (sumVec2d center) circle
polyExtremities :: Vec2 Pos
-> Float
-> Float
-> Int
-> [Vec2 Pos]
polyExtremities = translatedFullCircle