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. |