1+ -- ANCHOR: module_picture
12module Data.Picture where
23
34import Prelude
4-
55import Data.Foldable (foldl )
6+ -- ANCHOR_END: module_picture
7+ -- ANCHOR: picture_import_as
68import Global as Global
79import Math as Math
10+ -- ANCHOR_END: picture_import_as
811
9- data Point = Point
12+ -- ANCHOR: Point
13+ type Point =
1014 { x :: Number
1115 , y :: Number
1216 }
17+ -- ANCHOR_END: Point
1318
14- getX :: Point -> Number
15- getX (Point p) = p.x
16-
17- getY :: Point -> Number
18- getY (Point p) = p.y
19-
19+ -- ANCHOR: showPoint
2020showPoint :: Point -> String
21- showPoint ( Point { x, y }) =
21+ showPoint { x, y } =
2222 " (" <> show x <> " , " <> show y <> " )"
23+ -- ANCHOR_END: showPoint
2324
25+ -- ANCHOR: Shape
2426data Shape
2527 = Circle Point Number
2628 | Rectangle Point Number Number
2729 | Line Point Point
2830 | Text Point String
31+ -- ANCHOR_END: Shape
2932
33+ -- ANCHOR: showShape
3034showShape :: Shape -> String
3135showShape (Circle c r) =
3236 " Circle [center: " <> showPoint c <> " , radius: " <> show r <> " ]"
@@ -36,115 +40,132 @@ showShape (Line start end) =
3640 " Line [start: " <> showPoint start <> " , end: " <> showPoint end <> " ]"
3741showShape (Text loc text) =
3842 " Text [location: " <> showPoint loc <> " , text: " <> show text <> " ]"
43+ -- ANCHOR_END: showShape
44+
45+ -- ANCHOR: exampleLine
46+ exampleLine :: Shape
47+ exampleLine = Line p1 p2
48+ where
49+ p1 :: Point
50+ p1 = { x: 0.0 , y: 0.0 }
51+
52+ p2 :: Point
53+ p2 = { x: 100.0 , y: 50.0 }
54+ -- ANCHOR_END: exampleLine
3955
56+ -- ANCHOR: origin
4057origin :: Point
41- origin = Point { x: 0.0 , y: 0.0 }
58+ origin = { x, y }
59+ where
60+ x = 0.0
61+ y = 0.0
62+ -- ANCHOR_END: origin
63+ -- Would generally write it like this instead:
64+ -- origin = { x: 0.0, y: 0.0 }
4265
4366getCenter :: Shape -> Point
4467getCenter (Circle c r) = c
4568getCenter (Rectangle c w h) = c
46- getCenter (Line ( Point s) ( Point e)) = Point { x: (s.x + e.x) / 2.0 , y: (s.y + e.y) / 2.0 }
69+ getCenter (Line s e) = (s + e) * {x: 0.5 , y: 0.5 }
4770getCenter (Text loc text) = loc
4871
72+ -- ANCHOR: Picture
4973type Picture = Array Shape
74+ -- ANCHOR_END: Picture
5075
76+ -- ANCHOR: showPicture
5177showPicture :: Picture -> Array String
5278showPicture = map showShape
79+ -- ANCHOR_END: showPicture
5380
54- data Bounds = Bounds
81+ -- ANCHOR: Bounds
82+ type Bounds =
5583 { top :: Number
5684 , left :: Number
5785 , bottom :: Number
5886 , right :: Number
5987 }
88+ -- ANCHOR_END: Bounds
6089
6190showBounds :: Bounds -> String
62- showBounds ( Bounds b) =
91+ showBounds b =
6392 " Bounds [top: " <> show b.top <>
6493 " , left: " <> show b.left <>
6594 " , bottom: " <> show b.bottom <>
6695 " , right: " <> show b.right <>
6796 " ]"
6897
6998shapeBounds :: Shape -> Bounds
70- shapeBounds (Circle ( Point { x, y }) r) = Bounds
99+ shapeBounds (Circle { x, y } r) =
71100 { top: y - r
72101 , left: x - r
73102 , bottom: y + r
74103 , right: x + r
75104 }
76- shapeBounds (Rectangle ( Point { x, y }) w h) = Bounds
105+ shapeBounds (Rectangle { x, y } w h) =
77106 { top: y - h / 2.0
78107 , left: x - w / 2.0
79108 , bottom: y + h / 2.0
80109 , right: x + w / 2.0
81110 }
82- shapeBounds (Line ( Point p1) ( Point p2)) = Bounds
111+ shapeBounds (Line p1 p2) =
83112 { top: Math .min p1.y p2.y
84113 , left: Math .min p1.x p2.x
85114 , bottom: Math .max p1.y p2.y
86115 , right: Math .max p1.x p2.x
87116 }
88- shapeBounds (Text ( Point { x, y }) _) = Bounds
117+ shapeBounds (Text { x, y } _) =
89118 { top: y
90119 , left: x
91120 , bottom: y
92121 , right: x
93122 }
94123
95124union :: Bounds -> Bounds -> Bounds
96- union ( Bounds b1) ( Bounds b2) = Bounds
125+ union b1 b2 =
97126 { top: Math .min b1.top b2.top
98127 , left: Math .min b1.left b2.left
99128 , bottom: Math .max b1.bottom b2.bottom
100129 , right: Math .max b1.right b2.right
101130 }
102131
103132intersect :: Bounds -> Bounds -> Bounds
104- intersect ( Bounds b1) ( Bounds b2) = Bounds
133+ intersect b1 b2 =
105134 { top: Math .max b1.top b2.top
106135 , left: Math .max b1.left b2.left
107136 , bottom: Math .min b1.bottom b2.bottom
108137 , right: Math .min b1.right b2.right
109138 }
110139
111140emptyBounds :: Bounds
112- emptyBounds = Bounds
141+ emptyBounds =
113142 { top: Global .infinity
114143 , left: Global .infinity
115144 , bottom: -Global .infinity
116145 , right: -Global .infinity
117146 }
118147
119148infiniteBounds :: Bounds
120- infiniteBounds = Bounds
149+ infiniteBounds =
121150 { top: -Global .infinity
122151 , left: -Global .infinity
123152 , bottom: Global .infinity
124153 , right: Global .infinity
125154 }
126155
156+ -- ANCHOR: bounds
127157bounds :: Picture -> Bounds
128158bounds = foldl combine emptyBounds
129159 where
130160 combine :: Bounds -> Shape -> Bounds
131161 combine b shape = union (shapeBounds shape) b
162+ -- ANCHOR_END: bounds
132163
133164{-
134165These `instance`s are to enable testing.
135166Feel free to ignore these.
136167They'll make more sense in the next chapter.
137168-}
138- derive instance boundsEq :: Eq Bounds
139-
140- instance boundsShow :: Show Bounds where
141- show b = showBounds b
142-
143- derive instance pointEq :: Eq Point
144-
145- instance pointShow :: Show Point where
146- show p = showPoint p
147-
148169derive instance shapeEq :: Eq Shape
149170
150171instance shapeShow :: Show Shape where
0 commit comments