1 /**
2   2D circle type.
3 
4   Copyright: Chris Jones
5   License: Boost Software License, Version 1.0
6   Authors: Chris Jones
7 */
8 
9 module dg2d.circle;
10 
11 import dg2d.scalar;
12 import dg2d.point;
13 import dg2d.misc;
14 import dg2d.path;
15 
16 import std.algorithm: among;
17 
18 /**
19   2D circle
20 */
21 
22 struct Circle
23 {
24     Scalar x0 = 0;
25     Scalar y0 = 0;
26     Scalar radius = 0;
27 
28     this(Scalar x0, Scalar y0, Scalar radius)
29     {
30         this.x0 = x0;
31         this.y0 = y0;
32         this.radius = radius;
33     }
34 
35     auto asPath()
36     {
37         enum PathCmd[13] cmdlut = [
38             PathCmd.move,PathCmd.cubic,PathCmd.cubic,PathCmd.cubic,
39             PathCmd.cubic,PathCmd.cubic,PathCmd.cubic,
40             PathCmd.cubic,PathCmd.cubic,PathCmd.cubic,
41             PathCmd.cubic,PathCmd.cubic,PathCmd.cubic];
42 
43         struct CircleAsPath
44         {
45         public:
46             Point opIndex(size_t idx)
47             {
48                 assert(idx < 13);
49                 switch(idx)
50                 {
51                     case 0: return Point(m_circle.x0,m_circle.y0+m_circle.radius);
52                     case 1: return Point(m_circle.x0+m_circle.radius*CBezOutset,m_circle.y0+m_circle.radius);
53                     case 2: return Point(m_circle.x0+m_circle.radius,m_circle.y0+m_circle.radius*CBezOutset);
54                     case 3: return Point(m_circle.x0+m_circle.radius,m_circle.y0);
55                     case 4: return Point(m_circle.x0+m_circle.radius,m_circle.y0-m_circle.radius*CBezOutset);
56                     case 5: return Point(m_circle.x0+m_circle.radius*CBezOutset,m_circle.y0-m_circle.radius);
57                     case 6: return Point(m_circle.x0,m_circle.y0-m_circle.radius);
58                     case 7: return Point(m_circle.x0-m_circle.radius*CBezOutset,m_circle.y0-m_circle.radius);
59                     case 8: return Point(m_circle.x0-m_circle.radius,m_circle.y0-m_circle.radius*CBezOutset);
60                     case 9: return Point(m_circle.x0-m_circle.radius,m_circle.y0);
61                     case 10: return Point(m_circle.x0-m_circle.radius,m_circle.y0+m_circle.radius*CBezOutset);
62                     case 11: return Point(m_circle.x0-m_circle.radius*CBezOutset,m_circle.y0+m_circle.radius);
63                     case 12: return Point(m_circle.x0,m_circle.y0+m_circle.radius);
64                     default: assert(0);
65                 }
66             }
67             PathCmd cmd(size_t idx)
68             {
69                 assert(idx < 13);
70                 return cmdlut[idx];
71             }
72             size_t length() { return 13; }
73             void* source() { return &this; }
74             bool inPlace() { return true; }
75         private:
76             Circle* m_circle;
77         }
78         return CircleAsPath(&this);
79     }
80 
81 }
82