Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/geom/RoundedRectangle.java
1461 views
1
package org.newdawn.slick.geom;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import org.newdawn.slick.util.FastTrig;
7
8
/**
9
* Class to create rounded rectangles with.
10
*
11
* @author Mark Bernard
12
*/
13
public class RoundedRectangle extends Rectangle {
14
/** Indicates the top left corner should be rounded */
15
public static final int TOP_LEFT = 1;
16
/** Indicates the top right corner should be rounded */
17
public static final int TOP_RIGHT = 2;
18
/** Indicates the bottom right corner should be rounded */
19
public static final int BOTTOM_RIGHT = 4;
20
/** Indicates the bottom left corner should be rounded */
21
public static final int BOTTOM_LEFT = 8;
22
/** Indicates the all cornders should be rounded */
23
public static final int ALL = TOP_LEFT | TOP_RIGHT | BOTTOM_RIGHT | BOTTOM_LEFT;
24
25
/** Default number of segments to draw the rounded corners with */
26
private static final int DEFAULT_SEGMENT_COUNT = 25;
27
28
/** radius of each corner */
29
private float cornerRadius;
30
/** number of segments for each corner */
31
private int segmentCount;
32
/** The flags indicating which corners should be rounded */
33
private int cornerFlags;
34
35
/**
36
* Construct a rectangle with rounded corners.
37
*
38
* @param x The x position of the rectangle.
39
* @param y The y position of the rectangle.
40
* @param width The width of the rectangle.
41
* @param height The hieght of the rectangle.
42
* @param cornerRadius The radius to use for the arc in each corner.
43
*/
44
public RoundedRectangle(float x, float y, float width, float height, float cornerRadius) {
45
this(x, y, width, height, cornerRadius, DEFAULT_SEGMENT_COUNT);
46
}
47
48
/**
49
* Construct a rectangle with rounded corners.
50
*
51
* @param x The x position of the rectangle.
52
* @param y The y position of the rectangle.
53
* @param width The width of the rectangle.
54
* @param height The hieght of the rectangle.
55
* @param cornerRadius The radius to use for the arc in each corner.
56
* @param segmentCount The number of segments to use to draw each corner arc.
57
*/
58
public RoundedRectangle(float x, float y, float width, float height, float cornerRadius, int segmentCount) {
59
this(x,y,width,height,cornerRadius,segmentCount,ALL);
60
}
61
62
/**
63
* Construct a rectangle with rounded corners.
64
*
65
* @param x The x position of the rectangle.
66
* @param y The y position of the rectangle.
67
* @param width The width of the rectangle.
68
* @param height The hieght of the rectangle.
69
* @param cornerRadius The radius to use for the arc in each corner.
70
* @param segmentCount The number of segments to use to draw each corner arc.
71
* @param cornerFlags Indicates which corners should be rounded
72
*/
73
public RoundedRectangle(float x, float y, float width, float height,
74
float cornerRadius, int segmentCount, int cornerFlags) {
75
super(x,y,width,height);
76
77
if(cornerRadius < 0) {
78
throw new IllegalArgumentException("corner radius must be >= 0");
79
}
80
this.x = x;
81
this.y = y;
82
this.width = width;
83
this.height = height;
84
this.cornerRadius = cornerRadius;
85
this.segmentCount = segmentCount;
86
this.pointsDirty = true;
87
this.cornerFlags = cornerFlags;
88
}
89
90
/**
91
* Get the radius for each corner.
92
*
93
* @return The radius for each corner.
94
*/
95
public float getCornerRadius() {
96
return cornerRadius;
97
}
98
99
/**
100
* Set the radius for each corner.
101
*
102
* @param cornerRadius The radius for each corner to set.
103
*/
104
public void setCornerRadius(float cornerRadius) {
105
if (cornerRadius >= 0) {
106
if (cornerRadius != this.cornerRadius) {
107
this.cornerRadius = cornerRadius;
108
pointsDirty = true;
109
}
110
}
111
}
112
113
/**
114
* Get the height of this rectangle.
115
*
116
* @return The height of this rectangle.
117
*/
118
public float getHeight() {
119
return height;
120
}
121
122
/**
123
* Set the height of this rectangle.
124
*
125
* @param height The height to set.
126
*/
127
public void setHeight(float height) {
128
if (this.height != height) {
129
this.height = height;
130
pointsDirty = true;
131
}
132
}
133
134
/**
135
* Get the width of this rectangle.
136
*
137
* @return The width of this rectangle.
138
*/
139
public float getWidth() {
140
return width;
141
}
142
143
/**
144
* Set the width of this rectangle.
145
*
146
* @param width The width to set.
147
*/
148
public void setWidth(float width) {
149
if (width != this.width) {
150
this.width = width;
151
pointsDirty = true;
152
}
153
}
154
155
protected void createPoints() {
156
maxX = x + width;
157
maxY = y + height;
158
minX = x;
159
minY = y;
160
float useWidth = width - 1;
161
float useHeight = height - 1;
162
if(cornerRadius == 0) {
163
points = new float[8];
164
165
points[0] = x;
166
points[1] = y;
167
168
points[2] = x + useWidth;
169
points[3] = y;
170
171
points[4] = x + useWidth;
172
points[5] = y + useHeight;
173
174
points[6] = x;
175
points[7] = y + useHeight;
176
}
177
else {
178
float doubleRadius = cornerRadius * 2;
179
if(doubleRadius > useWidth) {
180
doubleRadius = useWidth;
181
cornerRadius = doubleRadius / 2;
182
}
183
if(doubleRadius > useHeight) {
184
doubleRadius = useHeight;
185
cornerRadius = doubleRadius / 2;
186
}
187
188
ArrayList tempPoints = new ArrayList();
189
//the outer most set of points for each arc will also ac as the points that start the
190
//straight sides, so the straight sides do not have to be added.
191
192
//top left corner arc
193
if ((cornerFlags & TOP_LEFT) != 0) {
194
tempPoints.addAll(createPoints(segmentCount, cornerRadius, x + cornerRadius, y + cornerRadius, 180, 270));
195
} else {
196
tempPoints.add(new Float(x));
197
tempPoints.add(new Float(y));
198
}
199
200
//top right corner arc
201
if ((cornerFlags & TOP_RIGHT) != 0) {
202
tempPoints.addAll(createPoints(segmentCount, cornerRadius, x + useWidth - cornerRadius, y + cornerRadius, 270, 360));
203
} else {
204
tempPoints.add(new Float(x+useWidth));
205
tempPoints.add(new Float(y));
206
}
207
208
//bottom right corner arc
209
if ((cornerFlags & BOTTOM_RIGHT) != 0) {
210
tempPoints.addAll(createPoints(segmentCount, cornerRadius, x + useWidth - cornerRadius, y + useHeight - cornerRadius, 0, 90));
211
} else {
212
tempPoints.add(new Float(x+useWidth));
213
tempPoints.add(new Float(y+useHeight));
214
}
215
216
//bottom left corner arc
217
if ((cornerFlags & BOTTOM_LEFT) != 0) {
218
tempPoints.addAll(createPoints(segmentCount, cornerRadius, x + cornerRadius, y + useHeight - cornerRadius, 90, 180));
219
} else {
220
tempPoints.add(new Float(x));
221
tempPoints.add(new Float(y+useHeight));
222
}
223
224
points = new float[tempPoints.size()];
225
for(int i=0;i<tempPoints.size();i++) {
226
points[i] = ((Float)tempPoints.get(i)).floatValue();
227
}
228
}
229
230
findCenter();
231
calculateRadius();
232
}
233
234
/**
235
* Generate the points to fill a corner arc.
236
*
237
* @param numberOfSegments How fine to make the ellipse.
238
* @param radius The radius of the arc.
239
* @param cx The x center of the arc.
240
* @param cy The y center of the arc.
241
* @param start The start angle of the arc.
242
* @param end The end angle of the arc.
243
* @return The points created.
244
*/
245
private List createPoints(int numberOfSegments, float radius, float cx, float cy, float start, float end) {
246
ArrayList tempPoints = new ArrayList();
247
248
int step = 360 / numberOfSegments;
249
250
for (float a=start;a<=end+step;a+=step) {
251
float ang = a;
252
if (ang > end) {
253
ang = end;
254
}
255
float x = (float) (cx + (FastTrig.cos(Math.toRadians(ang)) * radius));
256
float y = (float) (cy + (FastTrig.sin(Math.toRadians(ang)) * radius));
257
258
tempPoints.add(new Float(x));
259
tempPoints.add(new Float(y));
260
}
261
262
return tempPoints;
263
}
264
/**
265
* Apply a transformation and return a new shape. This will not alter the current shape but will
266
* return the transformed shape.
267
*
268
* @param transform The transform to be applied
269
* @return The transformed shape.
270
*/
271
public Shape transform(Transform transform) {
272
checkPoints();
273
274
Polygon resultPolygon = new Polygon();
275
276
float result[] = new float[points.length];
277
transform.transform(points, 0, result, 0, points.length / 2);
278
resultPolygon.points = result;
279
resultPolygon.findCenter();
280
281
return resultPolygon;
282
}
283
284
}
285
286