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