0 | module CyBy.Draw.Internal.Ring
 1 |
 2 | import Data.Fin
 3 | import Data.Array.Indexed
 4 | import CyBy.Draw.Internal.Atom
 5 | import CyBy.Draw.Internal.Graph
 6 | import CyBy.Draw.Internal.Label
 7 | import CyBy.Draw.Internal.Role
 8 | import Geom
 9 | import Text.Molfile
10 |
11 | %default total
12 |
13 | ringBonds : (n : Nat) -> List (Edge n CDBond)
14 | ringBonds n =
15 |   catMaybes $ natEdge 0 (pred n) :: map (\x => natEdge x (S x)) [0 .. pred n]
16 |   where
17 |     natEdge : Nat -> Nat -> Maybe (Edge n CDBond)
18 |     natEdge x y = do
19 |       fx <- tryNatToFin x
20 |       fy <- tryNatToFin y
21 |       mkEdge fx fy (CB None $ cast Single)
22 |
23 | add : Integer -> Double -> Double
24 | add n v = if n `mod` 2 == 0 then v / 2.0 else pi / (- 2.0)
25 |
26 | ||| Creates a regular, saturated n-cycle of carbon atoms.
27 | export
28 | nring : (n : Nat) -> {auto 0 p : LT 2 n} -> CDIGraph n
29 | nring n =
30 |   let step := TwoPi / cast n
31 |       plus := add (cast n) step
32 |       as   := generate n (\f => angle $ cast (cast {to = Nat} f) * step + plus)
33 |
34 |       -- length of vectors pointing from the origin to the points of the n-gon
35 |       -- this follows from `sine phi = opposite / hypotenuse`
36 |       l    := scale $ value BondLengthInPixels / (2.0 * sin (step / 2.0))
37 |    in adjAtomTypes $ mkGraph
38 |         (toVect $ map (\a => elemAt C (translate (polar l a) origin) None) as)
39 |         (ringBonds n)
40 |
41 | ||| Creates a regular, saturated n-cycle of carbon atoms.
42 | export
43 | ring : (n : Nat) -> {auto 0 p : LT 2 n} -> CDGraph
44 | ring n = G n $ nring n
45 |