{-# LANGUAGE FlexibleContexts #-}
module Diagrams.TwoD.Layout.CirclePacking
( renderCirclePacking
, createCirclePacking
, RadiusFunction
, approxRadius
, circleRadius ) where
import Optimisation.CirclePacking
import Diagrams.Core.Envelope
import Diagrams.Prelude
import Diagrams.TwoD.Vector (e)
renderCirclePacking :: (Monoid' m, Floating (N b), Ord (N b)) => RadiusFunction b m -> [QDiagram b V2 (N b) m] -> QDiagram b V2 (N b) m
renderCirclePacking :: forall m b.
(Monoid' m, Floating (N b), Ord (N b)) =>
RadiusFunction b m
-> [QDiagram b V2 (N b) m] -> QDiagram b V2 (N b) m
renderCirclePacking RadiusFunction b m
radiusFunc = forall m b a.
(Monoid' m, Ord (N b), Floating (N b)) =>
(a -> Double)
-> (a -> QDiagram b V2 (N b) m) -> [a] -> QDiagram b V2 (N b) m
createCirclePacking RadiusFunction b m
radiusFunc forall a. a -> a
id
toFractional :: (Real a, Fractional b) => a -> b
toFractional :: forall a b. (Real a, Fractional b) => a -> b
toFractional = forall a. Fractional a => Rational -> a
fromRational forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Real a => a -> Rational
toRational
createCirclePacking :: (Monoid' m, Ord (N b), Floating (N b)) => (a -> Double) -> (a -> QDiagram b V2 (N b) m) -> [a] -> QDiagram b V2 (N b) m
createCirclePacking :: forall m b a.
(Monoid' m, Ord (N b), Floating (N b)) =>
(a -> Double)
-> (a -> QDiagram b V2 (N b) m) -> [a] -> QDiagram b V2 (N b) m
createCirclePacking a -> Double
radiusFunc a -> QDiagram b V2 (N b) m
diagramFunc =
forall (v :: * -> *) n a.
(InSpace v n a, HasOrigin a, Monoid' a) =>
[(Point v n, a)] -> a
position forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall a b. (a -> b) -> [a] -> [b]
map (\(a
o,(Double
x,Double
y)) -> (forall n. (n, n) -> P2 n
p2 (forall a b. (Real a, Fractional b) => a -> b
toFractional Double
x, forall a b. (Real a, Fractional b) => a -> b
toFractional Double
y), a -> QDiagram b V2 (N b) m
diagramFunc a
o)) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall a. (a -> Double) -> [a] -> [(a, (Double, Double))]
packCircles a -> Double
radiusFunc
type RadiusFunction b m = QDiagram b V2 (N b) m -> Double
approxRadius :: (Monoid' m, Floating (N b), Real (N b), Ord (N b)) => Int -> RadiusFunction b m
approxRadius :: forall m b.
(Monoid' m, Floating (N b), Real (N b), Ord (N b)) =>
Int -> RadiusFunction b m
approxRadius Int
n =
if Int
n forall a. Ord a => a -> a -> Bool
< Int
3
then forall a. HasCallStack => [Char] -> a
error [Char]
"circleRadius: n needs to be at least 3"
else \QDiagram b V2 (N b) m
o -> Double
outByIn forall a. Num a => a -> a -> a
* forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [ forall a b. (Real a, Fractional b) => a -> b
toFractional (forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
envelopeS (forall n. Floating n => Angle n -> V2 n
e Angle (N (QDiagram b V2 (N b) m))
alpha) QDiagram b V2 (N b) m
o)
| Int
i <- [Int
1..Int
n]
, let alpha :: Angle (N (QDiagram b V2 (N b) m))
alpha = (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i forall a. Num a => a -> a -> a
+ N (QDiagram b V2 (N b) m)
0.5) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
turn
]
where
outByIn :: Double
outByIn = forall a. Floating a => a -> a
Prelude.tan (forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ (Double
2 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)) forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
sin (forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ (Double
2 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n))
circleRadius :: (Monoid' m, Floating (N b), Real (N b)) => RadiusFunction b m
circleRadius :: forall m b.
(Monoid' m, Floating (N b), Real (N b)) =>
RadiusFunction b m
circleRadius QDiagram b V2 (N b) m
o = forall a b. (Real a, Fractional b) => a -> b
toFractional forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [ forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
envelopeS (forall n. Floating n => Angle n -> V2 n
e (N (QDiagram b V2 (N b) m)
alpha forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
turn)) QDiagram b V2 (N b) m
o | N (QDiagram b V2 (N b) m)
alpha <- [N (QDiagram b V2 (N b) m)
0,N (QDiagram b V2 (N b) m)
0.25,N (QDiagram b V2 (N b) m)
0.5,N (QDiagram b V2 (N b) m)
0.75]]