1 /*
2  * DSFML - The Simple and Fast Multimedia Library for D
3  *
4  * Copyright (c) 2013 - 2018 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  * DSFML is based on SFML (Copyright Laurent Gomila)
26  */
27 
28 /**
29  * This class inherits all the functions of $(TRANSFORMABLE_LINK) (position,
30  * rotation, scale, bounds, ...) as well as the functions of $(SHAPE_LINK)
31  * (outline, color, texture, ...).
32  *
33  * Example:
34  * ---
35  * auto circle = new CircleShape();
36  * circle.radius = 150;
37  * circle.outlineColor = Color.Red;
38  * circle.outlineThickness = 5;
39  * circle.position = Vector2f(10, 20);
40  * ...
41  * window.draw(circle);
42  * ---
43  *
44  *$(PARA Since the graphics card can't draw perfect circles, we have to fake
45  * them with multiple triangles connected to each other. The "points count"
46  * property of $(U CircleShape) defines how many of these triangles to use, and
47  * therefore defines the quality of the circle.)
48  *
49  * See_Also:
50  * $(SHAPE_LINK), $(RECTANGLESHAPE_LINK), $(CONVEXSHAPE_LINK)
51  */
52 module nudsfml.graphics.circleshape;
53 
54 import nudsfml.graphics.shape;
55 
56 import nudsfml.system.vector2;
57 
58 import std.stdio;
59 
60 /**
61  * Specialized shape representing a circle.
62  */
63 class CircleShape : Shape {
64     private {
65         // Radius of the circle
66         float m_radius;
67         /// Number of points composing the circle
68         uint m_pointCount;
69     }
70 
71     /**
72      * Default constructor.
73      *
74      * Params:
75      * 		radius =		Radius of the circle
76      * 		pointCount =	Number of points composing the circle
77     */
78     this(float radius = 0, uint pointCount = 30) {
79         m_radius = radius;
80         m_pointCount = pointCount;
81         update();
82     }
83 
84     /// Destructor
85     ~this() {
86     }
87 
88     @property {
89         /// The number of points of the circle.
90         uint pointCount(uint newPointCount) {
91             m_pointCount = newPointCount;
92             return newPointCount;
93         }
94 
95         /// ditto
96         override uint pointCount() const {
97             return m_pointCount;
98         }
99     }
100 
101     @property {
102         /// The radius of the circle.
103         float radius(float newRadius) {
104             m_radius = newRadius;
105             update();
106             return newRadius;
107         }
108 
109         /// ditto
110         float radius() const {
111             return m_radius;
112         }
113     }
114 
115     /**
116      * Get a point of the shape.
117      *
118      * The result is undefined if index is out of the valid range.
119      *
120      * Params:
121      * 		index =	Index of the point to get, in range [0 .. pointCount - 1].
122      *
123      * Returns: Index-th point of the shape.
124      */
125     override Vector2f getPoint(uint index) const {
126         import std.math;
127         static const(float) pi = 3.141592654f;
128 
129         float angle = index * 2 * pi / m_pointCount - pi / 2;
130 
131         float x = cos(angle) * m_radius;
132         float y = sin(angle) * m_radius;
133 
134         return Vector2f(m_radius + x, m_radius + y);
135     }
136 
137     /// Clones this CircleShape
138     @property
139     CircleShape dup() const {
140         CircleShape temp = new CircleShape(m_radius, m_pointCount);
141 
142         temp.position = position;
143         temp.rotation = rotation;
144         temp.scale = scale;
145         temp.origin = origin;
146 
147         return temp;
148     }
149 }
150 
151 unittest
152 {
153     version(DSFML_Unittest_Graphics)
154     {
155         import bindbc.sfml;
156         import std.stdio;
157         import nudsfml.graphics;
158 
159         writeln("testing sfml");
160 
161         if(!loadSFML()){
162             writeln("failed to load sfml");
163 }
164 
165 
166         writeln("Unit test for CircleShape");
167         auto window = new RenderWindow(VideoMode(800,600), "CircleShape unittest");
168         writeln("window created");
169 
170         auto circleShape = new CircleShape(20);
171         writeln("circleShape.radius = ", circleShape.radius);
172 
173         circleShape.fillColor = Color.Blue;
174 
175         circleShape.outlineColor = Color.Green;
176 
177         auto clock = new Clock();
178 
179 
180         while(window.isOpen())
181         {
182             Event event;
183 
184             while(window.pollEvent(event))
185             {
186                 //no events gonna do stuffs!
187             }
188 
189             //draws the shape for a while before closing the window
190             if(clock.getElapsedTime().asSeconds() > 1)
191             {
192                 window.close();
193             }
194 
195             window.clear();
196             window.draw(circleShape);
197             window.display();
198         }
199 
200         writeln();
201     }
202 }