geomerative 1.1.0-java → 2.0.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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.mvn/extensions.xml +1 -1
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -1
  5. data/CHANGELOG.md +3 -0
  6. data/COPYING.md +1 -1
  7. data/README.md +0 -1
  8. data/Rakefile +2 -15
  9. data/docs/_includes/header.html +6 -6
  10. data/docs/_includes/icon-github.svg +3 -1
  11. data/docs/_includes/icon-twitter.svg +3 -1
  12. data/docs/_includes/navigation.html +18 -18
  13. data/docs/_sass/_base.scss +79 -79
  14. data/docs/_sass/_layout.scss +137 -137
  15. data/docs/_sass/_syntax-highlighting.scss +64 -64
  16. data/docs/index.html +18 -18
  17. data/examples/data/bot1.svg +1 -1
  18. data/examples/data/lion.svg +156 -156
  19. data/examples/data/ruby.svg +1 -1
  20. data/geomerative.gemspec +1 -2
  21. data/lib/geomerative/version.rb +1 -1
  22. data/mvnw +234 -0
  23. data/mvnw.cmd +145 -0
  24. data/pom.rb +14 -13
  25. data/pom.xml +14 -13
  26. data/src/geomerative/FastRClip.java +2149 -2156
  27. data/src/geomerative/RClip.java +2237 -2539
  28. data/src/geomerative/RClosest.java +33 -31
  29. data/src/geomerative/RCommand.java +1750 -1758
  30. data/src/geomerative/RContour.java +290 -292
  31. data/src/geomerative/RFont.java +277 -246
  32. data/src/geomerative/RG.java +722 -727
  33. data/src/geomerative/RGeomElem.java +967 -960
  34. data/src/geomerative/RGroup.java +508 -467
  35. data/src/geomerative/RMatrix.java +304 -289
  36. data/src/geomerative/RMesh.java +241 -229
  37. data/src/geomerative/RPath.java +924 -925
  38. data/src/geomerative/RPoint.java +391 -391
  39. data/src/geomerative/RPolygon.java +998 -988
  40. data/src/geomerative/RRectangle.java +43 -52
  41. data/src/geomerative/RSVG.java +480 -516
  42. data/src/geomerative/RShape.java +1767 -1777
  43. data/src/geomerative/RStrip.java +173 -176
  44. data/src/geomerative/RStyle.java +197 -194
  45. data/src/org/apache/batik/svggen/font/Font.java +141 -142
  46. data/src/org/apache/batik/svggen/font/Glyph.java +102 -71
  47. data/src/org/apache/batik/svggen/font/Point.java +12 -12
  48. data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +14 -12
  49. data/src/org/apache/batik/svggen/font/table/ClassDef.java +12 -12
  50. data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +27 -24
  51. data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +20 -17
  52. data/src/org/apache/batik/svggen/font/table/CmapFormat.java +43 -43
  53. data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +33 -26
  54. data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +25 -20
  55. data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +106 -96
  56. data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +36 -32
  57. data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +69 -49
  58. data/src/org/apache/batik/svggen/font/table/CmapTable.java +50 -50
  59. data/src/org/apache/batik/svggen/font/table/Coverage.java +19 -19
  60. data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +30 -27
  61. data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +26 -24
  62. data/src/org/apache/batik/svggen/font/table/CvtTable.java +16 -16
  63. data/src/org/apache/batik/svggen/font/table/Device.java +32 -32
  64. data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +39 -39
  65. data/src/org/apache/batik/svggen/font/table/Feature.java +26 -23
  66. data/src/org/apache/batik/svggen/font/table/FeatureList.java +37 -35
  67. data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +22 -22
  68. data/src/org/apache/batik/svggen/font/table/FeatureTags.java +4 -3
  69. data/src/org/apache/batik/svggen/font/table/FpgmTable.java +9 -9
  70. data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +134 -132
  71. data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +123 -122
  72. data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +44 -44
  73. data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +110 -109
  74. data/src/org/apache/batik/svggen/font/table/GlyfTable.java +46 -46
  75. data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +25 -13
  76. data/src/org/apache/batik/svggen/font/table/GposTable.java +26 -23
  77. data/src/org/apache/batik/svggen/font/table/GsubTable.java +85 -82
  78. data/src/org/apache/batik/svggen/font/table/HeadTable.java +131 -131
  79. data/src/org/apache/batik/svggen/font/table/HheaTable.java +80 -80
  80. data/src/org/apache/batik/svggen/font/table/HmtxTable.java +50 -49
  81. data/src/org/apache/batik/svggen/font/table/KernSubtable.java +29 -27
  82. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +35 -32
  83. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +28 -26
  84. data/src/org/apache/batik/svggen/font/table/KernTable.java +36 -31
  85. data/src/org/apache/batik/svggen/font/table/KerningPair.java +27 -23
  86. data/src/org/apache/batik/svggen/font/table/LangSys.java +28 -26
  87. data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +22 -22
  88. data/src/org/apache/batik/svggen/font/table/Ligature.java +24 -24
  89. data/src/org/apache/batik/svggen/font/table/LigatureSet.java +24 -24
  90. data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +9 -9
  91. data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +30 -30
  92. data/src/org/apache/batik/svggen/font/table/LocaTable.java +37 -37
  93. data/src/org/apache/batik/svggen/font/table/Lookup.java +41 -40
  94. data/src/org/apache/batik/svggen/font/table/LookupList.java +34 -34
  95. data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +7 -5
  96. data/src/org/apache/batik/svggen/font/table/MaxpTable.java +96 -96
  97. data/src/org/apache/batik/svggen/font/table/NameRecord.java +64 -65
  98. data/src/org/apache/batik/svggen/font/table/NameTable.java +33 -33
  99. data/src/org/apache/batik/svggen/font/table/Os2Table.java +196 -196
  100. data/src/org/apache/batik/svggen/font/table/Panose.java +14 -12
  101. data/src/org/apache/batik/svggen/font/table/PostTable.java +338 -338
  102. data/src/org/apache/batik/svggen/font/table/PrepTable.java +9 -9
  103. data/src/org/apache/batik/svggen/font/table/Program.java +15 -15
  104. data/src/org/apache/batik/svggen/font/table/RangeRecord.java +26 -25
  105. data/src/org/apache/batik/svggen/font/table/Script.java +38 -38
  106. data/src/org/apache/batik/svggen/font/table/ScriptList.java +42 -42
  107. data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +22 -22
  108. data/src/org/apache/batik/svggen/font/table/ScriptTags.java +2 -1
  109. data/src/org/apache/batik/svggen/font/table/SingleSubst.java +15 -16
  110. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +33 -33
  111. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +32 -32
  112. data/src/org/apache/batik/svggen/font/table/Table.java +171 -170
  113. data/src/org/apache/batik/svggen/font/table/TableDirectory.java +55 -55
  114. data/src/org/apache/batik/svggen/font/table/TableFactory.java +92 -93
  115. metadata +10 -11
  116. data/.travis.yml +0 -9
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
3
3
  *
4
- This file is part of Geomerative.
4
+ * This file is part of Geomerative.
5
5
  *
6
6
  * Geomerative is free software: you can redistribute it and/or modify it under
7
7
  * the terms of the GNU General Public License as published by the Free Software
@@ -26,839 +26,836 @@ import processing.core.*;
26
26
  * interface allows us to perform binary operations (difference, xor, union and
27
27
  * intersection) on polygons.
28
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
29
+ RPolygon
30
+ * Geometry
31
+ * RContour
32
+ * createCircle ( )
33
+ * createRing ( )
34
+ * createStar ( )
35
+ * diff ( )
36
+ * xor ( )
37
+ * union ( )
38
+ * intersection ( )
39
+
40
40
  */
41
41
  public class RPolygon extends RGeomElem {
42
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
- }
43
+ /**
44
+ *
45
+ */
46
+ public int type = RGeomElem.POLYGON;
47
+ public static int defaultDetail = 50;
139
48
 
140
- static public RPolygon createCircle(float radius) {
141
- return createCircle(0, 0, radius, defaultDetail);
49
+ /**
50
+ * Array of RContour objects holding the contours of the polygon.
51
+ *
52
+ contours
53
+ * RContour
54
+ * countContours ( )
55
+ * 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
+ createPolygon
67
+ * @param p the object of which to make a copy
68
+ */
69
+ public RPolygon(RPolygon p) {
70
+ if (p == null) {
71
+ return;
142
72
  }
143
73
 
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;
74
+ for (int i = 0; i < p.countContours(); i++) {
75
+ this.append(new RContour(p.contours[i]));
162
76
  }
77
+ type = RGeomElem.POLYGON;
163
78
 
164
- static public RPolygon createRectangle(float w, float h) {
165
- return createRectangle(0, 0, w, h);
166
- }
79
+ setStyle(p);
80
+ }
167
81
 
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
- );
82
+ /**
83
+ * Create a new polygon given an array of points.
84
+ *
85
+ 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
+ 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
+ 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
+ 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
+ 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
+ RGroup_getCentroid
247
+ * @return RPo the centroid point of the element
248
+ * getBounds ( )
249
+ * 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();
192
261
  }
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);
262
+ }
263
+ return bestCentroid;
198
264
  }
265
+ return null;
266
+ }
199
267
 
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;
268
+ /**
269
+ * Use this method to count the number of contours in the polygon.
270
+ *
271
+ countContours
272
+ * @return int the number contours in the polygon
273
+ * addContour ( )
274
+ */
275
+ public int countContours() {
276
+ if (this.contours == null) {
277
+ return 0;
229
278
  }
230
279
 
231
- static public RPolygon createRing(float radiusBig, float radiusSmall, int detail) {
232
- return createRing(0, 0, radiusBig, radiusSmall, detail);
233
- }
280
+ return this.contours.length;
281
+ }
234
282
 
235
- static public RPolygon createRing(float x, float y, float radiusBig, float radiusSmall) {
236
- return createRing(x, y, radiusBig, radiusSmall, defaultDetail);
283
+ /**
284
+ * Add a new contour to the polygon.
285
+ *
286
+ addContour
287
+ * @param c the contour to be added
288
+ * 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
+ addContour
298
+ * 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
+ addContour
308
+ * @param points the points of the new contour to be added
309
+ * 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
+ addContour
320
+ * 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
+ addPoint
330
+ * @param p the point to be added
331
+ * addContour ( )
332
+ * 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
+ 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
+ * addContour ( )
348
+ * 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
+ addPoint
361
+ * @param indContour the index of the contour to which the point will be added
362
+ * @param p the point to be added
363
+ * addContour ( )
364
+ * setCurrent ( )
365
+ */
366
+ public void addPoint(int indContour, RPoint p) {
367
+ if (contours == null) {
368
+ this.append(new RContour());
369
+ }
370
+ this.contours[indContour].append(p);
371
+ }
372
+
373
+ /**
374
+ * Add a new point to the selected contour.
375
+ *
376
+ addPoint
377
+ * @param indContour the index of the contour to which the point will be added
378
+ * @param x the x coordinate of the point to be added
379
+ * @param y the y coordinate of the point to be added
380
+ * addContour ( )
381
+ * setCurrent ( )
382
+ */
383
+ public void addPoint(int indContour, float x, float y) {
384
+ if (contours == null) {
385
+ this.append(new RContour());
386
+ }
387
+ this.contours[indContour].append(new RPoint(x, y));
388
+ }
389
+
390
+ public void addClose() {
391
+ if (contours == null) {
392
+ return;
393
+ }
394
+
395
+ contours[contours.length - 1].addClose();
396
+ }
397
+
398
+ /**
399
+ * Use this method to create a new mesh from a given polygon.
400
+ *
401
+ toMesh
402
+ * @return RMesh, the mesh made of tristrips resulting of a tesselation of the
403
+ * polygon
404
+ * draw ( )
405
+ */
406
+ @Override
407
+ public RMesh toMesh() {
408
+ if (contours == null) {
409
+ return new RMesh();
410
+ }
411
+
412
+ RMesh mesh = RClip.polygonToMesh(this);
413
+ if (mesh == null) {
414
+ return null;
415
+ }
416
+
417
+ mesh.setStyle(this);
418
+ return mesh;
419
+ }
420
+
421
+ @Override
422
+ public void print() {
423
+ System.out.println("polygon: ");
424
+ for (int i = 0; i < countContours(); i++) {
425
+ System.out.println("--- contour " + i + " ---");
426
+ contours[i].print();
427
+ System.out.println("---------------");
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Removes contours with less than 3 points. These are contours that are open.
433
+ * Since close polygons have points[0] == points[-1] and two more points to
434
+ * form a triangle at least. This is useful to avoid the clipping algorithm
435
+ * from breaking.
436
+ *
437
+ * @return
438
+ *
439
+ */
440
+ protected RPolygon removeOpenContours() {
441
+ RPolygon clean = new RPolygon();
442
+ for (int i = 0; i < countContours(); i++) {
443
+ if (contours[i].countPoints() > 3) {
444
+ clean.addContour(contours[i]);
445
+ }
237
446
  }
447
+ clean.setStyle(this);
448
+ return clean;
449
+ }
450
+
451
+ /**
452
+ * @return
453
+ */
454
+ @Override
455
+ public RPolygon toPolygon() {
456
+ return new RPolygon(this);
457
+ }
458
+
459
+ /**
460
+ * @return
461
+ */
462
+ @Override
463
+ public RShape toShape() {
464
+ int numContours = countContours();
238
465
 
239
- static public RPolygon createRing(float radiusBig, float radiusSmall) {
240
- return createRing(0, 0, radiusBig, radiusSmall, defaultDetail);
241
- }
466
+ RShape result = new RShape();
467
+ for (int i = 0; i < numContours; i++) {
468
+ RPoint[] newpoints = this.contours[i].getHandles();
242
469
 
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
- }
470
+ if (newpoints != null) {
471
+ result.addMoveTo(newpoints[0]);
267
472
 
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;
473
+ for (int j = 1; j < newpoints.length; j++) {
474
+ result.addLineTo(newpoints[j]);
278
475
  }
279
476
 
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());
477
+ if (contours[i].closed) {
478
+ result.addClose();
337
479
  }
338
- this.contours[currentContour].append(p);
339
- }
340
480
 
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));
481
+ result.paths[i].setStyle(contours[i]);
482
+ }
355
483
  }
356
484
 
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
- }
485
+ result.setStyle(this);
486
+ return result;
487
+ }
373
488
 
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());
489
+ /**
490
+ * Use this to return the points of the polygon. It returns the points in the
491
+ * way of an array of RPoint.
492
+ *
493
+ RPolygon_getHandles
494
+ * @return RPoint[], the points returned in an array.
495
+ *
496
+ */
497
+ @Override
498
+ public RPoint[] getHandles() {
499
+ int numContours = countContours();
500
+ if (numContours == 0) {
501
+ return null;
502
+ }
503
+
504
+ RPoint[] result = null;
505
+ RPoint[] newresult = null;
506
+ for (int i = 0; i < numContours; i++) {
507
+ RPoint[] newPoints = contours[i].getHandles();
508
+ if (newPoints != null) {
509
+ if (result == null) {
510
+ result = new RPoint[newPoints.length];
511
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
512
+ } else {
513
+ newresult = new RPoint[result.length + newPoints.length];
514
+ System.arraycopy(result, 0, newresult, 0, result.length);
515
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
516
+ result = newresult;
388
517
  }
389
- this.contours[indContour].append(new RPoint(x, y));
518
+ }
390
519
  }
520
+ return result;
521
+ }
391
522
 
392
- public void addClose() {
393
- if (contours == null) {
394
- return;
523
+ /**
524
+ * Use this to return the points of the polygon. It returns the points in the
525
+ * way of an array of RPoint.
526
+ *
527
+ RPolygon_getPoints
528
+ * @return RPoint[], the points returned in an array.
529
+ *
530
+ */
531
+ @Override
532
+ public RPoint[] getPoints() {
533
+ int numContours = countContours();
534
+ if (numContours == 0) {
535
+ return null;
536
+ }
537
+
538
+ RPoint[] result = null;
539
+ RPoint[] newresult = null;
540
+ for (int i = 0; i < numContours; i++) {
541
+ RPoint[] newPoints = contours[i].getPoints();
542
+ if (newPoints != null) {
543
+ if (result == null) {
544
+ result = new RPoint[newPoints.length];
545
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
546
+ } else {
547
+ newresult = new RPoint[result.length + newPoints.length];
548
+ System.arraycopy(result, 0, newresult, 0, result.length);
549
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
550
+ result = newresult;
395
551
  }
396
-
397
- contours[contours.length - 1].addClose();
552
+ }
398
553
  }
554
+ return result;
555
+ }
399
556
 
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;
557
+ /**
558
+ * Use this method to get the type of element this is.
559
+ *
560
+ RPolygon_getType
561
+ * @return int, will allways return RGeomElem.POLYGON
562
+ */
563
+ @Override
564
+ public int getType() {
565
+ return type;
566
+ }
567
+
568
+ /**
569
+ * Use this method to get the area covered by the polygon.
570
+ *
571
+ getArea
572
+ * @return float, the area covered by the polygon
573
+ * draw ( )
574
+ */
575
+ @Override
576
+ public float getArea() {
577
+ if (getNumPoints() < 3) {
578
+ return 0.0F;
579
+ }
580
+ float ax = getX(0);
581
+ float ay = getY(0);
582
+ float area = 0.0F;
583
+ for (int i = 1; i < (getNumPoints() - 1); i++) {
584
+ float bx = getX(i);
585
+ float by = getY(i);
586
+ float cx = getX(i + 1);
587
+ float cy = getY(i + 1);
588
+ float tarea = ((cx - bx) * (ay - by)) - ((ax - bx) * (cy - by));
589
+ area += tarea;
590
+ }
591
+ area = 0.5F * Math.abs(area);
592
+ return area;
593
+ }
594
+
595
+ /**
596
+ * Use this method to draw the polygon.
597
+ *
598
+ drawPolygon
599
+ * @param g PGraphics, the graphics object on which to draw the polygon
600
+ * draw ( )
601
+ */
602
+ @Override
603
+ public void draw(PGraphics g) {
604
+ int numContours = countContours();
605
+ if (numContours != 0) {
606
+ if (isIn(g)) {
607
+ if (!RG.ignoreStyles) {
608
+ saveContext(g);
609
+ setContext(g);
417
610
  }
418
611
 
419
- mesh.setStyle(this);
420
- return mesh;
421
- }
612
+ // Check whether to draw the fill or not
613
+ if (g.fill) {
614
+ // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
615
+ // 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
422
616
 
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
- }
617
+ // Save the information about the current stroke color and turn off
618
+ boolean stroking = g.stroke;
619
+ g.noStroke();
432
620
 
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]);
621
+ // Save smoothing state and turn off
622
+ int smoothing = g.smooth;
623
+ try {
624
+ if (smoothing > 0) {
625
+ g.noSmooth();
447
626
  }
448
- }
449
- clean.setStyle(this);
450
- return clean;
451
- }
452
-
453
- /**
454
- * @return
455
- * @invisible
456
- */
457
- @Override
458
- public RPolygon toPolygon() {
459
- return new RPolygon(this);
460
- }
461
-
462
- /**
463
- * @return
464
- * @invisible
465
- */
466
- @Override
467
- public RShape toShape() {
468
- int numContours = countContours();
469
-
470
- RShape result = new RShape();
471
- for (int i = 0; i < numContours; i++) {
472
- RPoint[] newpoints = this.contours[i].getHandles();
473
-
474
- if (newpoints != null) {
475
- result.addMoveTo(newpoints[0]);
627
+ } catch (Exception e) {
628
+ }
476
629
 
477
- for (int j = 1; j < newpoints.length; j++) {
478
- result.addLineTo(newpoints[j]);
479
- }
630
+ RMesh tempMesh = this.toMesh();
631
+ tempMesh.draw(g);
480
632
 
481
- if (contours[i].closed) {
482
- result.addClose();
483
- }
633
+ // Restore the old stroke color
634
+ if (stroking) {
635
+ g.stroke(g.strokeColor);
636
+ }
484
637
 
485
- result.paths[i].setStyle(contours[i]);
638
+ // Restore the old smoothing state
639
+ try {
640
+ if (smoothing > 0) {
641
+ g.smooth();
486
642
  }
643
+ } catch (Exception e) {
644
+ }
487
645
  }
488
646
 
489
- result.setStyle(this);
490
- return result;
491
- }
492
-
493
- /**
494
- * Use this to return the points of the polygon. It returns the points in
495
- * the way of an array of RPoint.
496
- *
497
- * @eexample RPolygon_getHandles
498
- * @return RPoint[], the points returned in an array.
499
- *
500
- */
501
- @Override
502
- public RPoint[] getHandles() {
503
- int numContours = countContours();
504
- if (numContours == 0) {
505
- return null;
647
+ // Check whether to draw the stroke or not
648
+ if (g.stroke) {
649
+ for (int i = 0; i < numContours; i++) {
650
+ contours[i].draw(g);
651
+ }
506
652
  }
507
653
 
508
- RPoint[] result = null;
509
- RPoint[] newresult = null;
510
- for (int i = 0; i < numContours; i++) {
511
- RPoint[] newPoints = contours[i].getHandles();
512
- if (newPoints != null) {
513
- if (result == null) {
514
- result = new RPoint[newPoints.length];
515
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
516
- } else {
517
- newresult = new RPoint[result.length + newPoints.length];
518
- System.arraycopy(result, 0, newresult, 0, result.length);
519
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
520
- result = newresult;
521
- }
522
- }
654
+ if (!RG.ignoreStyles) {
655
+ restoreContext(g);
523
656
  }
524
- return result;
657
+ }
525
658
  }
659
+ }
526
660
 
527
- /**
528
- * Use this to return the points of the polygon. It returns the points in
529
- * the way of an array of RPoint.
530
- *
531
- * @eexample RPolygon_getPoints
532
- * @return RPoint[], the points returned in an array.
533
- *
534
- */
535
- @Override
536
- public RPoint[] getPoints() {
537
- int numContours = countContours();
538
- if (numContours == 0) {
539
- return null;
540
- }
541
-
542
- RPoint[] result = null;
543
- RPoint[] newresult = null;
544
- for (int i = 0; i < numContours; i++) {
545
- RPoint[] newPoints = contours[i].getPoints();
546
- if (newPoints != null) {
547
- if (result == null) {
548
- result = new RPoint[newPoints.length];
549
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
550
- } else {
551
- newresult = new RPoint[result.length + newPoints.length];
552
- System.arraycopy(result, 0, newresult, 0, result.length);
553
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
554
- result = newresult;
555
- }
556
- }
661
+ @Override
662
+ public void draw(PApplet g) {
663
+ int numContours = countContours();
664
+ if (numContours != 0) {
665
+ if (isIn(g)) {
666
+ if (!RG.ignoreStyles) {
667
+ saveContext(g);
668
+ setContext(g);
557
669
  }
558
- return result;
559
- }
560
670
 
561
- /**
562
- * Use this method to get the type of element this is.
563
- *
564
- * @eexample RPolygon_getType
565
- * @return int, will allways return RGeomElem.POLYGON
566
- */
567
- public int getType() {
568
- return type;
569
- }
671
+ // Check whether to draw the fill or not
672
+ if (g.g.fill) {
673
+ // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
674
+ // 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
570
675
 
571
- /**
572
- * Use this method to get the area covered by the polygon.
573
- *
574
- * @eexample getArea
575
- * @return float, the area covered by the polygon
576
- * @related draw ( )
577
- */
578
- @Override
579
- public float getArea() {
580
- if (getNumPoints() < 3) {
581
- return 0.0F;
582
- }
583
- float ax = getX(0);
584
- float ay = getY(0);
585
- float area = 0.0F;
586
- for (int i = 1; i < (getNumPoints() - 1); i++) {
587
- float bx = getX(i);
588
- float by = getY(i);
589
- float cx = getX(i + 1);
590
- float cy = getY(i + 1);
591
- float tarea = ((cx - bx) * (ay - by)) - ((ax - bx) * (cy - by));
592
- area += tarea;
593
- }
594
- area = 0.5F * Math.abs(area);
595
- return area;
596
- }
676
+ // Save the information about the current stroke color and turn off
677
+ boolean stroking = g.g.stroke;
678
+ g.noStroke();
597
679
 
598
- /**
599
- * Use this method to draw the polygon.
600
- *
601
- * @eexample drawPolygon
602
- * @param g PGraphics, the graphics object on which to draw the polygon
603
- * @related draw ( )
604
- */
605
- @Override
606
- public void draw(PGraphics g) {
607
- int numContours = countContours();
608
- if (numContours != 0) {
609
- if (isIn(g)) {
610
- if (!RG.ignoreStyles) {
611
- saveContext(g);
612
- setContext(g);
613
- }
614
-
615
- // Check whether to draw the fill or not
616
- if (g.fill) {
617
- // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
618
- // 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
619
-
620
- // Save the information about the current stroke color and turn off
621
- boolean stroking = g.stroke;
622
- g.noStroke();
623
-
624
- // Save smoothing state and turn off
625
- int smoothing = g.smooth;
626
- try {
627
- if (smoothing > 0) {
628
- g.noSmooth();
629
- }
630
- } catch (Exception e) {
631
- }
632
-
633
- RMesh tempMesh = this.toMesh();
634
- tempMesh.draw(g);
635
-
636
- // Restore the old stroke color
637
- if (stroking) {
638
- g.stroke(g.strokeColor);
639
- }
640
-
641
- // Restore the old smoothing state
642
- try {
643
- if (smoothing > 0) {
644
- g.smooth();
645
- }
646
- } catch (Exception e) {
647
- }
648
- }
649
-
650
- // Check whether to draw the stroke or not
651
- if (g.stroke) {
652
- for (int i = 0; i < numContours; i++) {
653
- contours[i].draw(g);
654
- }
655
- }
656
-
657
- if (!RG.ignoreStyles) {
658
- restoreContext(g);
659
- }
680
+ // Save smoothing state and turn off
681
+ int smoothing = g.g.smooth;
682
+ try {
683
+ if (smoothing > 0) {
684
+ g.noSmooth();
660
685
  }
661
- }
662
- }
663
-
664
- @Override
665
- public void draw(PApplet g) {
666
- int numContours = countContours();
667
- if (numContours != 0) {
668
- if (isIn(g)) {
669
- if (!RG.ignoreStyles) {
670
- saveContext(g);
671
- setContext(g);
672
- }
673
-
674
- // Check whether to draw the fill or not
675
- if (g.g.fill) {
676
- // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
677
- // 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
678
-
679
- // Save the information about the current stroke color and turn off
680
- boolean stroking = g.g.stroke;
681
- g.noStroke();
682
-
683
- // Save smoothing state and turn off
684
- int smoothing = g.g.smooth;
685
- try {
686
- if (smoothing > 0) {
687
- g.noSmooth();
688
- }
689
- } catch (Exception e) {
690
- }
691
-
692
- RMesh tempMesh = this.toMesh();
693
- if (tempMesh != null) {
694
- tempMesh.draw(g);
695
- }
696
-
697
- // Restore the old stroke color
698
- if (stroking) {
699
- g.stroke(g.g.strokeColor);
700
- }
701
-
702
- // Restore the old smoothing state
703
- try {
704
- if (smoothing > 0) {
705
- g.smooth();
706
- }
707
- } catch (Exception e) {
708
- }
709
- }
710
-
711
- // Check whether to draws the stroke or not
712
- if (g.g.stroke) {
713
- for (int i = 0; i < numContours; i++) {
714
- contours[i].draw(g);
715
- }
716
- }
717
-
718
- if (!RG.ignoreStyles) {
719
- restoreContext(g);
720
- }
686
+ } catch (Exception e) {
687
+ }
688
+
689
+ RMesh tempMesh = this.toMesh();
690
+ if (tempMesh != null) {
691
+ tempMesh.draw(g);
692
+ }
693
+
694
+ // Restore the old stroke color
695
+ if (stroking) {
696
+ g.stroke(g.g.strokeColor);
697
+ }
698
+
699
+ // Restore the old smoothing state
700
+ try {
701
+ if (smoothing > 0) {
702
+ g.smooth();
721
703
  }
704
+ } catch (Exception e) {
705
+ }
722
706
  }
723
- }
724
-
725
- /**
726
- * Use this method to get the intersection of this polygon with the polygon
727
- * passed in as a parameter.
728
- *
729
- * @eexample intersection
730
- * @param p RPolygon, the polygon with which to perform the intersection
731
- * @return RPolygon, the intersection of the two polygons
732
- * @related union ( )
733
- * @related xor ( )
734
- * @related diff ( )
735
- */
736
- public RPolygon intersection(RPolygon p) {
737
- RPolygon res = RClip.intersection(p, this);
738
- res.setStyle(this.getStyle());
739
- return res;
740
- }
741
-
742
- /**
743
- * Use this method to get the union of this polygon with the polygon passed
744
- * in as a parameter.
745
- *
746
- * @eexample union
747
- * @param p RPolygon, the polygon with which to perform the union
748
- * @return RPolygon, the union of the two polygons
749
- * @related intersection ( )
750
- * @related xor ( )
751
- * @related diff ( )
752
- */
753
- public RPolygon union(RPolygon p) {
754
- RPolygon res = RClip.union(p, this);
755
- res.setStyle(this.getStyle());
756
- return res;
757
- }
758
-
759
- /**
760
- * Use this method to get the xor of this polygon with the polygon passed in
761
- * as a parameter.
762
- *
763
- * @eexample xor
764
- * @param p RPolygon, the polygon with which to perform the xor
765
- * @return RPolygon, the xor of the two polygons
766
- * @related union ( )
767
- * @related intersection ( )
768
- * @related diff ( )
769
- */
770
- public RPolygon xor(RPolygon p) {
771
- RPolygon res = RClip.xor(p, this);
772
- res.setStyle(this.getStyle());
773
- return res;
774
- }
775
-
776
- /**
777
- * Use this method to get the difference between this polygon and the
778
- * polygon passed in as a parameter.
779
- *
780
- * @eexample diff
781
- * @param p RPolygon, the polygon with which to perform the difference
782
- * @return RPolygon, the difference of the two polygons
783
- * @related union ( )
784
- * @related xor ( )
785
- * @related intersection ( )
786
- */
787
- public RPolygon diff(RPolygon p) {
788
- RPolygon res = RClip.diff(this, p);
789
- res.setStyle(this.getStyle());
790
- return res;
791
- }
792
-
793
- /**
794
- * Use this method to get a rebuilt version of a given polygon by removing
795
- * extra points and solving intersecting contours or holes.
796
- *
797
- * @eexample RPolygon_update
798
- * @return RPolygon, the updated polygon
799
- * @related diff ( )
800
- * @related union ( )
801
- * @related xor ( )
802
- * @related intersection ( )
803
- */
804
- public RPolygon update() {
805
- return RClip.update(this);
806
- }
807
707
 
808
- @Override
809
- public RPoint getPoint(float t) {
810
- PApplet.println("Feature not yet implemented for this class.");
811
- return null;
812
- }
813
-
814
- @Override
815
- public RPoint getTangent(float t) {
816
- PApplet.println("Feature not yet implemented for this class.");
817
- return null;
818
- }
819
-
820
- /**
821
- *
822
- * @return
823
- */
824
- @Override
825
- public RPoint[] getTangents() {
826
- PApplet.println("Feature not yet implemented for this class.");
827
- return null;
828
- }
829
-
830
- @Override
831
- public RPoint[][] getPointsInPaths() {
832
- PApplet.println("Feature not yet implemented for this class.");
833
- return null;
834
- }
835
-
836
- @Override
837
- public RPoint[][] getHandlesInPaths() {
838
- PApplet.println("Feature not yet implemented for this class.");
839
- return null;
840
- }
841
-
842
- @Override
843
- public RPoint[][] getTangentsInPaths() {
844
- PApplet.println("Feature not yet implemented for this class.");
845
- return null;
846
- }
708
+ // Check whether to draws the stroke or not
709
+ if (g.g.stroke) {
710
+ for (int i = 0; i < numContours; i++) {
711
+ contours[i].draw(g);
712
+ }
713
+ }
847
714
 
848
- @Override
849
- public boolean contains(RPoint p) {
850
- PApplet.println("Feature not yet implemented for this class.");
851
- return false;
715
+ if (!RG.ignoreStyles) {
716
+ restoreContext(g);
717
+ }
718
+ }
852
719
  }
720
+ }
853
721
 
854
- /**
855
- * Use this method to transform the polygon.
856
- *
857
- * @eexample RPolygon_transform
858
- * @param m RMatrix, the matrix of the affine transformation to apply to the
859
- * polygon
860
- */
861
- /*
722
+ /**
723
+ * Use this method to get the intersection of this polygon with the polygon
724
+ * passed in as a parameter.
725
+ *
726
+ intersection
727
+ * @param p RPolygon, the polygon with which to perform the intersection
728
+ * @return RPolygon, the intersection of the two polygons
729
+ * union ( )
730
+ * xor ( )
731
+ * diff ( )
732
+ */
733
+ public RPolygon intersection(RPolygon p) {
734
+ RPolygon res = RClip.intersection(p, this);
735
+ res.setStyle(this.getStyle());
736
+ return res;
737
+ }
738
+
739
+ /**
740
+ * Use this method to get the union of this polygon with the polygon passed in
741
+ * as a parameter.
742
+ *
743
+ union
744
+ * @param p RPolygon, the polygon with which to perform the union
745
+ * @return RPolygon, the union of the two polygons
746
+ * intersection ( )
747
+ * xor ( )
748
+ * diff ( )
749
+ */
750
+ public RPolygon union(RPolygon p) {
751
+ RPolygon res = RClip.union(p, this);
752
+ res.setStyle(this.getStyle());
753
+ return res;
754
+ }
755
+
756
+ /**
757
+ * Use this method to get the xor of this polygon with the polygon passed in
758
+ * as a parameter.
759
+ *
760
+ xor
761
+ * @param p RPolygon, the polygon with which to perform the xor
762
+ * @return RPolygon, the xor of the two polygons
763
+ * union ( )
764
+ * intersection ( )
765
+ * diff ( )
766
+ */
767
+ public RPolygon xor(RPolygon p) {
768
+ RPolygon res = RClip.xor(p, this);
769
+ res.setStyle(this.getStyle());
770
+ return res;
771
+ }
772
+
773
+ /**
774
+ * Use this method to get the difference between this polygon and the polygon
775
+ * passed in as a parameter.
776
+ *
777
+ diff
778
+ * @param p RPolygon, the polygon with which to perform the difference
779
+ * @return RPolygon, the difference of the two polygons
780
+ * union ( )
781
+ * xor ( )
782
+ * intersection ( )
783
+ */
784
+ public RPolygon diff(RPolygon p) {
785
+ RPolygon res = RClip.diff(this, p);
786
+ res.setStyle(this.getStyle());
787
+ return res;
788
+ }
789
+
790
+ /**
791
+ * Use this method to get a rebuilt version of a given polygon by removing
792
+ * extra points and solving intersecting contours or holes.
793
+ *
794
+ RPolygon_update
795
+ * @return RPolygon, the updated polygon
796
+ * diff ( )
797
+ * union ( )
798
+ * xor ( )
799
+ * intersection ( )
800
+ */
801
+ public RPolygon update() {
802
+ return RClip.update(this);
803
+ }
804
+
805
+ @Override
806
+ public RPoint getPoint(float t) {
807
+ PApplet.println("Feature not yet implemented for this class.");
808
+ return null;
809
+ }
810
+
811
+ @Override
812
+ public RPoint getTangent(float t) {
813
+ PApplet.println("Feature not yet implemented for this class.");
814
+ return null;
815
+ }
816
+
817
+ /**
818
+ *
819
+ * @return
820
+ */
821
+ @Override
822
+ public RPoint[] getTangents() {
823
+ PApplet.println("Feature not yet implemented for this class.");
824
+ return null;
825
+ }
826
+
827
+ @Override
828
+ public RPoint[][] getPointsInPaths() {
829
+ PApplet.println("Feature not yet implemented for this class.");
830
+ return null;
831
+ }
832
+
833
+ @Override
834
+ public RPoint[][] getHandlesInPaths() {
835
+ PApplet.println("Feature not yet implemented for this class.");
836
+ return null;
837
+ }
838
+
839
+ @Override
840
+ public RPoint[][] getTangentsInPaths() {
841
+ PApplet.println("Feature not yet implemented for this class.");
842
+ return null;
843
+ }
844
+
845
+ @Override
846
+ public boolean contains(RPoint p) {
847
+ PApplet.println("Feature not yet implemented for this class.");
848
+ return false;
849
+ }
850
+
851
+ /**
852
+ * Use this method to transform the polygon.
853
+ *
854
+ RPolygon_transform
855
+ * @param m RMatrix, the matrix of the affine transformation to apply to the
856
+ * polygon
857
+ */
858
+ /*
862
859
  public void transform(RMatrix m){
863
860
  int numContours = countContours();
864
861
  if(numContours!=0){
@@ -867,242 +864,255 @@ public class RPolygon extends RGeomElem {
867
864
  }
868
865
  }
869
866
  }
870
- */
871
- // ----------------------
872
- // --- Private Methods ---
873
- // ----------------------
874
- /**
875
- * Remove all of the points. Creates an empty polygon.
876
- */
877
- protected void clear() {
878
- this.contours = null;
879
- }
880
-
881
- /**
882
- * Add a point to the first inner polygon.
883
- * @param x
884
- * @param y
885
- */
886
- protected void add(float x, float y) {
887
- if (contours == null) {
888
- this.append(new RContour());
889
- }
890
- this.contours[0].append(new RPoint(x, y));
891
- }
892
-
893
- /**
894
- * Add a point to the first inner polygon.
895
- * @param p
896
- */
897
- protected void add(RPoint p) {
898
- if (contours == null) {
899
- this.append(new RContour());
900
- }
901
- this.contours[0].append(p);
902
- }
867
+ */
868
+ // ----------------------
869
+ // --- Private Methods ---
870
+ // ----------------------
871
+ /**
872
+ * Remove all of the points. Creates an empty polygon.
873
+ */
874
+ protected void clear() {
875
+ this.contours = null;
876
+ }
903
877
 
904
- /**
905
- * Add an inner polygon to this polygon - assumes that adding polygon does
906
- * not have any inner polygons.
907
- * @param p
908
- */
909
- protected void add(RPolygon p) {
910
- /*if (this.contours.length > 0 && this.isHole){
878
+ /**
879
+ * Add a point to the first inner polygon.
880
+ *
881
+ * @param x
882
+ * @param y
883
+ */
884
+ protected void add(float x, float y) {
885
+ if (contours == null) {
886
+ this.append(new RContour());
887
+ }
888
+ this.contours[0].append(new RPoint(x, y));
889
+ }
890
+
891
+ /**
892
+ * Add a point to the first inner polygon.
893
+ *
894
+ * @param p
895
+ */
896
+ protected void add(RPoint p) {
897
+ if (contours == null) {
898
+ this.append(new RContour());
899
+ }
900
+ this.contours[0].append(p);
901
+ }
902
+
903
+ /**
904
+ * Add an inner polygon to this polygon - assumes that adding polygon does not
905
+ * have any inner polygons.
906
+ *
907
+ * @param p
908
+ */
909
+ protected void add(RPolygon p) {
910
+ /*if (this.contours.length > 0 && this.isHole){
911
911
  throw new IllegalStateException("Cannot add polys to something designated as a hole.");
912
912
  }*/
913
- RContour c = new RContour();
914
- for (int i = 0; i < p.getNumPoints(); i++) {
915
- c.addPoint(p.getX(i), p.getY(i));
916
- }
917
- this.append(c);
913
+ RContour c = new RContour();
914
+ for (int i = 0; i < p.getNumPoints(); i++) {
915
+ c.addPoint(p.getX(i), p.getY(i));
918
916
  }
917
+ this.append(c);
918
+ }
919
919
 
920
- /**
921
- * Add an inner polygon to this polygon - assumes that adding polygon does
922
- * not have any inner polygons.
923
- * @param c
924
- */
925
- protected void add(RContour c) {
926
- /*if (this.contours.length > 0 && this.isHole){
920
+ /**
921
+ * Add an inner polygon to this polygon - assumes that adding polygon does not
922
+ * have any inner polygons.
923
+ *
924
+ * @param c
925
+ */
926
+ protected void add(RContour c) {
927
+ /*if (this.contours.length > 0 && this.isHole){
927
928
  throw new IllegalStateException("Cannot add polys to something designated as a hole.");
928
929
  }*/
929
- this.append(c);
930
- }
931
-
932
- /**
933
- * Return true if the polygon is empty
934
- * @return
935
- */
936
- protected boolean isEmpty() {
937
- return (this.contours == null);
938
- }
939
-
940
- /**
941
- * Returns the bounding box of the polygon.
942
- * @return
943
- */
944
- protected RRectangle getBBox() {
945
- if (this.contours == null) {
946
- return new RRectangle();
947
- } else if (this.contours.length == 1) {
948
-
949
- float xmin = Float.MAX_VALUE;
950
- float ymin = Float.MAX_VALUE;
951
- float xmax = -Float.MAX_VALUE;
952
- float ymax = -Float.MAX_VALUE;
953
-
954
- if (this.contours[0].points == null) {
955
- return new RRectangle();
956
- }
930
+ this.append(c);
931
+ }
957
932
 
958
- for (RPoint point : this.contours[0].points) {
959
- float x = point.getX();
960
- float y = point.getY();
961
- if (x < xmin) {
962
- xmin = x;
963
- }
964
- if (x > xmax) {
965
- xmax = x;
966
- }
967
- if (y < ymin) {
968
- ymin = y;
969
- }
970
- if (y > ymax) {
971
- ymax = y;
972
- }
973
- }
933
+ /**
934
+ * Return true if the polygon is empty
935
+ *
936
+ * @return
937
+ */
938
+ protected boolean isEmpty() {
939
+ return (this.contours == null);
940
+ }
941
+
942
+ /**
943
+ * Returns the bounding box of the polygon.
944
+ *
945
+ * @return
946
+ */
947
+ protected RRectangle getBBox() {
948
+ if (this.contours == null) {
949
+ return new RRectangle();
950
+ } else if (this.contours.length == 1) {
951
+
952
+ float xmin = Float.MAX_VALUE;
953
+ float ymin = Float.MAX_VALUE;
954
+ float xmax = -Float.MAX_VALUE;
955
+ float ymax = -Float.MAX_VALUE;
956
+
957
+ if (this.contours[0].points == null) {
958
+ return new RRectangle();
959
+ }
974
960
 
975
- return new RRectangle(xmin, ymin, (xmax - xmin), (ymax - ymin));
976
- } else {
977
- throw new UnsupportedOperationException("getBounds not supported on complex poly.");
961
+ for (RPoint point : this.contours[0].points) {
962
+ float x = point.getX();
963
+ float y = point.getY();
964
+ if (x < xmin) {
965
+ xmin = x;
978
966
  }
979
- }
980
-
981
- /**
982
- * Returns the polygon at this index.
983
- * @param polyIndex
984
- * @return
985
- */
986
- protected RPolygon getInnerPoly(int polyIndex) {
987
- return new RPolygon(this.contours[polyIndex]);
988
- }
989
-
990
- /**
991
- * Returns the number of inner polygons - inner polygons are assumed to
992
- * return one here.
993
- * @return
994
- */
995
- protected int getNumInnerPoly() {
996
- if (this.contours == null) {
997
- return 0;
967
+ if (x > xmax) {
968
+ xmax = x;
998
969
  }
999
- return this.contours.length;
1000
- }
1001
-
1002
- /**
1003
- * Return the number points of the first inner polygon
1004
- * @return
1005
- */
1006
- protected int getNumPoints() {
1007
- if (this.contours == null) {
1008
- return 0;
970
+ if (y < ymin) {
971
+ ymin = y;
1009
972
  }
1010
- if (this.contours[0].points == null) {
1011
- return 0;
973
+ if (y > ymax) {
974
+ ymax = y;
1012
975
  }
1013
- return this.contours[0].points.length;
1014
- }
976
+ }
1015
977
 
1016
- /**
1017
- * Return the X value of the point at the index in the first inner polygon
1018
- * @param index
1019
- * @return
1020
- */
1021
- protected float getX(int index) {
1022
- if (this.contours == null) {
1023
- return 0;
1024
- }
1025
- return this.contours[0].points[index].x;
978
+ return new RRectangle(xmin, ymin, (xmax - xmin), (ymax - ymin));
979
+ } else {
980
+ throw new UnsupportedOperationException("getBounds not supported on complex poly.");
1026
981
  }
982
+ }
1027
983
 
1028
- /**
1029
- * Return the Y value of the point at the index in the first inner polygon
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;
984
+ /**
985
+ * Returns the polygon at this index.
986
+ *
987
+ * @param polyIndex
988
+ * @return
989
+ */
990
+ protected RPolygon getInnerPoly(int polyIndex) {
991
+ return new RPolygon(this.contours[polyIndex]);
992
+ }
993
+
994
+ /**
995
+ * Returns the number of inner polygons - inner polygons are assumed to return
996
+ * one here.
997
+ *
998
+ * @return
999
+ */
1000
+ protected int getNumInnerPoly() {
1001
+ if (this.contours == null) {
1002
+ return 0;
1038
1003
  }
1004
+ return this.contours.length;
1005
+ }
1039
1006
 
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;
1007
+ /**
1008
+ * Return the number points of the first inner polygon
1009
+ *
1010
+ * @return
1011
+ */
1012
+ protected int getNumPoints() {
1013
+ if (this.contours == null) {
1014
+ return 0;
1052
1015
  }
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;
1016
+ if (this.contours[0].points == null) {
1017
+ return 0;
1066
1018
  }
1019
+ return this.contours[0].points.length;
1020
+ }
1067
1021
 
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
- * @param polyIndex
1072
- * @return
1073
- */
1074
- protected boolean isContributing(int polyIndex) {
1075
- return this.contours[polyIndex].isContributing;
1076
- }
1077
-
1078
- /**
1079
- * Set whether or not this inner polygon is constributing to the set
1080
- * operation. This method should NOT be used outside the Clip algorithm.
1081
- * @param polyIndex
1082
- * @param contributes
1083
- */
1084
- protected void setContributing(int polyIndex, boolean contributes) {
1085
- /*
1022
+ /**
1023
+ * Return the X value of the point at the index in the first inner polygon
1024
+ *
1025
+ * @param index
1026
+ * @return
1027
+ */
1028
+ protected float getX(int index) {
1029
+ if (this.contours == null) {
1030
+ return 0;
1031
+ }
1032
+ return this.contours[0].points[index].x;
1033
+ }
1034
+
1035
+ /**
1036
+ * Return the Y value of the point at the index in the first inner polygon
1037
+ *
1038
+ * @param index
1039
+ * @return
1040
+ */
1041
+ protected float getY(int index) {
1042
+ if (this.contours == null) {
1043
+ return 0;
1044
+ }
1045
+ return this.contours[0].points[index].y;
1046
+ }
1047
+
1048
+ /**
1049
+ * Return true if this polygon is a hole. Holes are assumed to be inner
1050
+ * polygons of a more complex polygon.
1051
+ *
1052
+ * @return
1053
+ * @throws IllegalStateException if called on a complex polygon.
1054
+ */
1055
+ public boolean isHole() {
1056
+ if (this.contours == null || this.contours.length > 1) {
1057
+ throw new IllegalStateException("Cannot call on a poly made up of more than one poly.");
1058
+ }
1059
+ return this.contours[0].isHole;
1060
+ }
1061
+
1062
+ /**
1063
+ * Set whether or not this polygon is a hole. Cannot be called on a complex
1064
+ * polygon.
1065
+ *
1066
+ * @param isHole
1067
+ * @throws IllegalStateException if called on a complex polygon.
1068
+ */
1069
+ protected void setIsHole(boolean isHole) {
1070
+ if (this.contours == null || this.contours.length > 1) {
1071
+ throw new IllegalStateException("Cannot call on a poly made up of more than one poly.");
1072
+ }
1073
+ this.contours[0].isHole = isHole;
1074
+ }
1075
+
1076
+ /**
1077
+ * Return true if the given inner polygon is contributing to the set
1078
+ * operation. This method should NOT be used outside the Clip algorithm.
1079
+ *
1080
+ * @param polyIndex
1081
+ * @return
1082
+ */
1083
+ protected boolean isContributing(int polyIndex) {
1084
+ return this.contours[polyIndex].isContributing;
1085
+ }
1086
+
1087
+ /**
1088
+ * Set whether or not this inner polygon is constributing to the set
1089
+ * operation. This method should NOT be used outside the Clip algorithm.
1090
+ *
1091
+ * @param polyIndex
1092
+ * @param contributes
1093
+ */
1094
+ protected void setContributing(int polyIndex, boolean contributes) {
1095
+ /*
1086
1096
  if( this.contours.length != 1 )
1087
1097
  {
1088
1098
  throw new IllegalStateException( "Only applies to polys of size 1" );
1089
1099
  }
1090
- */
1091
- this.contours[polyIndex].isContributing = contributes;
1092
- }
1093
-
1094
- private void append(RContour nextcontour) {
1095
- RContour[] newcontours;
1096
- if (contours == null) {
1097
- newcontours = new RContour[1];
1098
- newcontours[0] = nextcontour;
1099
- currentContour = 0;
1100
- } else {
1101
- newcontours = new RContour[this.contours.length + 1];
1102
- System.arraycopy(this.contours, 0, newcontours, 0, this.contours.length);
1103
- newcontours[this.contours.length] = nextcontour;
1104
- currentContour++;
1105
- }
1106
- this.contours = newcontours;
1107
- }
1100
+ */
1101
+ this.contours[polyIndex].isContributing = contributes;
1102
+ }
1103
+
1104
+ private void append(RContour nextcontour) {
1105
+ RContour[] newcontours;
1106
+ if (contours == null) {
1107
+ newcontours = new RContour[1];
1108
+ newcontours[0] = nextcontour;
1109
+ currentContour = 0;
1110
+ } else {
1111
+ newcontours = new RContour[this.contours.length + 1];
1112
+ System.arraycopy(this.contours, 0, newcontours, 0, this.contours.length);
1113
+ newcontours[this.contours.length] = nextcontour;
1114
+ currentContour++;
1115
+ }
1116
+ this.contours = newcontours;
1117
+ }
1108
1118
  }