|
Once we have our equal-area lots determined, we could ideally just stick each picnic blanket right in the middle of the lot. However, even though most lots will be square-ish in shape, given that the original shapes can have walkways and stuff, we'll want to make sure that a lot with a walkway in it doesn't have the center in a walkway. Here's the code that finds a smarter center and draws a dot in it: |
let findLotCenter :: [Polygon] -> Point
findLotCenter p = let (l,t,r,b) = boundingRect p
m@(x,y) = ((r+l)/2,(b+t)/2)
(lh,rh) = sliceX x p
(th,bh) = sliceY y $ lh ++ rh
centerOrder p1 p2 = compare (distance p1 m) (distance p2 m)
in minimumBy (comparing $ distance m) $ concat $ th ++ bh
let makeDot :: Point -> Polygon
makeDot (x,y) = [(x-2,y-2),(x+2,y-2),(x+2,y+2),(x-2,y+2)]
let centers = map findLotCenter lots
let spots = blue $ map makeDot centers
writeFile "tut5.svg" $ writePolygons $ (green park) ++ spots
|
Here's what tut5.svg looks like: |
|
The trick in the findLotCenter is to use our old sliceX and sliceY functions to make one more "plus-sign" cut and then pick the central-most vertex from the resulting triangles. |