-
Notifications
You must be signed in to change notification settings - Fork 0
/
CircularDiagrams.hs
109 lines (92 loc) · 4.19 KB
/
CircularDiagrams.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
module CircularDiagrams (diagramShowValue,diagramShowCharValue) where
import Shared
import LinearDiagrams.Shared (charToString)
import Diagrams.Prelude
import Diagrams.Backend.SVG.CmdLine
import Diagrams.TwoD.Arrow (arrowFromLocatedTrail)
import Data.Colour.Palette.ColorSet (Brightness(Light,Dark),d3Colors2)
import qualified Sound.Tidal.Context as T
import Data.Ratio
import Control.Applicative (ZipList(ZipList,getZipList))
radiusOfUnitCircumfrenceCircle :: Double
radiusOfUnitCircumfrenceCircle = 1.0 / (2.0 * pi)
theRadius :: Double
theRadius = radiusOfUnitCircumfrenceCircle
{--
Verify that radiusOfUnitCircumfrenceCircle gives us a circle of circumfrence
1.0:
> c = circle radiusOfUnitCircumfrenceCircle :: Trail V2 Double
> stdArcLength c
1.0001402927134473
--}
overallTransform :: Transformation V2 Double
overallTransform = scalingY (-1) <> (rotation $ (-1/4) @@ turn)
tickMark :: Rational -> Diagram B
tickMark tickLoc = mark
where
tickMarkSize = 0.1 * theRadius
startPoint = p2 (theRadius, 0)
rotAmount = fromRational tickLoc
mark = hrule tickMarkSize # moveTo startPoint # rotateBy rotAmount # transform overallTransform
tickMarkLabel :: Double -> Rational -> Diagram B
tickMarkLabel extraRadius tickLoc = label
where
labelStartPoint = p2 (theRadius + extraRadius, 0)
rotAmount = fromRational tickLoc
labelPoint = labelStartPoint # rotateBy rotAmount # transform overallTransform
labelText = ratioToString tickLoc
label = text labelText # fontSize tickMarkLabelSize # moveTo labelPoint
wedgeGeometry :: Rational -> Rational -> Diagram B
wedgeGeometry startLoc stopLoc = transformedWedge
where
angle = (fromRational (stopLoc - startLoc - 0.003)) @@ turn
startDir = xDir # rotateBy (fromRational startLoc)
innerRadius = theRadius - (eventWidth/2)
outerRadius = theRadius + (eventWidth/2)
theWedge = annularWedge outerRadius innerRadius startDir angle
transformedWedge = theWedge # transform overallTransform
labelGeometry :: String -> Rational -> Diagram B
labelGeometry labelString wedgeStartLoc = labelDiagram
where
labelPos = p2 (theRadius, 0) # rotateBy (fromRational (wedgeStartLoc + eventLabelInset)) # transform overallTransform
labelDiagram = text labelString # fontSize eventLabelSize # moveTo labelPos
cycleDirectionArrow :: Diagram B
cycleDirectionArrow = arro
where
shaft = arc' (theRadius * 1.45) xDir (0.08 @@ turn) # transform overallTransform
arro = arrowFromLocatedTrail shaft
tickMarkLabelOffset :: Double
tickMarkLabelOffset = 0.05
diagram :: (T.Event a -> String) -> T.Pattern a -> Integer -> (T.Event a -> Int) -> Diagram B
diagram formatLabel tidalPattern numTicks colourFunc =
mconcat patterneventlabels
<> mconcat patternevents
<> cycleDirectionArrow
<> mconcat (map tickMark tickLocList)
<> mconcat (map (tickMarkLabel tickMarkLabelOffset) tickLocList)
<> circle theRadius
where
events = ZipList $ T.queryArc tidalPattern (T.Arc 0 1)
--
patternevents = getZipList $ wedgeStyles <*> wedgegeometries
patterneventlabels = getZipList $ labelStyles <*> labelgeometries
--
tickLocList = init $ tickMarkLocations (1%numTicks) 1
--
labels = formatLabel <$> events
colours = colourFunc <$> events
starts = T.eventPartStart <$> events
stops = T.eventPartStop <$> events
--
wedgegeometries :: ZipList (Diagram B)
wedgegeometries = wedgeGeometry <$> starts <*> stops
labelgeometries :: ZipList (Diagram B)
labelgeometries = labelGeometry <$> labels <*> starts
wedgeStyles :: ZipList (Diagram B -> Diagram B)
wedgeStyles = (lw none . fc . d3Colors2 Dark) <$> colours
labelStyles :: ZipList (Diagram B -> Diagram B)
labelStyles = (lw none . fc . d3Colors2 Light) <$> colours
diagramShowValue :: (Show a) => T.Pattern a -> Integer -> (T.Event a -> Int) -> Diagram B
diagramShowValue = diagram (show . T.eventValue)
diagramShowCharValue :: T.Pattern Char -> Integer -> (T.Event Char -> Int) -> Diagram B
diagramShowCharValue = diagram (charToString . T.eventValue)