Created
January 2, 2019 11:25
-
-
Save DonaldKellett/5c43e69ffe9f2414c4eda70f91fe2f6b to your computer and use it in GitHub Desktop.
PureScript by Example - 5.17 Computing Bounding Rectangles - Exercise 1-2 Solutions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module PictureExtended where | |
-- Based on and extended from the project setup of 5. Pattern Matching | |
-- of PureScript by Example: | |
-- https://github.com/paf31/purescript-book/blob/master/exercises/chapter5/src/Data/Picture.purs | |
import Prelude | |
import Data.Foldable (foldl) | |
import Global as Global | |
import Math as Math | |
data Point = Point | |
{ x :: Number | |
, y :: Number | |
} | |
showPoint :: Point -> String | |
showPoint (Point { x, y }) = | |
"(" <> show x <> ", " <> show y <> ")" | |
data Shape | |
= Circle Point Number | |
| Rectangle Point Number Number | |
| Line Point Point | |
| Text Point String | |
| Clipped Picture -- Exercise 2 addition | |
showShape :: Shape -> String | |
showShape (Circle c r) = | |
"Circle [center: " <> showPoint c <> ", radius: " <> show r <> "]" | |
showShape (Rectangle c w h) = | |
"Rectangle [center: " <> showPoint c <> ", width: " <> show w <> ", height: " <> show h <> "]" | |
showShape (Line start end) = | |
"Line [start: " <> showPoint start <> ", end: " <> showPoint end <> "]" | |
showShape (Text loc text) = | |
"Text [location: " <> showPoint loc <> ", text: " <> show text <> "]" | |
-- Exercise 2 addition | |
showShape (Clipped picture) = | |
"Clipped [picture: " <> show (map showShape picture) <> "]" | |
type Picture = Array Shape | |
showPicture :: Picture -> Array String | |
showPicture = map showShape | |
data Bounds = Bounds | |
{ top :: Number | |
, left :: Number | |
, bottom :: Number | |
, right :: Number | |
} | |
showBounds :: Bounds -> String | |
showBounds (Bounds b) = | |
"Bounds [top: " <> show b.top <> | |
", left: " <> show b.left <> | |
", bottom: " <> show b.bottom <> | |
", right: " <> show b.right <> | |
"]" | |
shapeBounds :: Shape -> Bounds | |
shapeBounds (Circle (Point { x, y }) r) = Bounds | |
{ top: y - r | |
, left: x - r | |
, bottom: y + r | |
, right: x + r | |
} | |
shapeBounds (Rectangle (Point { x, y }) w h) = Bounds | |
{ top: y - h / 2.0 | |
, left: x - w / 2.0 | |
, bottom: y + h / 2.0 | |
, right: x + w / 2.0 | |
} | |
shapeBounds (Line (Point p1) (Point p2)) = Bounds | |
{ top: Math.min p1.y p2.y | |
, left: Math.min p1.x p2.x | |
, bottom: Math.max p1.y p2.y | |
, right: Math.max p1.x p2.x | |
} | |
shapeBounds (Text (Point { x, y }) _) = Bounds | |
{ top: y | |
, left: x | |
, bottom: y | |
, right: x | |
} | |
-- Exercise 2 addition | |
shapeBounds (Clipped picture) = bounds picture | |
union :: Bounds -> Bounds -> Bounds | |
union (Bounds b1) (Bounds b2) = Bounds | |
{ top: Math.min b1.top b2.top | |
, left: Math.min b1.left b2.left | |
, bottom: Math.max b1.bottom b2.bottom | |
, right: Math.max b1.right b2.right | |
} | |
intersect :: Bounds -> Bounds -> Bounds | |
intersect (Bounds b1) (Bounds b2) = Bounds | |
{ top: Math.max b1.top b2.top | |
, left: Math.max b1.left b2.left | |
, bottom: Math.min b1.bottom b2.bottom | |
, right: Math.min b1.right b2.right | |
} | |
emptyBounds :: Bounds | |
emptyBounds = Bounds | |
{ top: Global.infinity | |
, left: Global.infinity | |
, bottom: -Global.infinity | |
, right: -Global.infinity | |
} | |
infiniteBounds :: Bounds | |
infiniteBounds = Bounds | |
{ top: -Global.infinity | |
, left: -Global.infinity | |
, bottom: Global.infinity | |
, right: Global.infinity | |
} | |
bounds :: Picture -> Bounds | |
bounds = foldl combine emptyBounds | |
where | |
combine :: Bounds -> Shape -> Bounds | |
combine b shape = union (shapeBounds shape) b | |
-- Exercise 1 | |
area :: Shape -> Number | |
area (Circle _ r) = Math.pi * r * r | |
area (Rectangle _ l w) = l * w | |
area (Line _ _) = 0.0 | |
area (Text _ _) = 0.0 | |
-- Exercise 2 addition | |
area (Clipped picture) = case bounds picture of | |
(Bounds b) -> (b.bottom - b.top) * (b.right - b.left) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment