geomerative 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/LICENSE +662 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +2 -0
  6. data/Rakefile +37 -0
  7. data/examples/README.md +7 -0
  8. data/examples/data/FreeSans.ttf +0 -0
  9. data/examples/data/ReplicaBold.ttf +0 -0
  10. data/examples/data/bot1.svg +160 -0
  11. data/examples/hello_svg_to_pdf.rb +26 -0
  12. data/examples/hello_world.rb +23 -0
  13. data/examples/physics_type.rb +77 -0
  14. data/examples/rotate_first_letter.rb +28 -0
  15. data/geomerative.gemspec +32 -0
  16. data/lib/geomerative.rb +12 -0
  17. data/lib/geomerative/version.rb +3 -0
  18. data/pom.xml +110 -0
  19. data/src/geomerative/FastRClip.java +2715 -0
  20. data/src/geomerative/RClip.java +2892 -0
  21. data/src/geomerative/RClosest.java +64 -0
  22. data/src/geomerative/RCommand.java +1941 -0
  23. data/src/geomerative/RContour.java +348 -0
  24. data/src/geomerative/RFont.java +583 -0
  25. data/src/geomerative/RG.java +753 -0
  26. data/src/geomerative/RGeomElem.java +1075 -0
  27. data/src/geomerative/RGroup.java +888 -0
  28. data/src/geomerative/RMatrix.java +401 -0
  29. data/src/geomerative/RMesh.java +420 -0
  30. data/src/geomerative/RPath.java +1095 -0
  31. data/src/geomerative/RPoint.java +419 -0
  32. data/src/geomerative/RPolygon.java +1110 -0
  33. data/src/geomerative/RRectangle.java +91 -0
  34. data/src/geomerative/RSVG.java +976 -0
  35. data/src/geomerative/RShape.java +2045 -0
  36. data/src/geomerative/RStrip.java +221 -0
  37. data/src/geomerative/RStyle.java +469 -0
  38. data/src/org/apache/batik/svggen/font/.SVGFont.java.swp +0 -0
  39. data/src/org/apache/batik/svggen/font/Font.java +188 -0
  40. data/src/org/apache/batik/svggen/font/Glyph.java +113 -0
  41. data/src/org/apache/batik/svggen/font/Messages.java.bak +72 -0
  42. data/src/org/apache/batik/svggen/font/Point.java +38 -0
  43. data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +15 -0
  44. data/src/org/apache/batik/svggen/font/table/ClassDef.java +42 -0
  45. data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +55 -0
  46. data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +49 -0
  47. data/src/org/apache/batik/svggen/font/table/CmapFormat.java +81 -0
  48. data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +60 -0
  49. data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +48 -0
  50. data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +147 -0
  51. data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +60 -0
  52. data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +84 -0
  53. data/src/org/apache/batik/svggen/font/table/CmapTable.java +87 -0
  54. data/src/org/apache/batik/svggen/font/table/Coverage.java +50 -0
  55. data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +59 -0
  56. data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +56 -0
  57. data/src/org/apache/batik/svggen/font/table/CvtTable.java +48 -0
  58. data/src/org/apache/batik/svggen/font/table/Device.java +63 -0
  59. data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +73 -0
  60. data/src/org/apache/batik/svggen/font/table/Feature.java +56 -0
  61. data/src/org/apache/batik/svggen/font/table/FeatureList.java +70 -0
  62. data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +52 -0
  63. data/src/org/apache/batik/svggen/font/table/FeatureTags.java +30 -0
  64. data/src/org/apache/batik/svggen/font/table/FpgmTable.java +38 -0
  65. data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +165 -0
  66. data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +160 -0
  67. data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +79 -0
  68. data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +155 -0
  69. data/src/org/apache/batik/svggen/font/table/GlyfTable.java +111 -0
  70. data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +39 -0
  71. data/src/org/apache/batik/svggen/font/table/GposTable.java +80 -0
  72. data/src/org/apache/batik/svggen/font/table/GsubTable.java +118 -0
  73. data/src/org/apache/batik/svggen/font/table/HeadTable.java +159 -0
  74. data/src/org/apache/batik/svggen/font/table/HheaTable.java +109 -0
  75. data/src/org/apache/batik/svggen/font/table/HmtxTable.java +99 -0
  76. data/src/org/apache/batik/svggen/font/table/KernSubtable.java +58 -0
  77. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +65 -0
  78. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +56 -0
  79. data/src/org/apache/batik/svggen/font/table/KernTable.java +64 -0
  80. data/src/org/apache/batik/svggen/font/table/KerningPair.java +53 -0
  81. data/src/org/apache/batik/svggen/font/table/LangSys.java +58 -0
  82. data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +52 -0
  83. data/src/org/apache/batik/svggen/font/table/Ligature.java +57 -0
  84. data/src/org/apache/batik/svggen/font/table/LigatureSet.java +55 -0
  85. data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +40 -0
  86. data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +63 -0
  87. data/src/org/apache/batik/svggen/font/table/LocaTable.java +72 -0
  88. data/src/org/apache/batik/svggen/font/table/Lookup.java +77 -0
  89. data/src/org/apache/batik/svggen/font/table/LookupList.java +68 -0
  90. data/src/org/apache/batik/svggen/font/table/LookupSubtable.java +27 -0
  91. data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +31 -0
  92. data/src/org/apache/batik/svggen/font/table/MaxpTable.java +124 -0
  93. data/src/org/apache/batik/svggen/font/table/NameRecord.java +98 -0
  94. data/src/org/apache/batik/svggen/font/table/NameTable.java +67 -0
  95. data/src/org/apache/batik/svggen/font/table/Os2Table.java +232 -0
  96. data/src/org/apache/batik/svggen/font/table/Panose.java +108 -0
  97. data/src/org/apache/batik/svggen/font/table/PostTable.java +379 -0
  98. data/src/org/apache/batik/svggen/font/table/PrepTable.java +38 -0
  99. data/src/org/apache/batik/svggen/font/table/Program.java +49 -0
  100. data/src/org/apache/batik/svggen/font/table/RangeRecord.java +57 -0
  101. data/src/org/apache/batik/svggen/font/table/Script.java +72 -0
  102. data/src/org/apache/batik/svggen/font/table/ScriptList.java +78 -0
  103. data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +52 -0
  104. data/src/org/apache/batik/svggen/font/table/ScriptTags.java +28 -0
  105. data/src/org/apache/batik/svggen/font/table/SingleSubst.java +47 -0
  106. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +67 -0
  107. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +67 -0
  108. data/src/org/apache/batik/svggen/font/table/Table.java +204 -0
  109. data/src/org/apache/batik/svggen/font/table/TableDirectory.java +94 -0
  110. data/src/org/apache/batik/svggen/font/table/TableFactory.java +121 -0
  111. metadata +206 -0
@@ -0,0 +1,419 @@
1
+ /**
2
+ Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
3
+
4
+ This file is part of Geomerative.
5
+
6
+ Geomerative is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Geomerative is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with Geomerative. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ package geomerative;
21
+
22
+ /**
23
+ * RPoint is a very simple interface for creating, holding and drawing 2D points.
24
+ * @eexample RPoint
25
+ * @usage Geometry
26
+ * @related x
27
+ * @related y
28
+ */
29
+ public class RPoint
30
+ {
31
+ /**
32
+ * The x coordinate of the point.
33
+ * @eexample RPoint_x
34
+ * @usage Geometry
35
+ * @related y
36
+ */
37
+ public float x;
38
+
39
+ /**
40
+ * The y coordinate of the point.
41
+ * @eexample RPoint_y
42
+ * @usage Geometry
43
+ * @related x
44
+ */
45
+ public float y;
46
+
47
+ /**
48
+ * Create a new point, given the coordinates.
49
+ * @eexample RPoint_constructor
50
+ * @usage Geometry
51
+ * @param x the x coordinate of the new point
52
+ * @param y the y coordinate of the new point
53
+ * @related x
54
+ * @related y
55
+ */
56
+ public RPoint(float x,float y)
57
+ {
58
+ this.x = x;
59
+ this.y = y;
60
+ }
61
+
62
+ public RPoint(double x, double y)
63
+ {
64
+ this.x = (float)x;
65
+ this.y = (float)y;
66
+ }
67
+
68
+ /**
69
+ * Create a new point at (0, 0).
70
+ * @eexample RPoint_constructor
71
+ * @usage Geometry
72
+ * @related x
73
+ * @related y
74
+ */
75
+ public RPoint()
76
+ {
77
+ x = 0;
78
+ y = 0;
79
+ }
80
+
81
+ /**
82
+ * Copy a point.
83
+ * @eexample RPoint_constructor
84
+ * @usage Geometry
85
+ * @param p the point we wish to make a copy of
86
+ * @related x
87
+ * @related y
88
+ */
89
+ public RPoint(RPoint p)
90
+ {
91
+ this.x = p.x;
92
+ this.y = p.y;
93
+ }
94
+
95
+ /**
96
+ * @invisible
97
+ */
98
+ float getX()
99
+ {
100
+ return this.x;
101
+ }
102
+
103
+ /**
104
+ * @invisible
105
+ */
106
+ float getY()
107
+ {
108
+ return this.y;
109
+ }
110
+
111
+
112
+ /**
113
+ * @invisible
114
+ */
115
+ void setLocation(float nx, float ny)
116
+ {
117
+ this.x = nx;
118
+ this.y = ny;
119
+ }
120
+
121
+ /**
122
+ * Use this to apply a transformation to the point.
123
+ * @eexample RPoint_transform
124
+ * @usage Geometry
125
+ * @param m the transformation matrix to be applied
126
+ * @related translate ( )
127
+ * @related rotate ( )
128
+ * @related scale ( )
129
+ */
130
+ public void transform(RMatrix m)
131
+ {
132
+ float tempx = m.m00*x + m.m01*y + m.m02;
133
+ float tempy = m.m10*x + m.m11*y + m.m12;
134
+
135
+ x = tempx;
136
+ y = tempy;
137
+ }
138
+
139
+ /**
140
+ * Apply a translation to the point.
141
+ * @eexample RPoint_translate
142
+ * @usage Geometry
143
+ * @param tx the coefficient of x translation
144
+ * @param ty the coefficient of y translation
145
+ * @related transform ( )
146
+ * @related rotate ( )
147
+ * @related scale ( )
148
+ */
149
+ public void translate(float tx, float ty)
150
+ {
151
+ x += tx;
152
+ y += ty;
153
+ }
154
+
155
+ /**
156
+ * Apply a translation to the point.
157
+ * @eexample RPoint_translate
158
+ * @usage Geometry
159
+ * @param t the translation vector to be applied
160
+ * @related transform ( )
161
+ * @related rotate ( )
162
+ * @related scale ( )
163
+ */
164
+ public void translate(RPoint t)
165
+ {
166
+ x += t.x;
167
+ y += t.y;
168
+ }
169
+
170
+ /**
171
+ * Apply a rotation to the point, given the angle and optionally the coordinates of the center of rotation.
172
+ * @eexample RPoint_rotate
173
+ * @usage Geometry
174
+ * @param angle the angle of rotation to be applied
175
+ * @param vx the x coordinate of the center of rotation
176
+ * @param vy the y coordinate of the center of rotation
177
+ * @related transform ( )
178
+ * @related translate ( )
179
+ * @related scale ( )
180
+ */
181
+ public void rotate(float angle, float vx, float vy)
182
+ {
183
+ float c = (float)Math.cos(angle);
184
+ float s = (float)Math.sin(angle);
185
+
186
+ x -= vx;
187
+ y -= vy;
188
+
189
+ float tempx = x;
190
+ float tempy = y;
191
+
192
+ x = tempx*c - tempy*s;
193
+ y = tempx*s + tempy*c;
194
+
195
+ x += vx;
196
+ y += vy;
197
+ }
198
+
199
+ public void rotate(float angle)
200
+ {
201
+ float c = (float)Math.cos(angle);
202
+ float s = (float)Math.sin(angle);
203
+
204
+ float tempx = x;
205
+ float tempy = y;
206
+
207
+ x = tempx*c - tempy*s;
208
+ y = tempx*s + tempy*c;
209
+ }
210
+
211
+ /**
212
+ * Apply a rotation to the point, given the angle and optionally the point of the center of rotation.
213
+ * @eexample RPoint_rotate
214
+ * @usage Geometry
215
+ * @param angle the angle of rotation to be applied
216
+ * @param v the position vector of the center of rotation
217
+ * @related transform ( )
218
+ * @related translate ( )
219
+ * @related scale ( )
220
+ */
221
+ public void rotate(float angle, RPoint v)
222
+ {
223
+ float c = (float)Math.cos(angle);
224
+ float s = (float)Math.sin(angle);
225
+
226
+ x -= v.x;
227
+ y -= v.y;
228
+
229
+ float tempx = x;
230
+ float tempy = y;
231
+
232
+ x = tempx*c - tempy*s;
233
+ y = tempx*s + tempy*c;
234
+
235
+ x += v.x;
236
+ y += v.y;
237
+ }
238
+
239
+ /**
240
+ * Apply a scaling to the point, given the scaling factors.
241
+ * @eexample RPoint_scale
242
+ * @usage Geometry
243
+ * @param sx the scaling coefficient over the x axis
244
+ * @param sy the scaling coefficient over the y axis
245
+ * @related transform ( )
246
+ * @related translate ( )
247
+ * @related rotate ( )
248
+ */
249
+ public void scale (float sx, float sy)
250
+ {
251
+ x *= sx;
252
+ y *= sy;
253
+ }
254
+
255
+ /**
256
+ * Apply a scaling to the point, given a scaling factor.
257
+ * @eexample RPoint_scale
258
+ * @usage Geometry
259
+ * @param s the scaling coefficient for a uniform scaling
260
+ * @related transform ( )
261
+ * @related translate ( )
262
+ * @related rotate ( )
263
+ */
264
+ public void scale (float s)
265
+ {
266
+ x *= s;
267
+ y *= s;
268
+ }
269
+
270
+ /**
271
+ * Apply a scaling to the point, given a scaling vector.
272
+ * @eexample RPoint_scale
273
+ * @usage Geometry
274
+ * @param s the scaling vector
275
+ * @related transform ( )
276
+ * @related translate ( )
277
+ * @related rotate ( )
278
+ */
279
+ public void scale (RPoint s)
280
+ {
281
+ x *= s.x;
282
+ y *= s.y;
283
+ }
284
+
285
+
286
+ /**
287
+ * Use this to normalize the point. This means that after applying, it's norm will be equal to 1.
288
+ * @eexample RPoint_normalize
289
+ * @usage Geometry
290
+ * @related transform ( )
291
+ * @related translate ( )
292
+ * @related rotate ( )
293
+ * @related scale ( )
294
+ */
295
+ public void normalize ()
296
+ {
297
+ float norma = norm();
298
+ if(norma!=0) scale(1/norma);
299
+ }
300
+
301
+ /**
302
+ * Use this to subtract a vector from this point.
303
+ * @eexample RPoint_sub
304
+ * @usage Geometry
305
+ * @param p the vector to substract
306
+ * @related add ( )
307
+ * @related mult ( )
308
+ * @related cross ( )
309
+ */
310
+ public void sub (RPoint p)
311
+ {
312
+ x -= p.x;
313
+ y -= p.y;
314
+ }
315
+
316
+ /**
317
+ * Use this to add a vector to this point.
318
+ * @eexample RPoint_add
319
+ * @usage Geometry
320
+ * @param p the vector to add
321
+ * @related sub ( )
322
+ * @related mult ( )
323
+ * @related cross ( )
324
+ */
325
+ public void add (RPoint p)
326
+ {
327
+ x += p.x;
328
+ y += p.y;
329
+ }
330
+
331
+ /**
332
+ * Use this to multiply a vector to this point. This returns a float corresponding to the scalar product of both vectors.
333
+ * @eexample RPoint_mult
334
+ * @usage Geometry
335
+ * @param p the vector to multiply
336
+ * @return float, the result of the scalar product
337
+ * @related add ( )
338
+ * @related sub ( )
339
+ * @related cross ( )
340
+ */
341
+ public float mult (RPoint p)
342
+ {
343
+ return (x * p.x + y * p.y);
344
+ }
345
+
346
+ /**
347
+ * Use this to perform a cross product of the point with another point. This returns a RPoint corresponding to the cross product of both vectors.
348
+ * @eexample RPoint_cross
349
+ * @usage Geometry
350
+ * @param p the vector to perform the cross product with
351
+ * @return RPoint, the resulting vector of the cross product
352
+ * @related add ( )
353
+ * @related sub ( )
354
+ * @related mult ( )
355
+ */
356
+ public RPoint cross (RPoint p)
357
+ {
358
+ return new RPoint(x * p.y - p.x * y, y * p.x - p.y * x);
359
+ }
360
+
361
+ /**
362
+ * Use this to obtain the norm of the point.
363
+ * @eexample RPoint_norm
364
+ * @usage Geometry
365
+ * @return float, the norm of the point
366
+ * @related angle ( )
367
+ */
368
+ public float norm ()
369
+ {
370
+ return (float)Math.sqrt(mult(this));
371
+ }
372
+
373
+ /**
374
+ * Use this to obtain the square norm of the point.
375
+ * @eexample RPoint_norm
376
+ * @usage Geometry
377
+ * @return float, the norm of the point
378
+ * @related angle ( )
379
+ */
380
+ public float sqrnorm ()
381
+ {
382
+ return (float)mult(this);
383
+ }
384
+
385
+ /**
386
+ * Use this to obtain the angle between the vector and another vector
387
+ * @eexample RPoint_angle
388
+ * @usage Geometry
389
+ * @param p the vector relative to which we want to evaluate the angle
390
+ * @return float, the angle between the two vectors
391
+ * @related norm ( )
392
+ */
393
+ public float angle (RPoint p)
394
+ {
395
+ float normp = p.norm();
396
+ float normthis = norm();
397
+ return (float)Math.acos(mult(p)/(normp*normthis));
398
+ }
399
+
400
+ /**
401
+ * Use this to obtain the distance between the vector and another vector
402
+ * @eexample RPoint_dist
403
+ * @usage Geometry
404
+ * @param p the vector relative to which we want to evaluate the distance
405
+ * @return float, the distance between the two vectors
406
+ * @related norm ( )
407
+ */
408
+ public float dist (RPoint p)
409
+ {
410
+ float dx = (p.x-this.x);
411
+ float dy = (p.y-this.y);
412
+ return (float)Math.sqrt(dx*dx + dy*dy);
413
+ }
414
+
415
+
416
+ public void print(){
417
+ System.out.print("("+x+","+y+")\n");
418
+ }
419
+ }
@@ -0,0 +1,1110 @@
1
+ /**
2
+ * Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
3
+ *
4
+ This file is part of Geomerative.
5
+ *
6
+ * Geomerative is free software: you can redistribute it and/or modify it under
7
+ * the terms of the GNU General Public License as published by the Free Software
8
+ * Foundation, either version 3 of the License, or (at your option) any later
9
+ * version.
10
+ *
11
+ * Geomerative is distributed in the hope that it will be useful, but WITHOUT
12
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
+ * details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License along with
17
+ * Geomerative. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+ package geomerative;
20
+
21
+ import processing.core.*;
22
+
23
+ /**
24
+ * RPolygon is a reduced interface for creating, holding and drawing complex
25
+ * polygons. Polygons are groups of one or more contours (RContour). This
26
+ * interface allows us to perform binary operations (difference, xor, union and
27
+ * intersection) on polygons.
28
+ *
29
+ * @eexample RPolygon
30
+ * @usage Geometry
31
+ * @related RContour
32
+ * @related createCircle ( )
33
+ * @related createRing ( )
34
+ * @related createStar ( )
35
+ * @related diff ( )
36
+ * @related xor ( )
37
+ * @related union ( )
38
+ * @related intersection ( )
39
+ * @extended
40
+ */
41
+ public class RPolygon extends RGeomElem {
42
+
43
+ /**
44
+ * @invisible
45
+ */
46
+ public int type = RGeomElem.POLYGON;
47
+ public static int defaultDetail = 50;
48
+
49
+ /**
50
+ * Array of RContour objects holding the contours of the polygon.
51
+ *
52
+ * @eexample contours
53
+ * @related RContour
54
+ * @related countContours ( )
55
+ * @related addContour ( )
56
+ */
57
+ public RContour[] contours;
58
+ int currentContour = 0;
59
+
60
+ // ----------------------
61
+ // --- Public Methods ---
62
+ // ----------------------
63
+ /**
64
+ * Make a copy of the given polygon.
65
+ *
66
+ * @eexample createPolygon
67
+ * @param p the object of which to make a copy
68
+ */
69
+ public RPolygon(RPolygon p) {
70
+ if (p == null) {
71
+ return;
72
+ }
73
+
74
+ for (int i = 0; i < p.countContours(); i++) {
75
+ this.append(new RContour(p.contours[i]));
76
+ }
77
+ type = RGeomElem.POLYGON;
78
+
79
+ setStyle(p);
80
+ }
81
+
82
+ /**
83
+ * Create a new polygon given an array of points.
84
+ *
85
+ * @eexample createPolygon
86
+ * @param points the points for the new polygon.
87
+ */
88
+ public RPolygon(RPoint[] points) {
89
+ this(new RContour(points));
90
+ }
91
+
92
+ /**
93
+ * Create a new polygon given a contour.
94
+ *
95
+ * @param newcontour the contour for the new polygon.
96
+ */
97
+ public RPolygon(RContour newcontour) {
98
+ this.append(newcontour);
99
+ type = RGeomElem.POLYGON;
100
+ }
101
+
102
+ /**
103
+ * Create an empty polygon.
104
+ */
105
+ public RPolygon() {
106
+ contours = null;
107
+ type = RGeomElem.POLYGON;
108
+ }
109
+
110
+ /**
111
+ * Use this method to create a new circle polygon.
112
+ *
113
+ * @param x
114
+ * @param y
115
+ * @eexample createCircle
116
+ * @param radius the radius of the circle
117
+ * @param detail the number of vertices of the polygon
118
+ * @return RPolygon, the circular polygon newly created
119
+ */
120
+ static public RPolygon createCircle(float x, float y, float radius, int detail) {
121
+ RPoint[] points = new RPoint[detail];
122
+ double radiansPerStep = 2 * Math.PI / detail;
123
+ for (int i = 0; i < detail; i++) {
124
+ points[i] = new RPoint(
125
+ radius * Math.cos(i * radiansPerStep) + x,
126
+ radius * Math.sin(i * radiansPerStep) + y
127
+ );
128
+ }
129
+ return new RPolygon(points);
130
+ }
131
+
132
+ static public RPolygon createCircle(float radius, int detail) {
133
+ return createCircle(0, 0, radius, detail);
134
+ }
135
+
136
+ static public RPolygon createCircle(float x, float y, float radius) {
137
+ return createCircle(x, y, radius, defaultDetail);
138
+ }
139
+
140
+ static public RPolygon createCircle(float radius) {
141
+ return createCircle(0, 0, radius, defaultDetail);
142
+ }
143
+
144
+ /**
145
+ * Use this method to create a new rectangle polygon.
146
+ *
147
+ * @eexample createRectangle
148
+ * @param x the upper-left corner x coordinate
149
+ * @param y the upper-left corner y coordinate
150
+ * @param w the width
151
+ * @param h the height
152
+ * @return RPolygon, the circular polygon newly created
153
+ */
154
+ static public RPolygon createRectangle(float x, float y, float w, float h) {
155
+ RPolygon rectangle = new RPolygon();
156
+ rectangle.addPoint(x, y);
157
+ rectangle.addPoint(x + w, y);
158
+ rectangle.addPoint(x + w, y + h);
159
+ rectangle.addPoint(x, y + h);
160
+ rectangle.addPoint(x, y);
161
+ return rectangle;
162
+ }
163
+
164
+ static public RPolygon createRectangle(float w, float h) {
165
+ return createRectangle(0, 0, w, h);
166
+ }
167
+
168
+ /**
169
+ * Use this method to create a new starform polygon.
170
+ *
171
+ * @param x
172
+ * @param y
173
+ * @eexample createStar
174
+ * @param radiusBig the outter radius of the star polygon
175
+ * @param radiusSmall the inner radius of the star polygon
176
+ * @param spikes the amount of spikes on the star polygon
177
+ * @return RPolygon, the starform polygon newly created
178
+ */
179
+ static public RPolygon createStar(float x, float y, float radiusBig, float radiusSmall, int spikes) {
180
+ int numPoints = spikes * 2;
181
+ RPoint[] points = new RPoint[numPoints];
182
+ double radiansPerStep = Math.PI / spikes;
183
+ for (int i = 0; i < numPoints; i += 2) {
184
+ points[i] = new RPoint(
185
+ radiusBig * Math.cos(i * radiansPerStep) + x,
186
+ radiusBig * Math.sin(i * radiansPerStep) + y
187
+ );
188
+ points[i + 1] = new RPoint(
189
+ radiusSmall * Math.cos(i * radiansPerStep) + x,
190
+ radiusSmall * Math.sin(i * radiansPerStep) + y
191
+ );
192
+ }
193
+ return new RPolygon(points);
194
+ }
195
+
196
+ static public RPolygon createStar(float radiusBig, float radiusSmall, int spikes) {
197
+ return createStar(0, 0, radiusBig, radiusSmall, spikes);
198
+ }
199
+
200
+ /**
201
+ * Use this method to create a new ring polygon.
202
+ *
203
+ * @param x
204
+ * @param y
205
+ * @eexample createRing
206
+ * @param radiusBig the outter radius of the ring polygon
207
+ * @param radiusSmall the inner radius of the ring polygon
208
+ * @param detail the number of vertices on each contour of the ring
209
+ * @return RPolygon, the ring polygon newly created
210
+ */
211
+ static public RPolygon createRing(float x, float y, float radiusBig, float radiusSmall, int detail) {
212
+ RPoint[] inner = new RPoint[detail];
213
+ RPoint[] outer = new RPoint[detail];
214
+ double radiansPerStep = 2 * Math.PI / detail;
215
+ for (int i = 0; i < detail; i++) {
216
+ inner[i] = new RPoint(
217
+ radiusSmall * Math.cos(i * radiansPerStep) + x,
218
+ radiusSmall * Math.sin(i * radiansPerStep) + y
219
+ );
220
+ outer[i] = new RPoint(
221
+ radiusBig * Math.cos(i * radiansPerStep) + x,
222
+ radiusBig * Math.sin(i * radiansPerStep) + y
223
+ );
224
+ }
225
+ RPolygon ring = new RPolygon();
226
+ ring.addContour(outer);
227
+ ring.addContour(inner);
228
+ return ring;
229
+ }
230
+
231
+ static public RPolygon createRing(float radiusBig, float radiusSmall, int detail) {
232
+ return createRing(0, 0, radiusBig, radiusSmall, detail);
233
+ }
234
+
235
+ static public RPolygon createRing(float x, float y, float radiusBig, float radiusSmall) {
236
+ return createRing(x, y, radiusBig, radiusSmall, defaultDetail);
237
+ }
238
+
239
+ static public RPolygon createRing(float radiusBig, float radiusSmall) {
240
+ return createRing(0, 0, radiusBig, radiusSmall, defaultDetail);
241
+ }
242
+
243
+ /**
244
+ * Use this method to get the centroid of the element.
245
+ *
246
+ * @eexample RGroup_getCentroid
247
+ * @return RPo the centroid point of the element
248
+ * @related getBounds ( )
249
+ * @related getCenter ( )
250
+ */
251
+ @Override
252
+ public RPoint getCentroid() {
253
+ RPoint bestCentroid = new RPoint();
254
+ float bestArea = Float.NEGATIVE_INFINITY;
255
+ if (contours != null) {
256
+ for (RContour contour : contours) {
257
+ float area = Math.abs(contour.getArea());
258
+ if (area > bestArea) {
259
+ bestArea = area;
260
+ bestCentroid = contour.getCentroid();
261
+ }
262
+ }
263
+ return bestCentroid;
264
+ }
265
+ return null;
266
+ }
267
+
268
+ /**
269
+ * Use this method to count the number of contours in the polygon.
270
+ *
271
+ * @eexample countContours
272
+ * @return int the number contours in the polygon
273
+ * @related addContour ( )
274
+ */
275
+ public int countContours() {
276
+ if (this.contours == null) {
277
+ return 0;
278
+ }
279
+
280
+ return this.contours.length;
281
+ }
282
+
283
+ /**
284
+ * Add a new contour to the polygon.
285
+ *
286
+ * @eexample addContour
287
+ * @param c the contour to be added
288
+ * @related addPoint ( )
289
+ */
290
+ public void addContour(RContour c) {
291
+ this.append(c);
292
+ }
293
+
294
+ /**
295
+ * Add an empty contour to the polygon.
296
+ *
297
+ * @eexample addContour
298
+ * @related addPoint ( )
299
+ */
300
+ public void addContour() {
301
+ this.append(new RContour());
302
+ }
303
+
304
+ /**
305
+ * Add a new contour to the polygon given an array of points.
306
+ *
307
+ * @eexample addContour
308
+ * @param points the points of the new contour to be added
309
+ * @related addPoint ( )
310
+ */
311
+ public void addContour(RPoint[] points) {
312
+ this.append(new RContour(points));
313
+ }
314
+
315
+ /**
316
+ * Use this method to set the current contour to which append points.
317
+ *
318
+ * @param indContour
319
+ * @eexample addContour
320
+ * @related addPoint ( )
321
+ */
322
+ public void setContour(int indContour) {
323
+ this.currentContour = indContour;
324
+ }
325
+
326
+ /**
327
+ * Add a new point to the current contour.
328
+ *
329
+ * @eexample addPoint
330
+ * @param p the point to be added
331
+ * @related addContour ( )
332
+ * @related setCurrent ( )
333
+ */
334
+ public void addPoint(RPoint p) {
335
+ if (contours == null) {
336
+ this.append(new RContour());
337
+ }
338
+ this.contours[currentContour].append(p);
339
+ }
340
+
341
+ /**
342
+ * Add a new point to the current contour.
343
+ *
344
+ * @eexample addPoint
345
+ * @param x the x coordinate of the point to be added
346
+ * @param y the y coordinate of the point to be added
347
+ * @related addContour ( )
348
+ * @related setCurrent ( )
349
+ */
350
+ public void addPoint(float x, float y) {
351
+ if (contours == null) {
352
+ this.append(new RContour());
353
+ }
354
+ this.contours[currentContour].append(new RPoint(x, y));
355
+ }
356
+
357
+ /**
358
+ * Add a new point to the selected contour.
359
+ *
360
+ * @eexample addPoint
361
+ * @param indContour the index of the contour to which the point will be
362
+ * added
363
+ * @param p the point to be added
364
+ * @related addContour ( )
365
+ * @related setCurrent ( )
366
+ */
367
+ public void addPoint(int indContour, RPoint p) {
368
+ if (contours == null) {
369
+ this.append(new RContour());
370
+ }
371
+ this.contours[indContour].append(p);
372
+ }
373
+
374
+ /**
375
+ * Add a new point to the selected contour.
376
+ *
377
+ * @eexample addPoint
378
+ * @param indContour the index of the contour to which the point will be
379
+ * added
380
+ * @param x the x coordinate of the point to be added
381
+ * @param y the y coordinate of the point to be added
382
+ * @related addContour ( )
383
+ * @related setCurrent ( )
384
+ */
385
+ public void addPoint(int indContour, float x, float y) {
386
+ if (contours == null) {
387
+ this.append(new RContour());
388
+ }
389
+ this.contours[indContour].append(new RPoint(x, y));
390
+ }
391
+
392
+ public void addClose() {
393
+ if (contours == null) {
394
+ return;
395
+ }
396
+
397
+ contours[contours.length - 1].addClose();
398
+ }
399
+
400
+ /**
401
+ * Use this method to create a new mesh from a given polygon.
402
+ *
403
+ * @eexample toMesh
404
+ * @return RMesh, the mesh made of tristrips resulting of a tesselation of
405
+ * the polygon
406
+ * @related draw ( )
407
+ */
408
+ @Override
409
+ public RMesh toMesh() {
410
+ if (contours == null) {
411
+ return new RMesh();
412
+ }
413
+
414
+ RMesh mesh = RClip.polygonToMesh(this);
415
+ if (mesh == null) {
416
+ return null;
417
+ }
418
+
419
+ mesh.setStyle(this);
420
+ return mesh;
421
+ }
422
+
423
+ @Override
424
+ public void print() {
425
+ System.out.println("polygon: ");
426
+ for (int i = 0; i < countContours(); i++) {
427
+ System.out.println("--- contour " + i + " ---");
428
+ contours[i].print();
429
+ System.out.println("---------------");
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Removes contours with less than 3 points. These are contours that are
435
+ * open. Since close polygons have points[0] == points[-1] and two more
436
+ * points to form a triangle at least. This is useful to avoid the clipping
437
+ * algorithm from breaking.
438
+ *
439
+ * @return
440
+ * @invisible
441
+ */
442
+ protected RPolygon removeOpenContours() {
443
+ RPolygon clean = new RPolygon();
444
+ for (int i = 0; i < countContours(); i++) {
445
+ if (contours[i].countPoints() > 3) {
446
+ clean.addContour(contours[i]);
447
+ }
448
+ }
449
+ clean.setStyle(this);
450
+ return clean;
451
+ }
452
+
453
+ /**
454
+ * @return @invisible
455
+ */
456
+ @Override
457
+ public RPolygon toPolygon() {
458
+ return new RPolygon(this);
459
+ }
460
+
461
+ /**
462
+ * @return @invisible
463
+ */
464
+ @Override
465
+ public RShape toShape() {
466
+ int numContours = countContours();
467
+
468
+ RShape result = new RShape();
469
+ for (int i = 0; i < numContours; i++) {
470
+ RPoint[] newpoints = this.contours[i].getHandles();
471
+
472
+ if (newpoints != null) {
473
+ result.addMoveTo(newpoints[0]);
474
+
475
+ for (int j = 1; j < newpoints.length; j++) {
476
+ result.addLineTo(newpoints[j]);
477
+ }
478
+
479
+ if (contours[i].closed) {
480
+ result.addClose();
481
+ }
482
+
483
+ result.paths[i].setStyle(contours[i]);
484
+ }
485
+ }
486
+
487
+ result.setStyle(this);
488
+ return result;
489
+ }
490
+
491
+ /**
492
+ * Use this to return the points of the polygon. It returns the points in
493
+ * the way of an array of RPoint.
494
+ *
495
+ * @eexample RPolygon_getHandles
496
+ * @return RPoint[], the points returned in an array.
497
+ *
498
+ */
499
+ @Override
500
+ public RPoint[] getHandles() {
501
+ int numContours = countContours();
502
+ if (numContours == 0) {
503
+ return null;
504
+ }
505
+
506
+ RPoint[] result = null;
507
+ RPoint[] newresult = null;
508
+ for (int i = 0; i < numContours; i++) {
509
+ RPoint[] newPoints = contours[i].getHandles();
510
+ if (newPoints != null) {
511
+ if (result == null) {
512
+ result = new RPoint[newPoints.length];
513
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
514
+ } else {
515
+ newresult = new RPoint[result.length + newPoints.length];
516
+ System.arraycopy(result, 0, newresult, 0, result.length);
517
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
518
+ result = newresult;
519
+ }
520
+ }
521
+ }
522
+ return result;
523
+ }
524
+
525
+ /**
526
+ * Use this to return the points of the polygon. It returns the points in
527
+ * the way of an array of RPoint.
528
+ *
529
+ * @eexample RPolygon_getPoints
530
+ * @return RPoint[], the points returned in an array.
531
+ *
532
+ */
533
+ @Override
534
+ public RPoint[] getPoints() {
535
+ int numContours = countContours();
536
+ if (numContours == 0) {
537
+ return null;
538
+ }
539
+
540
+ RPoint[] result = null;
541
+ RPoint[] newresult = null;
542
+ for (int i = 0; i < numContours; i++) {
543
+ RPoint[] newPoints = contours[i].getPoints();
544
+ if (newPoints != null) {
545
+ if (result == null) {
546
+ result = new RPoint[newPoints.length];
547
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
548
+ } else {
549
+ newresult = new RPoint[result.length + newPoints.length];
550
+ System.arraycopy(result, 0, newresult, 0, result.length);
551
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
552
+ result = newresult;
553
+ }
554
+ }
555
+ }
556
+ return result;
557
+ }
558
+
559
+ /**
560
+ * Use this method to get the type of element this is.
561
+ *
562
+ * @eexample RPolygon_getType
563
+ * @return int, will allways return RGeomElem.POLYGON
564
+ */
565
+ @Override
566
+ public int getType() {
567
+ return type;
568
+ }
569
+
570
+ /**
571
+ * Use this method to get the area covered by the polygon.
572
+ *
573
+ * @eexample getArea
574
+ * @return float, the area covered by the polygon
575
+ * @related draw ( )
576
+ */
577
+ @Override
578
+ public float getArea() {
579
+ if (getNumPoints() < 3) {
580
+ return 0.0F;
581
+ }
582
+ float ax = getX(0);
583
+ float ay = getY(0);
584
+ float area = 0.0F;
585
+ for (int i = 1; i < (getNumPoints() - 1); i++) {
586
+ float bx = getX(i);
587
+ float by = getY(i);
588
+ float cx = getX(i + 1);
589
+ float cy = getY(i + 1);
590
+ float tarea = ((cx - bx) * (ay - by)) - ((ax - bx) * (cy - by));
591
+ area += tarea;
592
+ }
593
+ area = 0.5F * Math.abs(area);
594
+ return area;
595
+ }
596
+
597
+ /**
598
+ * Use this method to draw the polygon.
599
+ *
600
+ * @eexample drawPolygon
601
+ * @param g PGraphics, the graphics object on which to draw the polygon
602
+ * @related draw ( )
603
+ */
604
+ @Override
605
+ public void draw(PGraphics g) {
606
+ int numContours = countContours();
607
+ if (numContours != 0) {
608
+ if (isIn(g)) {
609
+ if (!RG.ignoreStyles) {
610
+ saveContext(g);
611
+ setContext(g);
612
+ }
613
+
614
+ // Check whether to draw the fill or not
615
+ if (g.fill) {
616
+ // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
617
+ // NOTE: there's currently no way of drawing the outline of a mesh, since no information is kept about what vertices are at the edge
618
+
619
+ // Save the information about the current stroke color and turn off
620
+ boolean stroking = g.stroke;
621
+ g.noStroke();
622
+
623
+ // Save smoothing state and turn off
624
+ // boolean smoothing = g.smooth;
625
+ try {
626
+
627
+ g.noSmooth();
628
+
629
+ } catch (Exception e) {
630
+ }
631
+
632
+ RMesh tempMesh = this.toMesh();
633
+ tempMesh.draw(g);
634
+
635
+ // Restore the old stroke color
636
+ if (stroking) {
637
+ g.stroke(g.strokeColor);
638
+ }
639
+
640
+ }
641
+
642
+ // Check whether to draw the stroke or not
643
+ if (g.stroke) {
644
+ for (int i = 0; i < numContours; i++) {
645
+ contours[i].draw(g);
646
+ }
647
+ }
648
+
649
+ if (!RG.ignoreStyles) {
650
+ restoreContext(g);
651
+ }
652
+ }
653
+ }
654
+ }
655
+
656
+ /**
657
+ *
658
+ * @param g
659
+ */
660
+ @Override
661
+ public void draw(PApplet g) {
662
+ int numContours = countContours();
663
+ if (numContours != 0) {
664
+ if (isIn(g)) {
665
+ if (!RG.ignoreStyles) {
666
+ saveContext(g);
667
+ setContext(g);
668
+ }
669
+
670
+ // Check whether to draw the fill or not
671
+ if (g.g.fill) {
672
+ // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
673
+ // NOTE: there's currently no way of drawing the outline of a mesh, since no information is kept about what vertices are at the edge
674
+
675
+ // Save the information about the current stroke color and turn off
676
+ boolean stroking = g.g.stroke;
677
+ g.noStroke();
678
+
679
+ RMesh tempMesh = this.toMesh();
680
+ if (tempMesh != null) {
681
+ tempMesh.draw(g);
682
+ }
683
+
684
+ // Restore the old stroke color
685
+ if (stroking) {
686
+ g.stroke(g.g.strokeColor);
687
+ }
688
+
689
+ }
690
+
691
+ // Check whether to draws the stroke or not
692
+ if (g.g.stroke) {
693
+ for (int i = 0; i < numContours; i++) {
694
+ contours[i].draw(g);
695
+ }
696
+ }
697
+
698
+ if (!RG.ignoreStyles) {
699
+ restoreContext(g);
700
+ }
701
+ }
702
+ }
703
+ }
704
+
705
+ /**
706
+ * Use this method to get the intersection of this polygon with the polygon
707
+ * passed in as a parameter.
708
+ *
709
+ * @eexample intersection
710
+ * @param p RPolygon, the polygon with which to perform the intersection
711
+ * @return RPolygon, the intersection of the two polygons
712
+ * @related union ( )
713
+ * @related xor ( )
714
+ * @related diff ( )
715
+ */
716
+ public RPolygon intersection(RPolygon p) {
717
+ RPolygon res = RClip.intersection(p, this);
718
+ res.setStyle(this.getStyle());
719
+ return res;
720
+ }
721
+
722
+ /**
723
+ * Use this method to get the union of this polygon with the polygon passed
724
+ * in as a parameter.
725
+ *
726
+ * @eexample union
727
+ * @param p RPolygon, the polygon with which to perform the union
728
+ * @return RPolygon, the union of the two polygons
729
+ * @related intersection ( )
730
+ * @related xor ( )
731
+ * @related diff ( )
732
+ */
733
+ public RPolygon union(RPolygon p) {
734
+ RPolygon res = RClip.union(p, this);
735
+ res.setStyle(this.getStyle());
736
+ return res;
737
+ }
738
+
739
+ /**
740
+ * Use this method to get the xor of this polygon with the polygon passed in
741
+ * as a parameter.
742
+ *
743
+ * @eexample xor
744
+ * @param p RPolygon, the polygon with which to perform the xor
745
+ * @return RPolygon, the xor of the two polygons
746
+ * @related union ( )
747
+ * @related intersection ( )
748
+ * @related diff ( )
749
+ */
750
+ public RPolygon xor(RPolygon p) {
751
+ RPolygon res = RClip.xor(p, this);
752
+ res.setStyle(this.getStyle());
753
+ return res;
754
+ }
755
+
756
+ /**
757
+ * Use this method to get the difference between this polygon and the
758
+ * polygon passed in as a parameter.
759
+ *
760
+ * @eexample diff
761
+ * @param p RPolygon, the polygon with which to perform the difference
762
+ * @return RPolygon, the difference of the two polygons
763
+ * @related union ( )
764
+ * @related xor ( )
765
+ * @related intersection ( )
766
+ */
767
+ public RPolygon diff(RPolygon p) {
768
+ RPolygon res = RClip.diff(this, p);
769
+ res.setStyle(this.getStyle());
770
+ return res;
771
+ }
772
+
773
+ /**
774
+ * Use this method to get a rebuilt version of a given polygon by removing
775
+ * extra points and solving intersecting contours or holes.
776
+ *
777
+ * @eexample RPolygon_update
778
+ * @return RPolygon, the updated polygon
779
+ * @related diff ( )
780
+ * @related union ( )
781
+ * @related xor ( )
782
+ * @related intersection ( )
783
+ */
784
+ public RPolygon update() {
785
+ return RClip.update(this);
786
+ }
787
+
788
+ @Override
789
+ public RPoint getPoint(float t) {
790
+ PApplet.println("Feature not yet implemented for this class.");
791
+ return null;
792
+ }
793
+
794
+ /**
795
+ *
796
+ * @param t
797
+ * @return
798
+ */
799
+ @Override
800
+ public RPoint getTangent(float t) {
801
+ PApplet.println("Feature not yet implemented for this class.");
802
+ return null;
803
+ }
804
+
805
+ /**
806
+ *
807
+ * @return
808
+ */
809
+ @Override
810
+ public RPoint[] getTangents() {
811
+ PApplet.println("Feature not yet implemented for this class.");
812
+ return null;
813
+ }
814
+
815
+ /**
816
+ *
817
+ * @return
818
+ */
819
+ @Override
820
+ public RPoint[][] getPointsInPaths() {
821
+ PApplet.println("Feature not yet implemented for this class.");
822
+ return null;
823
+ }
824
+
825
+ @Override
826
+ public RPoint[][] getHandlesInPaths() {
827
+ PApplet.println("Feature not yet implemented for this class.");
828
+ return null;
829
+ }
830
+
831
+ @Override
832
+ public RPoint[][] getTangentsInPaths() {
833
+ PApplet.println("Feature not yet implemented for this class.");
834
+ return null;
835
+ }
836
+
837
+ @Override
838
+ public boolean contains(RPoint p) {
839
+ PApplet.println("Feature not yet implemented for this class.");
840
+ return false;
841
+ }
842
+
843
+ /**
844
+ * Use this method to transform the polygon.
845
+ *
846
+ * @eexample RPolygon_transform
847
+ * @param m RMatrix, the matrix of the affine transformation to apply to the
848
+ * polygon
849
+ */
850
+ /*
851
+ public void transform(RMatrix m){
852
+ int numContours = countContours();
853
+ if(numContours!=0){
854
+ for(int i=0;i<numContours;i++){
855
+ contours[i].transform(m);
856
+ }
857
+ }
858
+ }
859
+ */
860
+ // ----------------------
861
+ // --- Private Methods ---
862
+ // ----------------------
863
+ /**
864
+ * Remove all of the points. Creates an empty polygon.
865
+ */
866
+ protected void clear() {
867
+ this.contours = null;
868
+ }
869
+
870
+ /**
871
+ * Add a point to the first inner polygon.
872
+ *
873
+ * @param x
874
+ * @param y
875
+ */
876
+ protected void add(float x, float y) {
877
+ if (contours == null) {
878
+ this.append(new RContour());
879
+ }
880
+ this.contours[0].append(new RPoint(x, y));
881
+ }
882
+
883
+ /**
884
+ * Add a point to the first inner polygon.
885
+ *
886
+ * @param p
887
+ */
888
+ protected void add(RPoint p) {
889
+ if (contours == null) {
890
+ this.append(new RContour());
891
+ }
892
+ this.contours[0].append(p);
893
+ }
894
+
895
+ /**
896
+ * Add an inner polygon to this polygon - assumes that adding polygon does
897
+ * not have any inner polygons.
898
+ *
899
+ * @param p
900
+ */
901
+ protected void add(RPolygon p) {
902
+ /*if (this.contours.length > 0 && this.isHole){
903
+ throw new IllegalStateException("Cannot add polys to something designated as a hole.");
904
+ }*/
905
+ RContour c = new RContour();
906
+ for (int i = 0; i < p.getNumPoints(); i++) {
907
+ c.addPoint(p.getX(i), p.getY(i));
908
+ }
909
+ this.append(c);
910
+ }
911
+
912
+ /**
913
+ * Add an inner polygon to this polygon - assumes that adding polygon does
914
+ * not have any inner polygons.
915
+ *
916
+ * @param c
917
+ */
918
+ protected void add(RContour c) {
919
+ /*if (this.contours.length > 0 && this.isHole){
920
+ throw new IllegalStateException("Cannot add polys to something designated as a hole.");
921
+ }*/
922
+ this.append(c);
923
+ }
924
+
925
+ /**
926
+ * Return true if the polygon is empty
927
+ *
928
+ * @return
929
+ */
930
+ protected boolean isEmpty() {
931
+ return (this.contours == null);
932
+ }
933
+
934
+ /**
935
+ * Returns the bounding box of the polygon.
936
+ *
937
+ * @return
938
+ */
939
+ protected RRectangle getBBox() {
940
+ if (this.contours == null) {
941
+ return new RRectangle();
942
+ } else if (this.contours.length == 1) {
943
+
944
+ float xmin = Float.MAX_VALUE;
945
+ float ymin = Float.MAX_VALUE;
946
+ float xmax = -Float.MAX_VALUE;
947
+ float ymax = -Float.MAX_VALUE;
948
+
949
+ if (this.contours[0].points == null) {
950
+ return new RRectangle();
951
+ }
952
+
953
+ for (RPoint point : this.contours[0].points) {
954
+ float x = point.getX();
955
+ float y = point.getY();
956
+ if (x < xmin) {
957
+ xmin = x;
958
+ }
959
+ if (x > xmax) {
960
+ xmax = x;
961
+ }
962
+ if (y < ymin) {
963
+ ymin = y;
964
+ }
965
+ if (y > ymax) {
966
+ ymax = y;
967
+ }
968
+ }
969
+
970
+ return new RRectangle(xmin, ymin, (xmax - xmin), (ymax - ymin));
971
+ } else {
972
+ throw new UnsupportedOperationException("getBounds not supported on complex poly.");
973
+ }
974
+ }
975
+
976
+ /**
977
+ * Returns the polygon at this index.
978
+ *
979
+ * @param polyIndex
980
+ * @return
981
+ */
982
+ protected RPolygon getInnerPoly(int polyIndex) {
983
+ return new RPolygon(this.contours[polyIndex]);
984
+ }
985
+
986
+ /**
987
+ * Returns the number of inner polygons - inner polygons are assumed to
988
+ * return one here.
989
+ *
990
+ * @return
991
+ */
992
+ protected int getNumInnerPoly() {
993
+ if (this.contours == null) {
994
+ return 0;
995
+ }
996
+ return this.contours.length;
997
+ }
998
+
999
+ /**
1000
+ * Return the number points of the first inner polygon
1001
+ *
1002
+ * @return
1003
+ */
1004
+ protected int getNumPoints() {
1005
+ if (this.contours == null) {
1006
+ return 0;
1007
+ }
1008
+ if (this.contours[0].points == null) {
1009
+ return 0;
1010
+ }
1011
+ return this.contours[0].points.length;
1012
+ }
1013
+
1014
+ /**
1015
+ * Return the X value of the point at the index in the first inner polygon
1016
+ *
1017
+ * @param index
1018
+ * @return
1019
+ */
1020
+ protected float getX(int index) {
1021
+ if (this.contours == null) {
1022
+ return 0;
1023
+ }
1024
+ return this.contours[0].points[index].x;
1025
+ }
1026
+
1027
+ /**
1028
+ * Return the Y value of the point at the index in the first inner polygon
1029
+ *
1030
+ * @param index
1031
+ * @return
1032
+ */
1033
+ protected float getY(int index) {
1034
+ if (this.contours == null) {
1035
+ return 0;
1036
+ }
1037
+ return this.contours[0].points[index].y;
1038
+ }
1039
+
1040
+ /**
1041
+ * Return true if this polygon is a hole. Holes are assumed to be inner
1042
+ * polygons of a more complex polygon.
1043
+ *
1044
+ * @return
1045
+ * @throws IllegalStateException if called on a complex polygon.
1046
+ */
1047
+ public boolean isHole() {
1048
+ if (this.contours == null || this.contours.length > 1) {
1049
+ throw new IllegalStateException("Cannot call on a poly made up of more than one poly.");
1050
+ }
1051
+ return this.contours[0].isHole;
1052
+ }
1053
+
1054
+ /**
1055
+ * Set whether or not this polygon is a hole. Cannot be called on a complex
1056
+ * polygon.
1057
+ *
1058
+ * @param isHole
1059
+ * @throws IllegalStateException if called on a complex polygon.
1060
+ */
1061
+ protected void setIsHole(boolean isHole) {
1062
+ if (this.contours == null || this.contours.length > 1) {
1063
+ throw new IllegalStateException("Cannot call on a poly made up of more than one poly.");
1064
+ }
1065
+ this.contours[0].isHole = isHole;
1066
+ }
1067
+
1068
+ /**
1069
+ * Return true if the given inner polygon is contributing to the set
1070
+ * operation. This method should NOT be used outside the Clip algorithm.
1071
+ *
1072
+ * @param polyIndex
1073
+ * @return
1074
+ */
1075
+ protected boolean isContributing(int polyIndex) {
1076
+ return this.contours[polyIndex].isContributing;
1077
+ }
1078
+
1079
+ /**
1080
+ * Set whether or not this inner polygon is constributing to the set
1081
+ * operation. This method should NOT be used outside the Clip algorithm.
1082
+ *
1083
+ * @param polyIndex
1084
+ * @param contributes
1085
+ */
1086
+ protected void setContributing(int polyIndex, boolean contributes) {
1087
+ /*
1088
+ if( this.contours.length != 1 )
1089
+ {
1090
+ throw new IllegalStateException( "Only applies to polys of size 1" );
1091
+ }
1092
+ */
1093
+ this.contours[polyIndex].isContributing = contributes;
1094
+ }
1095
+
1096
+ private void append(RContour nextcontour) {
1097
+ RContour[] newcontours;
1098
+ if (contours == null) {
1099
+ newcontours = new RContour[1];
1100
+ newcontours[0] = nextcontour;
1101
+ currentContour = 0;
1102
+ } else {
1103
+ newcontours = new RContour[this.contours.length + 1];
1104
+ System.arraycopy(this.contours, 0, newcontours, 0, this.contours.length);
1105
+ newcontours[this.contours.length] = nextcontour;
1106
+ currentContour++;
1107
+ }
1108
+ this.contours = newcontours;
1109
+ }
1110
+ }