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