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  * It is important to keep in mind that a convex shape must always be... convex,
31  * otherwise it may not be drawn correctly. Moreover, the points must be defined
32  * in order; using a random order would result in an incorrect shape.
33  *
34  * Example:
35  * ---
36  * auto polygon = new ConvexShape();
37  * polygon.pointCount = 3;
38  * polygon.setPoint(0, Vector2f(0, 0));
39  * polygon.setPoint(1, Vector2f(0, 10));
40  * polygon.setPoint(2, Vector2f(25, 5));
41  * polygon.outlineColor = Color.Red;
42  * polygon.outlineThickness = 5;
43  * polygon.position = Vector2f(10, 20);
44  * ...
45  * window.draw(polygon);
46  * ---
47  *
48  * See_Also:
49  * $(SHAPE_LINK), $(RECTANGLESHAPE_LINK), $(CIRCLESHAPE_LINK)
50  */
51 module dsfml.graphics.convexshape;
52 
53 import dsfml.system.vector2;
54 import dsfml.graphics.shape;
55 
56 /**
57  * Specialized shape representing a convex polygon.
58  */
59 class ConvexShape : Shape
60 {
61     private Vector2f[] m_points;
62 
63     /**
64      * Default constructor.
65      *
66      * Params:
67      * thePointCount = Number of points on the polygon
68      */
69     this(uint thePointCount = 0)
70     {
71         this.pointCount = thePointCount;
72         update();
73     }
74 
75     /// Destructor.
76     ~this()
77     {
78         import dsfml.system.config;
79         mixin(destructorOutput);
80     }
81 
82     @property
83     {
84         /// The number of points on the polygon
85         uint pointCount(uint newPointCount)
86         {
87             m_points.length = newPointCount;
88             update();
89             return newPointCount;
90         }
91         /// ditto
92         override uint pointCount()
93         {
94             import std.algorithm;
95             return cast(uint)min(m_points.length, uint.max);
96         }
97     }
98 
99     /**
100      * Get the position of a point.
101      *
102      * The result is undefined if index is out of the valid range.
103      *
104      * Params:
105      * 		index =	Index of the point to get, in range [0 .. `pointCount` - 1]
106      *
107      * Returns: Index-th point of the shape.
108      */
109     override Vector2f getPoint(uint index) const
110     {
111         return m_points[index];
112     }
113 
114     /**
115      * Set the position of a point.
116      *
117      * Don't forget that the polygon must remain convex, and the points need to
118      * stay ordered! `pointCount` must be changed first in order to set the total
119      * number of points. The result is undefined if index is out of the valid
120      *range.
121      *
122      * Params:
123      * 		index =	Index of the point to change, in range
124                     [0 .. `pointCount` - 1]
125      * 		point =	New position of the point
126      */
127     void setPoint(uint index, Vector2f point)
128     {
129         m_points[index] = point;
130     }
131 
132     /**
133      * Add a point to the polygon.
134      *
135      * Don't forget that the polygon must remain convex, and the points need to
136      * stay ordered!
137      *
138      * Params:
139      * 		point =	Position of the new point.
140      */
141     void addPoint(Vector2f point)
142     {
143         m_points ~=point;
144         update();
145     }
146 }
147 
148 unittest
149 {
150     version(DSFML_Unittest_Graphics)
151     {
152         import std.stdio;
153         import dsfml.graphics;
154 
155         writeln("Unit test for ConvexShape");
156         auto window = new RenderWindow(VideoMode(800,600), "ConvexShape unittest");
157 
158         auto convexShape = new ConvexShape();
159 
160         convexShape.addPoint(Vector2f(0,20));
161         convexShape.addPoint(Vector2f(10,10));
162         convexShape.addPoint(Vector2f(20,20));
163         convexShape.addPoint(Vector2f(20,30));
164         convexShape.addPoint(Vector2f(10,40));
165         convexShape.addPoint(Vector2f(0,30));
166 
167         convexShape.fillColor = Color.Blue;
168 
169         convexShape.outlineColor = Color.Green;
170 
171         auto clock = new Clock();
172 
173 
174         while(window.isOpen())
175         {
176             Event event;
177 
178             while(window.pollEvent(event))
179             {
180                 //no events gonna do stuffs!
181             }
182 
183             //draws the shape for a while before closing the window
184             if(clock.getElapsedTime().total!"seconds" > 1)
185             {
186                 window.close();
187             }
188 
189             window.clear();
190             window.draw(convexShape);
191             window.display();
192         }
193 
194         writeln();
195     }
196 }