brillo-examples-1.13.3: picture/Visibility/World.hs
module World (
Segment,
World (..),
initialWorld,
normaliseWorld,
)
where
import Brillo (Point)
import Data.Vector.Unboxed qualified as V
import Geometry.Randomish (randomishPoints)
import Geometry.Segment (Segment, splitSegmentsOnY, translateSegment)
-- We keep this unpacked so we can use unboxed vector.
-- index, x1, y1, x2, y2
newtype World = World {worldSegments :: V.Vector Segment}
-- | Generate the initial world.
initialWorld :: IO World
initialWorld = do
let
n = 100
minZ = -300
maxZ = 300
minDelta = -100
maxDelta = 100
centers = randomishPoints 1234 n minZ maxZ
deltas = randomishPoints 4321 n minDelta maxDelta
makePoint n' (cX, cY) (dX, dY) =
(n', (cX, cY), (cX + dX, cY + dY))
segs = V.zipWith3 makePoint (V.enumFromTo 0 (n - 1)) centers deltas
return $ World segs
{-| Normalise the world so that the given point is at the origin,
and split segements that cross the y=0 line.
-}
normaliseWorld :: Point -> World -> World
normaliseWorld (px, py) world = do
let
segments_trans =
V.map (translateSegment (-px) (-py)) $
worldSegments world
segments_split =
splitSegmentsOnY 0 segments_trans
world{worldSegments = segments_split}