module Geometry.Shapes (
haskellLogo
, regularPolygon
, spiralPolygon
) where
import Geometry.Core
haskellLogo :: [Polygon]
haskellLogo :: [Polygon]
haskellLogo = [Polygon] -> [Polygon]
rescaleNormalizePolygons [Polygon]
haskellLogoRaw
rescaleNormalizePolygons :: [Polygon] -> [Polygon]
rescaleNormalizePolygons :: [Polygon] -> [Polygon]
rescaleNormalizePolygons [Polygon]
polygons =
let BoundingBox (Vec2 Double
minX Double
minY) (Vec2 Double
_maxX Double
maxY) = [Polygon] -> BoundingBox
forall a. HasBoundingBox a => a -> BoundingBox
boundingBox [Polygon]
polygons
scaleFactor :: Double
scaleFactor = Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
maxY Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
minY)
transformation :: Transformation
transformation = Double -> Transformation
scale Double
scaleFactor Transformation -> Transformation -> Transformation
forall a. Semigroup a => a -> a -> a
<> Vec2 -> Transformation
translate (Double -> Double -> Vec2
Vec2 (- Double
minX) (- Double
minY))
in Transformation -> [Polygon] -> [Polygon]
forall geo. Transform geo => Transformation -> geo -> geo
transform Transformation
transformation [Polygon]
polygons
haskellLogoRaw :: [Polygon]
haskellLogoRaw :: [Polygon]
haskellLogoRaw = [Polygon
left, Polygon
lambda, Polygon
upper, Polygon
lower]
where
left :: Polygon
left = [Vec2] -> Polygon
Polygon [Double -> Double -> Vec2
Vec2 Double
0 Double
340.15625, Double -> Double -> Vec2
Vec2 Double
113.386719 Double
170.078125, Double -> Double -> Vec2
Vec2 Double
0 Double
0, Double -> Double -> Vec2
Vec2 Double
85.039062 Double
0, Double -> Double -> Vec2
Vec2 Double
198.425781 Double
170.078125, Double -> Double -> Vec2
Vec2 Double
85.039062 Double
340.15625]
lambda :: Polygon
lambda = [Vec2] -> Polygon
Polygon [Double -> Double -> Vec2
Vec2 Double
113.386719 Double
340.15625, Double -> Double -> Vec2
Vec2 Double
226.773438 Double
170.078125, Double -> Double -> Vec2
Vec2 Double
113.386719 Double
0, Double -> Double -> Vec2
Vec2 Double
198.425781 Double
0, Double -> Double -> Vec2
Vec2 Double
425.195312 Double
340.15625, Double -> Double -> Vec2
Vec2 Double
340.15625 Double
340.15625, Double -> Double -> Vec2
Vec2 Double
269.292969 Double
233.859375, Double -> Double -> Vec2
Vec2 Double
198.425781 Double
340.15625]
upper :: Polygon
upper = [Vec2] -> Polygon
Polygon [Double -> Double -> Vec2
Vec2 Double
330.710938 Double
155.90625, Double -> Double -> Vec2
Vec2 Double
292.914062 Double
99.214844, Double -> Double -> Vec2
Vec2 Double
481.890625 Double
99.210938, Double -> Double -> Vec2
Vec2 Double
481.890625 Double
155.90625]
lower :: Polygon
lower = [Vec2] -> Polygon
Polygon [Double -> Double -> Vec2
Vec2 Double
387.402344 Double
240.945312, Double -> Double -> Vec2
Vec2 Double
349.609375 Double
184.253906, Double -> Double -> Vec2
Vec2 Double
481.890625 Double
184.25, Double -> Double -> Vec2
Vec2 Double
481.890625 Double
240.945312]
spiralPolygon
:: Int
-> Double
-> Polygon
spiralPolygon :: Int -> Double -> Polygon
spiralPolygon Int
n Double
width = [Vec2] -> Polygon
Polygon ([Vec2] -> [Vec2]
forall a. [a] -> [a]
reverse ((Vec2 -> Vec2 -> Vec2) -> Vec2 -> [Vec2] -> [Vec2]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Vec2 -> Vec2 -> Vec2
forall v. VectorSpace v => v -> v -> v
(+.) (Double -> Double -> Vec2
Vec2 Double
0 Double
0) [Vec2]
relativeSpiral))
where
instructions :: [(Int, Vec2 -> Vec2)]
instructions = [[(Int, Vec2 -> Vec2)]] -> [(Int, Vec2 -> Vec2)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Int] -> [Vec2 -> Vec2] -> [(Int, Vec2 -> Vec2)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..Int
n] ((Vec2 -> Vec2) -> [Vec2 -> Vec2]
forall a. a -> [a]
repeat Vec2 -> Vec2
turnLeft)
, [(Int
1, Vec2 -> Vec2
turnLeft)]
, [(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1, Vec2 -> Vec2
turnRight)]
, [Int] -> [Vec2 -> Vec2] -> [(Int, Vec2 -> Vec2)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
3, Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
4 .. Int
1] ((Vec2 -> Vec2) -> [Vec2 -> Vec2]
forall a. a -> [a]
repeat Vec2 -> Vec2
turnRight)
]
relativeSpiral :: [Vec2]
relativeSpiral = [(Int, Vec2 -> Vec2)] -> Vec2 -> [Vec2]
forall {t} {a}.
(VectorSpace t, Integral a) =>
[(a, t -> t)] -> t -> [t]
go [(Int, Vec2 -> Vec2)]
instructions (Double -> Double -> Vec2
Vec2 Double
1 Double
0)
where
go :: [(a, t -> t)] -> t -> [t]
go [] t
_dir = []
go ((a
len, t -> t
makeCorner) : [(a, t -> t)]
rest) t
dir = Double
widthDouble -> Double -> Double
forall a. Num a => a -> a -> a
*a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
len Double -> t -> t
forall v. VectorSpace v => Double -> v -> v
*. t
dir t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [(a, t -> t)] -> t -> [t]
go [(a, t -> t)]
rest (t -> t
makeCorner t
dir)
turnLeft :: Vec2 -> Vec2
turnLeft (Vec2 Double
x Double
y) = Double -> Double -> Vec2
Vec2 Double
y (-Double
x)
turnRight :: Vec2 -> Vec2
turnRight (Vec2 Double
x Double
y) = Double -> Double -> Vec2
Vec2 (-Double
y) Double
x
regularPolygon :: Int -> Polygon
regularPolygon :: Int -> Polygon
regularPolygon Int
n =
let angleStepSize :: Double
angleStepSize = Double
360Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
in [Vec2] -> Polygon
Polygon [Angle -> Double -> Vec2
polar (Double -> Angle
deg Double
angle) Double
1 | Double
angle <- (Double -> Bool) -> [Double] -> [Double]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<Double
360) ((Double -> Double) -> Double -> [Double]
forall a. (a -> a) -> a -> [a]
iterate (Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
angleStepSize) Double
0)]