View Javadoc
1   package org.newdawn.slick.geom;
2   
3   import javax.annotation.Nonnull;
4   import java.util.ArrayList;
5   import java.util.List;
6   
7   /**
8    * A polygon implementation meeting the <code>Shape</code> contract. 
9    * 
10   * @author Mark
11   */
12  public class Polygon extends Shape {
13      /**
14       * 
15       */
16      private static final long serialVersionUID = 1L;
17      /** Allow duplicated points */
18      private boolean allowDups = false;
19      /** True if the polygon is closed */
20      private boolean closed = true;
21  
22      /**
23       * Construct a new polygon with 3 or more points. 
24       * This constructor will take the first set of points and copy them after
25       * the last set of points to create a closed shape.
26       * 
27       * @param points An array of points in x, y order.
28       */
29      private Polygon(@Nonnull float points[]) {
30          int length = points.length;
31          
32          this.points = new float[length];
33          maxX = -Float.MIN_VALUE;
34          maxY = -Float.MIN_VALUE;
35          minX = Float.MAX_VALUE;
36          minY = Float.MAX_VALUE;
37          x = Float.MAX_VALUE;
38          y = Float.MAX_VALUE;
39          
40          for(int i=0;i<length;i++) {
41              this.points[i] = points[i];
42              if(i % 2 == 0) {
43                  if(points[i] > maxX) {
44                      maxX = points[i];
45                  }
46                  if(points[i] < minX) {
47                      minX = points[i];
48                  }
49                  if(points[i] < x) {
50                      x = points[i];
51                  }
52              }
53              else {
54                  if(points[i] > maxY) {
55                      maxY = points[i];
56                  }
57                  if(points[i] < minY) {
58                      minY = points[i];
59                  }
60                  if(points[i] < y) {
61                      y = points[i];
62                  }
63              }
64          }
65          
66          findCenter();
67          calculateRadius();
68          pointsDirty = true;
69      }
70      /**
71       * Create an empty polygon
72       *
73       */
74      public Polygon(){
75          points = new float[0];
76          maxX = -Float.MIN_VALUE;
77          maxY = -Float.MIN_VALUE;
78          minX = Float.MAX_VALUE;
79          minY = Float.MAX_VALUE;
80      }
81      
82      /**
83       * Indicate if duplicate points are allow
84       * 
85       * @param allowDups True if duplicate points are allowed
86       */
87      public void setAllowDuplicatePoints(boolean allowDups) {
88          this.allowDups = allowDups;
89      }
90      
91      /**
92       * Add a point to the polygon
93       * 
94       * @param x The x coordinate of the point
95       * @param y The y coordinate of the point
96       */
97      public void addPoint(float x, float y) {
98          if (hasVertex(x,y) && (!allowDups)) {
99              return;
100         }
101 
102         final List<Float> tempPoints = new ArrayList<>();
103         for (float point : points) {
104             tempPoints.add(point);
105         }
106         tempPoints.add(x);
107         tempPoints.add(y);
108         int length = tempPoints.size();
109         points = new float[length];
110         for(int i=0;i<length;i++) {
111             points[i] = tempPoints.get(i);
112         }
113         if(x > maxX) {
114             maxX = x;
115         }
116         if(y > maxY) {
117             maxY = y;
118         }
119         if(x < minX) {
120             minX = x;
121         }
122         if(y < minY) {
123             minY = y;
124         }
125         findCenter();
126         calculateRadius();
127         
128         pointsDirty = true;
129     }
130 
131 
132     /**
133      * Apply a transformation and return a new shape.  This will not alter the current shape but will 
134      * return the transformed shape.
135      * 
136      * @param transform The transform to be applied
137      * @return The transformed shape.
138      */
139     @Nonnull
140     public Shape transform(@Nonnull Transform transform) {
141         checkPoints();
142         
143         Polygon resultPolygon = new Polygon();
144         
145         float result[] = new float[points.length];
146         transform.transform(points, 0, result, 0, points.length / 2);
147         resultPolygon.points = result;
148         resultPolygon.findCenter();
149         resultPolygon.closed = closed;
150 
151         return resultPolygon;
152     }
153     
154     /**
155      * @see org.newdawn.slick.geom.Shape#setX(float)
156      */
157     public void setX(float x) {
158         super.setX(x);
159         
160         pointsDirty = false;
161     }
162     
163     /**
164      * @see org.newdawn.slick.geom.Shape#setY(float)
165      */
166     public void setY(float y) {
167         super.setY(y);
168         
169         pointsDirty = false;
170     }
171     
172     /**
173      * @see org.newdawn.slick.geom.Shape#createPoints()
174      */
175     protected void createPoints() {
176 //        This is empty since a polygon must have it's points all the time.
177     }
178     
179     /**
180      * @see org.newdawn.slick.geom.Shape#closed()
181      */
182     public boolean closed() {
183         return closed;
184     }
185 
186     /**
187      * Indicate if the polygon should be closed
188      *
189      * @param closed True if the polygon should be closed
190      */
191     public void setClosed(boolean closed) {
192         this.closed = closed;
193     }
194 
195     /**
196      * Provide a copy of this polygon
197      *
198      * @return A copy of this polygon
199      */
200     @Nonnull
201     public Polygon copy() {
202         float[] copyPoints = new float[points.length];
203         System.arraycopy(points, 0, copyPoints, 0, copyPoints.length);
204 
205         return new Polygon(copyPoints);
206     }
207 }