geomerative 0.1.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }