oscpacking 0.2.1.1 → 0.3.0.0
raw patch · 9 files changed
+225/−173 lines, 9 filesdep ~basedep ~glossdep ~random
Dependency ranges changed: base, gloss, random
Files
- Graphics/OscPacking.hs +8/−0
- Graphics/OscPacking/Boundary.hs +24/−20
- Graphics/OscPacking/Examples.hs +82/−52
- Graphics/OscPacking/Geometry.hs +9/−17
- Graphics/OscPacking/Interpret.hs +20/−25
- Graphics/OscPacking/Packing.hs +33/−25
- Graphics/OscPacking/Paint.hs +35/−30
- changelog.md +8/−0
- oscpacking.cabal +6/−4
Graphics/OscPacking.hs view
@@ -1,3 +1,11 @@+{-|+Module : Graphics.OscPacking.OscPacking+Description : Re-exports the library functions+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com+-}+ module Graphics.OscPacking ( module Graphics.OscPacking.Boundary , module Graphics.OscPacking.Paint
Graphics/OscPacking/Boundary.hs view
@@ -1,32 +1,36 @@-{---This file is part of the OscPacking library.-Copyright 2016 Christopher Howard.-- OscPacking is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- OscPacking is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with OscPacking. If not, see <http://www.gnu.org/licenses/>.---}-+{-|+Module : Graphics.OscPacking.Boundary+Description : Functions for bounding circle coverage+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com+-} module Graphics.OscPacking.Boundary where import Graphics.OscPacking.Geometry+import Prelude ((/), (+), (/), (-), (>), ($), foldr, min, Maybe(..), (<), or, Float) +-- |A 'Boundary' is a function which takes a 'Point' and determines if+-- it is inside some area. If the Point is outside the area, it+-- returns 'Nothing'. Otherwise, it returns the distance to the edge+-- of the area. Any such 'Boundary' need not be a simple, traditional+-- geometric shape. Though, it is often difficult to calculate the+-- distance for more exotic shapes. type Boundary = Point -> Maybe Float -circleB :: Point -> Float -> Boundary+-- |Provides a 'Boundary' for a circle of given origin and radius.+circleB+ :: Point -- ^ origin+ -> Float -- ^ radius+ -> Boundary circleB originP r testP = if d > r then Nothing else Just (r - d) where d = euclidean originP testP -rectB :: Point -> Float -> Float -> Boundary+-- |Provides a 'Boundary' for a rectangle of given origin and dimensions+rectB :: Point -- ^ coordinate of the bottom left corner+ -> Float -- ^ width+ -> Float -- ^ height+ -> Boundary rectB (bLX, bLY) width height (tPX, tPY) = if or [tPX < bLX, tPX > bLX + width,
Graphics/OscPacking/Examples.hs view
@@ -1,59 +1,89 @@-{---This file is part of the OscPacking library.-Copyright 2016 Christopher Howard.-- OscPacking is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- OscPacking is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.+{-|+Module : Graphics.OscPacking.Examples+Description : Examples to study+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com - You should have received a copy of the GNU General Public License- along with OscPacking. If not, see <http://www.gnu.org/licenses/>.---}+Please be aware that breaking changes to example functions will not be+represented as such for purposes of package versioning. Do not link to+example functions from production code.+-} module Graphics.OscPacking.Examples where -import Graphics.Gloss.Interface.Pure.Display+import Graphics.Gloss.Data.Color (black) import Graphics.OscPacking--displayExample1 :: IO()-displayExample1 = displayWindow (800, 600) black $- buildPicture (cycling 0.05 200)- defaultPacking { boxWidth = 800.0,- boxHeight = 600.0,- seedX = 42,- seedY = 11,- boundary = Just (rectB (20, 20) 760 560),- startingCircles = [Graphics.OscPacking.Circle- { position = (400, 300), radius = 10 }]- }- 1000+import Prelude ((/), ($), Maybe(..), putStrLn, IO) -displayExample2 :: IO()-displayExample2 = displayWindow (600, 600) black $- buildPicture (colorful 270)- defaultPacking { boxWidth = 600.0,- boxHeight = 600.0,- seedX = 331,- seedY = 2010,- boundary = Just (circleB (600.0 / 2, 600.0 / 2) 250),- startingCircles = [Graphics.OscPacking.Circle- { position = (300, 300), radius = 10 }]- }- 1000+-- |Packs a rectangle with circles.+--+-- @+-- example1 :: IO()+-- example1 =+-- do putStrLn \"Packing. Please be patient.\"+-- displayWindow (800, 600) black $+-- buildPicture interpretation packing totalcircles+-- where packing = defaultPacking { boxWidth = 800.0,+-- boxHeight = 600.0,+-- seedX = 42,+-- seedY = 11,+-- boundary = Just (rectB (20, 20) 760 560),+-- startingCircles =+-- [Graphics.OscPacking.Circle+-- { position = (400, 300), radius = 10 }] }+-- totalcircles = 1500+-- interpretation = cycling 0.05 200+-- @+example1 :: IO()+example1 =+ do putStrLn "Packing. Please be patient."+ displayWindow (800, 600) black $+ buildPicture interpretation packing totalcircles+ where packing = defaultPacking { boxWidth = 800.0,+ boxHeight = 600.0,+ seedX = 42,+ seedY = 11,+ boundary = Just (rectB (20, 20) 760 560),+ startingCircles =+ [Graphics.OscPacking.Circle+ { position = (400, 300), radius = 10 }] }+ totalcircles = 1500+ interpretation = cycling 0.05 200 -growExample1 :: IO()-growExample1 = growWindow (600, 600) black (colorful 55) 8- defaultPacking { boxWidth = 600.0,- boxHeight = 600.0,- seedX = 58387,- seedY = 943,- boundary = Just (circleB (600.0 / 2, 600.0 / 2) 250),- startingCircles = [Graphics.OscPacking.Circle- { position = (300, 300), radius = 10 }]- }+-- |Packs a circle with circles.+--+-- @+-- example2 :: IO()+-- example2 =+-- do putStrLn \"Packing. Please be patient.\"+-- displayWindow (800, 600) black $+-- buildPicture interpretation packing totalcircles+-- where packing = defaultPacking { boxWidth = 600.0,+-- boxHeight = 600.0,+-- seedX = 331,+-- seedY = 2010,+-- boundary = Just (circleB+-- (600.0 \/ 2, 600.0 \/ 2) 250),+-- startingCircles =+-- [Graphics.OscPacking.Circle+-- { position = (300, 300), radius = 10 }] }+-- totalcircles = 1500+-- interpretation = colorful 270+-- @+example2 :: IO()+example2 =+ do putStrLn "Packing. Please be patient."+ displayWindow (800, 600) black $+ buildPicture interpretation packing totalcircles+ where packing = defaultPacking { boxWidth = 600.0,+ boxHeight = 600.0,+ seedX = 331,+ seedY = 2010,+ boundary = Just (circleB+ (600.0 / 2, 600.0 / 2) 250),+ startingCircles =+ [Graphics.OscPacking.Circle+ { position = (300, 300), radius = 10 }] }+ totalcircles = 1500+ interpretation = colorful 270
Graphics/OscPacking/Geometry.hs view
@@ -1,22 +1,14 @@-{---This file is part of the OscPacking library.-Copyright 2016 Christopher Howard.-- OscPacking is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- OscPacking is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with OscPacking. If not, see <http://www.gnu.org/licenses/>.---}+{-|+Module : Graphics.OscPacking.Geometry+Description : Geometry helper functions and data types+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com+-} module Graphics.OscPacking.Geometry where++import Prelude ((-), (**), (+), sqrt, Float) data Circle = Circle { position :: Point,
Graphics/OscPacking/Interpret.hs view
@@ -1,43 +1,39 @@-{---This file is part of the OscPacking library.-Copyright 2016 Christopher Howard.-- OscPacking is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- OscPacking is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with OscPacking. If not, see <http://www.gnu.org/licenses/>.---}+{-|+Module : Graphics.OscPacking.Interpret+Description : Interpreting circles as colorful pictures+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com+-} module Graphics.OscPacking.Interpret where +import Prelude ((*), floor, mod, fromInteger, (+), snd, fst, map, (.), Float, pi, (**)) import Graphics.OscPacking.Geometry-import Graphics.Gloss.Data.Picture hiding (Circle, Point)+import Graphics.Gloss.Data.Picture (Picture(Translate, Pictures, Color)) import qualified Graphics.Gloss.Data.Picture as P (Picture(Circle))-import Graphics.Gloss.Data.Color-import Data.Colour.RGBSpace-import Data.Colour.RGBSpace.HSL+import Graphics.Gloss.Data.Color (white, makeColor)+import Data.Colour.RGBSpace (channelBlue, channelRed, channelGreen)+import Data.Colour.RGBSpace.HSL (hsl)+import Graphics.Gloss.Data.Color (Color) type Interpretation = [Circle] -> Picture +-- |All circles are white monoWhite :: Interpretation monoWhite = (Pictures . map mF) where mF (Circle { radius = r, position = p }) = Translate (fst p) (snd p) (Color white (P.Circle r)) --- hue :: Int -> Color+-- |Takes a hue value (/H/SL) and returns a Gloss 'Color'+hue :: Float -> Graphics.Gloss.Data.Color.Color hue degrees = let rgb = hsl degrees 1 0.7 (red, green, blue) = (channelRed rgb, channelGreen rgb, channelBlue rgb) in makeColor red green blue 1.0 +-- |Provides a multi-colored interpretation which tends to scale+-- smoothly across the hues as the radius grows colorful :: Float -> Interpretation colorful offset = (Pictures . map mF) where mF (Circle { radius = r, position = p }) =@@ -46,6 +42,8 @@ (fromInteger (mod (floor ((r + offset)**2)) 360))) (P.Circle r)) +-- |Provides a multi-colored interpretation which gives a seemingly+-- random show of the hues cycling :: Float -> Float -> Interpretation cycling speed offset = (Pictures . map mF) where mF (Circle { radius = r, position = p }) =@@ -53,6 +51,3 @@ (Color (Graphics.OscPacking.Interpret.hue (offset + (fromInteger (mod (floor ((2*pi*r) * speed)) 360)))) (P.Circle r))---
Graphics/OscPacking/Packing.hs view
@@ -1,20 +1,10 @@-{---This file is part of the OscPacking library.-Copyright 2016 Christopher Howard.-- OscPacking is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- OscPacking is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with OscPacking. If not, see <http://www.gnu.org/licenses/>.---}+{-|+Module : Graphics.OscPacking.Packing+Description : Core packing functionality+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com+-} module Graphics.OscPacking.Packing ( Packing(..),@@ -22,12 +12,20 @@ pack ) where +import Prelude (tail, head, (++), Maybe (..), zip, Int, Float, min, (/), (<=), foldr, fmap) import Graphics.OscPacking.Geometry-import System.Random+import System.Random (mkStdGen, randomRs) import Graphics.OscPacking.Boundary -fit :: Maybe Float -> Point -> [Circle] -> Maybe Boundary -> Maybe Circle-fit cap point srtCircles boundary = fmap+-- |Attempt to create a new Circle at specified Point. If the Point is+-- inside an existing circle, or does not fit a specified Boundary,+-- return Nothing+fit :: Maybe Float -- ^ An optional maximum radius for new circles+ -> Point -- ^ The point where we will attempt to place the circle+ -> [Circle] -- ^ the circles into which we are attempting to fit the new circle+ -> Maybe Boundary -- ^ An optional 'Boundary' for circle placement+ -> Maybe Circle+fit cap point srtCircles bound = fmap (\distance -> Circle { position = point, radius = distance }) (foldr chooseCloser (Just (1/0)) srtCircles) where chooseCloser _ Nothing = Nothing@@ -38,12 +36,14 @@ else let upperlim = case cap of Nothing -> 1 / 0 Just cap' -> cap' in- case boundary of+ case bound of Nothing -> Just (min upperlim (min d minval))- Just boundary' -> case boundary' point of+ Just bound' -> case bound' point of Nothing -> Nothing Just bDist -> Just (min bDist (min upperlim (min d minval))) +-- |The initializing parameters for a particular packing image, minus+-- the actual display parameters such as color. data Packing = Packing { boxWidth :: Float, boxHeight :: Float,@@ -54,6 +54,7 @@ seedY :: Int } +-- |Some sensible default parameters provided for convenience. defaultPacking :: Packing defaultPacking = Packing { boxWidth = 800.0,@@ -65,13 +66,20 @@ seedY = 2 } -rndPoints :: Float -> Float -> Int -> Int -> [Point]++-- |Generates an infinite list of random points within some area.+rndPoints :: Float -- ^ width+ -> Float -- ^ height+ -> Int -- ^ seed value of x-value generator+ -> Int -- ^ seed value of y-value generator+ -> [Point] rndPoints width height xseed yseed = zip xvals yvals where (xgen, ygen) = (mkStdGen xseed, mkStdGen yseed) (xvals, yvals) = (randomRs (0, width) xgen, randomRs (0, height) ygen) --- Provides /infinite/ list of Circles-pack :: Packing -> [Circle]+-- |Generates an infinite list of circles, using a packing algorithm+pack :: Packing -- ^ initialization parameters+ -> [Circle] pack pkg = (startingCircles pkg) ++ build (startingCircles pkg) points where points = rndPoints (boxWidth pkg) (boxHeight pkg) (seedX pkg) (seedY pkg)
Graphics/OscPacking/Paint.hs view
@@ -1,47 +1,52 @@-{---This file is part of the OscPacking library.-Copyright 2016 Christopher Howard.-- OscPacking is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- OscPacking is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with OscPacking. If not, see <http://www.gnu.org/licenses/>.---}+{-|+Module : Graphics.OscPacking.Paint+Description : Displaying packings on the screen+Copyright : (c) Christopher Howard, 2016+License : GPL-3+Maintainer : ch.howard@zoho.com+-} module Graphics.OscPacking.Paint where +import Prelude (Int, IO, take, (/), (*)) import Graphics.OscPacking.Packing import Graphics.OscPacking.Interpret-import Graphics.Gloss+import Graphics.Gloss (Picture, display, Display (InWindow, FullScreen), Color, translate) -buildPicture :: Interpretation -> Packing -> Int -> Picture+-- |Generating a packing from Packing parameters and convert into a Picture+buildPicture :: Interpretation -- ^ graphical interpretation method+ -> Packing -- ^ initialization parameters+ -> Int -- ^ maximum number of circles to build+ -> Picture buildPicture intp pkg maxcircles = translate ((-1) * boxWidth pkg / 2) ((-1) * boxHeight pkg / 2) (intp (take maxcircles (pack pkg))) -displayWindow :: (Int, Int) -> Color -> Picture -> IO ()+-- |Display a picture in a window on-screen+displayWindow :: (Int, Int) -- ^ width and height of window+ -> Color -- ^ background color+ -> Picture -- ^ the Picture to display+ -> IO () displayWindow (width, height) bg pic = display (InWindow "KC" (width, height) (0, 0)) bg pic -displayFullscreen :: (Int, Int) -> Color -> Picture -> IO ()+-- |Display a picture in full-screen mode+displayFullscreen :: (Int, Int) -- ^ width and height of actual display area+ -> Color -- ^ background color+ -> Picture -- ^ the Picture to display+ -> IO () displayFullscreen (width, height) bg pic = display (FullScreen (width, height)) bg pic -growWindow :: (Int, Int) -> Color -> Interpretation -> Int -> Packing -> IO ()-growWindow (width, height) bg intp stepsPerSec pkg =- simulate (InWindow "KC" (width, height) (0, 0)) bg stepsPerSec- ([head circles], tail circles) toPic step- where circles = pack pkg- toPic (usedCircles, _) = translate ((-1) * boxWidth pkg / 2)- ((-1) * boxHeight pkg / 2)- (intp usedCircles)- step _ _ (usedCircles, remCircles) = (head remCircles : usedCircles, tail remCircles)+-- Removed because, at late processing stages, does not all for+-- processing keyboard input often enough:+-- growWindow :: (Int, Int) -> Color -> Interpretation -> Int -> Packing -> IO ()+-- growWindow (width, height) bg intp stepsPerSec pkg =+-- simulate (InWindow "KC" (width, height) (0, 0)) bg stepsPerSec+-- ([head circles], tail circles) toPic step+-- where circles = pack pkg+-- toPic (usedCircles, _) = translate ((-1) * boxWidth pkg / 2)+-- ((-1) * boxHeight pkg / 2)+-- (intp usedCircles)+-- step _ _ (usedCircles, remCircles) = (head remCircles : usedCircles, tail remCircles)
+ changelog.md view
@@ -0,0 +1,8 @@+# Changelog for [`oscpacking` package](http://hackage.haskell.org/package/oscpacking)++## 0.3.0.0 *Aug 2016*++ * Breaking removal of `growWindow` from `Graphics.OscPacking.Paint`+ * Modifies examples+ * Code documentation and other cleanup +
oscpacking.cabal view
@@ -2,12 +2,11 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: oscpacking-version: 0.2.1.1+version: 0.3.0.0 synopsis: Implements an osculatory packing (kissing circles) algorithm and display. description: Implements the simple algorithm for packing an area with circles that are- 'mutually tangent'. Also provides functions for displaying as a picture or- an animation.+ 'mutually tangent' as well as functions for displaying the image on-screen. license: GPL-3 license-file: LICENSE author: Christopher Howard@@ -15,7 +14,10 @@ -- copyright: category: Graphics build-type: Simple+ -- extra-source-files: +extra-source-files: changelog.md+ cabal-version: >=1.10 library@@ -28,6 +30,6 @@ Graphics.OscPacking.Boundary -- other-modules: -- other-extensions: - build-depends: base >=4.6 && <4.8, gloss >=1.7 && <1.8, colour >=2.3 && <2.4, random >=1.0 && <1.1+ build-depends: base >=4.6 && <4.10, gloss >=1.7 && <1.11, colour >=2.3 && <2.4, random >=1.0 && <1.2 -- hs-source-dirs: default-language: Haskell2010