1 /*
2  * DSFML - The Simple and Fast Multimedia Library for D
3  *
4  * Copyright (c) 2013 - 2017 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5  *
6  * This software is provided 'as-is', without any express or implied warranty.
7  * In no event will the authors be held liable for any damages arising from the
8  * use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not claim
15  * that you wrote the original software. If you use this software in a product,
16  * an acknowledgment in the product documentation would be appreciated but is
17  * not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  * misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source distribution
23  */
24 
25 /**
26  * This class inherits all the functions of $(TRANSFORMABLE_LINK) (position,
27  * rotation, scale, bounds, ...) as well as the functions of $(SHAPE_LINK)
28  * (outline, color, texture, ...).
29  *
30  * Example:
31  * ---
32  * auto circle = new CircleShape();
33  * circle.radius = 150;
34  * circle.outlineColor = Color.Red;
35  * circle.outlineThickness = 5;
36  * circle.position = Vector2f(10, 20);
37  * ...
38  * window.draw(circle);
39  * ---
40  *
41  *$(PARA Since the graphics card can't draw perfect circles, we have to fake
42  * them with multiple triangles connected to each other. The "points count"
43  * property of $(U CircleShape) defines how many of these triangles to use, and
44  * therefore defines the quality of the circle.)
45  *
46  * See_Also:
47  * $(SHAPE_LINK), $(RECTANGLESHAPE_LINK), $(CONVEXSHAPE_LINK)
48  */
49 module dsfml.graphics.circleshape;
50 
51 import dsfml.graphics.shape;
52 
53 import dsfml.system.vector2;
54 
55 /**
56  * Specialized shape representing a circle.
57  */
58 class CircleShape : Shape
59 {
60     private
61     {
62         // Radius of the circle
63         float m_radius;
64         /// Number of points composing the circle
65         uint m_pointCount;
66     }
67 
68     /**
69      * Default constructor.
70      *
71      * Params:
72      * 		radius =		Radius of the circle
73      * 		pointCount =	Number of points composing the circle
74     */
75     this(float radius = 0, uint pointCount = 30)
76     {
77         m_radius = radius;
78         m_pointCount = pointCount;
79 
80         update();
81     }
82 
83     /// Destructor
84     ~this()
85     {
86         import dsfml.system.config;
87         mixin(destructorOutput);
88     }
89 
90     @property
91     {
92         /// The number of points of the circle.
93         uint pointCount(uint newPointCount)
94         {
95             m_pointCount = newPointCount;
96             return newPointCount;
97         }
98         /// ditto
99         override uint pointCount()
100         {
101             return m_pointCount;
102         }
103     }
104 
105     @property
106     {
107         /// The radius of the circle.
108         float radius(float newRadius)
109         {
110             m_radius = newRadius;
111             update();
112             return newRadius;
113         }
114         /// ditto
115         float radius()
116         {
117             return m_radius;
118         }
119     }
120 
121     /**
122      * Get a point of the shape.
123      *
124      * The result is undefined if index is out of the valid range.
125      *
126      * Params:
127      * 		index =	Index of the point to get, in range [0 .. pointCount - 1].
128      *
129      * Returns: Index-th point of the shape.
130      */
131     override Vector2f getPoint(uint index) const
132     {
133         import std.math;
134         static const(float) pi = 3.141592654f;
135 
136         float angle = index * 2 * pi / m_pointCount - pi / 2;
137 
138         float x = cos(angle) * m_radius;
139         float y = sin(angle) * m_radius;
140 
141         return Vector2f(m_radius + x, m_radius + y);
142     }
143 
144     /// Clones this CircleShape
145     @property
146     CircleShape dup() const
147     {
148         CircleShape temp = new CircleShape(m_radius, m_pointCount);
149 
150         temp.position = position;
151         temp.rotation = rotation;
152         temp.scale = scale;
153         temp.origin = origin;
154 
155         return temp;
156     }
157 }
158 
159 unittest
160 {
161     version(DSFML_Unittest_Graphics)
162     {
163         import std.stdio;
164         import dsfml.graphics;
165 
166         writeln("Unit test for CircleShape");
167         auto window = new RenderWindow(VideoMode(800,600), "CircleShape unittest");
168 
169         auto circleShape = new CircleShape(20);
170 
171         circleShape.fillColor = Color.Blue;
172 
173         circleShape.outlineColor = Color.Green;
174 
175         auto clock = new Clock();
176 
177 
178         while(window.isOpen())
179         {
180             Event event;
181 
182             while(window.pollEvent(event))
183             {
184                 //no events gonna do stuffs!
185             }
186 
187             //draws the shape for a while before closing the window
188             if(clock.getElapsedTime().total!"seconds" > 1)
189             {
190                 window.close();
191             }
192 
193             window.clear();
194             window.draw(circleShape);
195             window.display();
196         }
197 
198         writeln();
199     }
200 }