geomerative 1.1.0-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -18,1663 +18,1653 @@
18
18
  */
19
19
  package geomerative;
20
20
 
21
-
22
-
23
21
  import processing.core.PApplet;
24
22
  import processing.core.PConstants;
25
23
  import processing.core.PGraphics;
26
24
 
27
-
28
25
  /**
29
26
  * RShape is a reduced interface for creating, holding and drawing complex
30
27
  * shapes. Shapes are groups of one or more paths (RPath). Shapes can be
31
28
  * selfintersecting and can contain holes. This interface also allows you to
32
29
  * transform shapes into polygons by segmenting the curves forming the shape.
33
30
  *
34
- * @eexample RShape
35
- * @usage Geometry
36
- * @related RPath
31
+ RShape
32
+ * Geometry
33
+ * RPath
37
34
  */
38
35
  public class RShape extends RGeomElem {
39
36
 
40
- /**
41
- * @invisible
42
- */
43
- public int type = RGeomElem.SHAPE;
44
-
45
- /**
46
- * Array of RPath objects holding the paths of the polygon.
47
- *
48
- * @eexample paths
49
- * @related RPath
50
- * @related countPaths ( )
51
- * @related addPath ( )
52
- */
53
- public RPath[] paths = null;
54
- protected int currentPath = 0;
55
-
56
- public RShape[] children = null;
57
- protected int currentChild;
58
-
59
- // ----------------------
60
- // --- Public Methods ---
61
- // ----------------------
62
- /**
63
- * Use this method to create a new empty shape.
64
- *
65
- * @eexample RShape
66
- */
67
- public RShape() {
68
- type = RGeomElem.SHAPE;
69
- }
70
-
71
- public RShape(RPath newpath) {
72
- this.append(newpath);
73
- type = RGeomElem.SHAPE;
74
- }
75
-
76
- public RShape(RPath[] newpaths) {
77
- this.paths = newpaths;
78
- type = RGeomElem.SHAPE;
79
- }
80
-
81
- public RShape(RPoint[][] points) {
82
- if (points == null) {
83
- return;
84
- }
85
-
86
- RPath[] newpaths = new RPath[points.length];
87
- for (int i = 0; i < points.length; i++) {
88
- newpaths[i] = new RPath(points[i]);
89
- }
90
-
91
- this.paths = newpaths;
92
- type = RGeomElem.SHAPE;
93
- }
94
-
95
- public RShape(RShape s) {
96
- for (int i = 0; i < s.countPaths(); i++) {
97
- this.append(new RPath(s.paths[i]));
98
- }
99
-
100
- for (int i = 0; i < s.countChildren(); i++) {
101
- this.appendChild(new RShape(s.children[i]));
102
- }
103
-
104
- type = RGeomElem.SHAPE;
105
-
106
- setStyle(s);
107
- }
108
-
109
- /**
110
- * Use this method to create a new line.
111
- *
112
- * @eexample createRing
113
- * @param x1 x coordinate of the first point of the line
114
- * @param y1 y coordinate of the first point of the line
115
- * @param x2 x coordinate of the last point of the line
116
- * @param y2 y coordinate of the last point of the line
117
- * @return RShape, the ring polygon newly created
118
- */
119
- static public RShape createLine(float x1, float y1, float x2, float y2) {
120
- RShape line = new RShape();
121
- RPath path = new RPath();
122
-
123
- RCommand lineCommand = new RCommand(x1, y1, x2, y2);
124
- path.addCommand(lineCommand);
125
- line.addPath(path);
126
-
127
- return line;
128
- }
129
-
130
- /**
131
- * Use this method to create a new ring polygon.
132
- *
133
- * @eexample createRing
134
- * @param x x coordinate of the center of the shape
135
- * @param y y coordinate of the center of the shape
136
- * @param widthBig the outer width of the ring polygon
137
- * @param widthSmall the inner width of the ring polygon
138
- * @return RShape, the ring polygon newly created
139
- */
140
- static public RShape createRing(float x, float y, float widthBig, float widthSmall) {
141
- RShape ring = new RShape();
142
- RShape outer = RShape.createCircle(x, y, widthBig);
143
- RShape inner = RShape.createCircle(x, y, -widthSmall);
144
-
145
- ring.addPath(outer.paths[0]);
146
- ring.addPath(inner.paths[0]);
147
-
148
- return ring;
149
- }
150
-
151
- /**
152
- * Use this method to create a new starform polygon.
153
- *
154
- * @param x
155
- * @param y
156
- * @eexample createStar
157
- * @param widthBig the outer width of the star polygon
158
- * @param widthSmall the inner width of the star polygon
159
- * @param spikes the amount of spikes on the star polygon
160
- * @return RShape, the starform polygon newly created
161
- */
162
- static public RShape createStar(float x, float y, float widthBig, float widthSmall, int spikes) {
163
- float radiusBig = widthBig / 2F;
164
- float radiusSmall = widthSmall / 2F;
165
- RShape star = new RShape();
166
- star.addMoveTo(x - radiusBig, y);
167
- star.addLineTo(x - (float) (radiusSmall * Math.cos(Math.PI / spikes)), y - (float) (radiusSmall * Math.sin(Math.PI / spikes)));
168
-
169
- for (int i = 2; i < 2 * spikes; i += 2) {
170
- star.addLineTo(x - (float) (radiusBig * Math.cos(Math.PI * i / spikes)), y - (float) (radiusBig * Math.sin(Math.PI * i / spikes)));
171
- star.addLineTo(x - (float) (radiusSmall * Math.cos(Math.PI * (i + 1) / spikes)), y - (float) (radiusSmall * Math.sin(Math.PI * (i + 1) / spikes)));
172
- }
173
-
174
- star.addClose();
175
-
176
- return star;
177
- }
178
-
179
- /**
180
- * Use this method to create a new circle shape.
181
- *
182
- * @eexample createRectangle
183
- * @param x the x position of the rectangle
184
- * @param y the y position of the rectangle
185
- * @param w the width of the rectangle
186
- * @param h the height of the rectangle
187
- * @return RShape, the rectangular shape just created
188
- */
189
- static public RShape createRectangle(float x, float y, float w, float h) {
190
- RShape rect = new RShape();
191
- rect.addMoveTo(x, y);
192
- rect.addLineTo(x + w, y);
193
- rect.addLineTo(x + w, y + h);
194
- rect.addLineTo(x, y + h);
195
- rect.addLineTo(x, y);
196
- return rect;
197
- }
198
-
199
- /**
200
- * Use this method to create a new elliptical shape.
201
- *
202
- * @eexample createEllipse
203
- * @param x the x position of the ellipse
204
- * @param y the y position of the ellipse
205
- * @param w the width of the ellipse
206
- * @param h the height of the ellipse
207
- * @return RShape, the elliptical shape just created
208
- */
209
- static public RShape createEllipse(float x, float y, float w, float h) {
210
- float rx = w / 2F;
211
- float ry = h / 2F;
212
- RPoint center = new RPoint(x, y);
213
- RShape circle = new RShape();
214
- float kx = (((8F / (float) Math.sqrt(2F)) - 4F) / 3F) * rx;
215
- float ky = (((8F / (float) Math.sqrt(2F)) - 4F) / 3F) * ry;
216
- circle.addMoveTo(center.x, center.y - ry);
217
- circle.addBezierTo(center.x + kx, center.y - ry, center.x + rx, center.y - ky, center.x + rx, center.y);
218
- circle.addBezierTo(center.x + rx, center.y + ky, center.x + kx, center.y + ry, center.x, center.y + ry);
219
- circle.addBezierTo(center.x - kx, center.y + ry, center.x - rx, center.y + ky, center.x - rx, center.y);
220
- circle.addBezierTo(center.x - rx, center.y - ky, center.x - kx, center.y - ry, center.x, center.y - ry);
221
- circle.addClose();
222
- return circle;
223
- }
224
-
225
- static public RShape createCircle(float x, float y, float d) {
226
- return createEllipse(x, y, d, d);
227
- }
228
-
229
- /**
230
- *
231
- * Extracts a shape by its name. The shape is returned as an RShape object,
232
- * or null is returned if no shape with the name has been found.
233
- *
234
- * @param target
235
- * @return RShape or null, the target shape or null if not found
236
- *
237
- */
238
- public RShape getChild(String target) {
239
- if (this.name.equals(target)) {
240
- return this;
241
- }
242
-
243
- for (int i = 0; i < countChildren(); i++) {
244
- RShape shp = children[i].getChild(target);
245
- if (shp != null) {
246
- return shp;
247
- }
248
- }
249
-
250
- return null;
251
- }
252
-
253
- /**
254
- * Use this method to get the centroid of the element.
255
- *
256
- * @eexample RGroup_getCentroid
257
- * @return RPoint, the centroid point of the element
258
- * @related getBounds ( )
259
- * @related getCenter ( )
260
- */
261
- @Override
262
- public RPoint getCentroid() {
263
- RPoint bestCentroid = new RPoint();
264
- float bestArea = Float.NEGATIVE_INFINITY;
265
- if (paths != null) {
266
- for (RPath path : paths) {
267
- float area = Math.abs(path.getArea());
268
- if (area > bestArea) {
269
- bestArea = area;
270
- bestCentroid = path.getCentroid();
271
- }
272
- }
273
- return bestCentroid;
274
- }
275
- return null;
276
- }
37
+ /**
38
+ *
39
+ */
40
+ public int type = RGeomElem.SHAPE;
41
+
42
+ /**
43
+ * Array of RPath objects holding the paths of the polygon.
44
+ *
45
+ paths
46
+ * RPath
47
+ * countPaths ( )
48
+ * addPath ( )
49
+ */
50
+ public RPath[] paths = null;
51
+ protected int currentPath = 0;
52
+
53
+ public RShape[] children = null;
54
+ protected int currentChild;
55
+
56
+ // ----------------------
57
+ // --- Public Methods ---
58
+ // ----------------------
59
+ /**
60
+ * Use this method to create a new empty shape.
61
+ *
62
+ RShape
63
+ */
64
+ public RShape() {
65
+ type = RGeomElem.SHAPE;
66
+ }
67
+
68
+ public RShape(RPath newpath) {
69
+ this.append(newpath);
70
+ type = RGeomElem.SHAPE;
71
+ }
72
+
73
+ public RShape(RPath[] newpaths) {
74
+ this.paths = newpaths;
75
+ type = RGeomElem.SHAPE;
76
+ }
77
+
78
+ public RShape(RPoint[][] points) {
79
+ if (points == null) {
80
+ return;
81
+ }
82
+
83
+ RPath[] newpaths = new RPath[points.length];
84
+ for (int i = 0; i < points.length; i++) {
85
+ newpaths[i] = new RPath(points[i]);
86
+ }
87
+
88
+ this.paths = newpaths;
89
+ type = RGeomElem.SHAPE;
90
+ }
91
+
92
+ public RShape(RShape s) {
93
+ for (int i = 0; i < s.countPaths(); i++) {
94
+ this.append(new RPath(s.paths[i]));
95
+ }
96
+
97
+ for (int i = 0; i < s.countChildren(); i++) {
98
+ this.appendChild(new RShape(s.children[i]));
99
+ }
100
+
101
+ type = RGeomElem.SHAPE;
102
+
103
+ setStyle(s);
104
+ }
105
+
106
+ /**
107
+ * Use this method to create a new line.
108
+ *
109
+ createRing
110
+ * @param x1 x coordinate of the first point of the line
111
+ * @param y1 y coordinate of the first point of the line
112
+ * @param x2 x coordinate of the last point of the line
113
+ * @param y2 y coordinate of the last point of the line
114
+ * @return RShape, the ring polygon newly created
115
+ */
116
+ static public RShape createLine(float x1, float y1, float x2, float y2) {
117
+ RShape line = new RShape();
118
+ RPath path = new RPath();
119
+
120
+ RCommand lineCommand = new RCommand(x1, y1, x2, y2);
121
+ path.addCommand(lineCommand);
122
+ line.addPath(path);
123
+
124
+ return line;
125
+ }
126
+
127
+ /**
128
+ * Use this method to create a new ring polygon.
129
+ *
130
+ createRing
131
+ * @param x x coordinate of the center of the shape
132
+ * @param y y coordinate of the center of the shape
133
+ * @param widthBig the outer width of the ring polygon
134
+ * @param widthSmall the inner width of the ring polygon
135
+ * @return RShape, the ring polygon newly created
136
+ */
137
+ static public RShape createRing(float x, float y, float widthBig, float widthSmall) {
138
+ RShape ring = new RShape();
139
+ RShape outer = RShape.createCircle(x, y, widthBig);
140
+ RShape inner = RShape.createCircle(x, y, -widthSmall);
141
+
142
+ ring.addPath(outer.paths[0]);
143
+ ring.addPath(inner.paths[0]);
144
+
145
+ return ring;
146
+ }
147
+
148
+ /**
149
+ * Use this method to create a new starform polygon.
150
+ *
151
+ * @param x
152
+ * @param y
153
+ createStar
154
+ * @param widthBig the outer width of the star polygon
155
+ * @param widthSmall the inner width of the star polygon
156
+ * @param spikes the amount of spikes on the star polygon
157
+ * @return RShape, the starform polygon newly created
158
+ */
159
+ static public RShape createStar(float x, float y, float widthBig, float widthSmall, int spikes) {
160
+ float radiusBig = widthBig / 2F;
161
+ float radiusSmall = widthSmall / 2F;
162
+ RShape star = new RShape();
163
+ star.addMoveTo(x - radiusBig, y);
164
+ star.addLineTo(x - (float) (radiusSmall * Math.cos(Math.PI / spikes)), y - (float) (radiusSmall * Math.sin(Math.PI / spikes)));
165
+
166
+ for (int i = 2; i < 2 * spikes; i += 2) {
167
+ star.addLineTo(x - (float) (radiusBig * Math.cos(Math.PI * i / spikes)), y - (float) (radiusBig * Math.sin(Math.PI * i / spikes)));
168
+ star.addLineTo(x - (float) (radiusSmall * Math.cos(Math.PI * (i + 1) / spikes)), y - (float) (radiusSmall * Math.sin(Math.PI * (i + 1) / spikes)));
169
+ }
170
+
171
+ star.addClose();
172
+
173
+ return star;
174
+ }
175
+
176
+ /**
177
+ * Use this method to create a new circle shape.
178
+ *
179
+ createRectangle
180
+ * @param x the x position of the rectangle
181
+ * @param y the y position of the rectangle
182
+ * @param w the width of the rectangle
183
+ * @param h the height of the rectangle
184
+ * @return RShape, the rectangular shape just created
185
+ */
186
+ static public RShape createRectangle(float x, float y, float w, float h) {
187
+ RShape rect = new RShape();
188
+ rect.addMoveTo(x, y);
189
+ rect.addLineTo(x + w, y);
190
+ rect.addLineTo(x + w, y + h);
191
+ rect.addLineTo(x, y + h);
192
+ rect.addLineTo(x, y);
193
+ return rect;
194
+ }
195
+
196
+ /**
197
+ * Use this method to create a new elliptical shape.
198
+ *
199
+ createEllipse
200
+ * @param x the x position of the ellipse
201
+ * @param y the y position of the ellipse
202
+ * @param w the width of the ellipse
203
+ * @param h the height of the ellipse
204
+ * @return RShape, the elliptical shape just created
205
+ */
206
+ static public RShape createEllipse(float x, float y, float w, float h) {
207
+ float rx = w / 2F;
208
+ float ry = h / 2F;
209
+ RPoint center = new RPoint(x, y);
210
+ RShape circle = new RShape();
211
+ float kx = (((8F / (float) Math.sqrt(2F)) - 4F) / 3F) * rx;
212
+ float ky = (((8F / (float) Math.sqrt(2F)) - 4F) / 3F) * ry;
213
+ circle.addMoveTo(center.x, center.y - ry);
214
+ circle.addBezierTo(center.x + kx, center.y - ry, center.x + rx, center.y - ky, center.x + rx, center.y);
215
+ circle.addBezierTo(center.x + rx, center.y + ky, center.x + kx, center.y + ry, center.x, center.y + ry);
216
+ circle.addBezierTo(center.x - kx, center.y + ry, center.x - rx, center.y + ky, center.x - rx, center.y);
217
+ circle.addBezierTo(center.x - rx, center.y - ky, center.x - kx, center.y - ry, center.x, center.y - ry);
218
+ circle.addClose();
219
+ return circle;
220
+ }
221
+
222
+ static public RShape createCircle(float x, float y, float d) {
223
+ return createEllipse(x, y, d, d);
224
+ }
225
+
226
+ /**
227
+ *
228
+ * Extracts a shape by its name. The shape is returned as an RShape object, or
229
+ * null is returned if no shape with the name has been found.
230
+ *
231
+ * @param target
232
+ * @return RShape or null, the target shape or null if not found
233
+ *
234
+ */
235
+ public RShape getChild(String target) {
236
+ if (this.name.equals(target)) {
237
+ return this;
238
+ }
239
+
240
+ for (int i = 0; i < countChildren(); i++) {
241
+ RShape shp = children[i].getChild(target);
242
+ if (shp != null) {
243
+ return shp;
244
+ }
245
+ }
246
+
247
+ return null;
248
+ }
249
+
250
+ /**
251
+ * Use this method to get the centroid of the element.
252
+ *
253
+ RGroup_getCentroid
254
+ * @return RPoint, the centroid point of the element
255
+ * getBounds ( )
256
+ * getCenter ( )
257
+ */
258
+ @Override
259
+ public RPoint getCentroid() {
260
+ RPoint bestCentroid = new RPoint();
261
+ float bestArea = Float.NEGATIVE_INFINITY;
262
+ if (paths != null) {
263
+ for (RPath path : paths) {
264
+ float area = Math.abs(path.getArea());
265
+ if (area > bestArea) {
266
+ bestArea = area;
267
+ bestCentroid = path.getCentroid();
268
+ }
269
+ }
270
+ return bestCentroid;
271
+ }
272
+ return null;
273
+ }
274
+
275
+ /**
276
+ * Use this method to count the number of paths in the shape.
277
+ *
278
+ countPaths
279
+ * @return
280
+ * addPath ( )
281
+ */
282
+ public int countPaths() {
283
+ if (this.paths == null) {
284
+ return 0;
285
+ }
286
+
287
+ return this.paths.length;
288
+ }
289
+
290
+ public int countChildren() {
291
+ if (this.children == null) {
292
+ return 0;
293
+ }
294
+
295
+ return this.children.length;
296
+ }
297
+
298
+ /**
299
+ * Use this method to add a new shape. The paths of the shape we are adding
300
+ * will simply be added to the current shape.
301
+ *
302
+ addShape
303
+ * @param s RShape, the shape to be added.
304
+ * setPath ( )
305
+ * addMoveTo ( )
306
+ *
307
+ */
308
+ public void addShape(RShape s) {
309
+ for (int i = 0; i < s.countPaths(); i++) {
310
+ this.append(s.paths[i]);
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Use this method to create a new path. The first point of the new path will
316
+ * be set to (0,0). Use addMoveTo ( ) in order to add a new path with a
317
+ * different first point.
318
+ *
319
+ addPath
320
+ * @param s the path to be added.
321
+ * setPath ( )
322
+ * addMoveTo ( )
323
+ */
324
+ public void addPath(RPath s) {
325
+ this.append(s);
326
+ }
327
+
328
+ public void addPath() {
329
+ this.append(new RPath());
330
+ }
331
+
332
+ public void addChild() {
333
+ this.appendChild(new RShape());
334
+ }
335
+
336
+ public void addChild(RShape s) {
337
+ this.appendChild(s);
338
+ }
339
+
340
+ /**
341
+ * Use this method to set the current path.
342
+ *
343
+ * @param indPath
344
+ setPath
345
+ * addMoveTo ( )
346
+ * addLineTo ( )
347
+ * addQuadTo ( )
348
+ * addBezierTo ( )
349
+ * addPath ( )
350
+ */
351
+ public void setPath(int indPath) {
352
+ this.currentPath = indPath;
353
+ }
354
+
355
+ /**
356
+ * Use this method to add a new moveTo command to the shape. The command
357
+ * moveTo acts different to normal commands, in order to make a better analogy
358
+ * to its borthers classes Polygon and Mesh. MoveTo creates a new path in the
359
+ * shape. It's similar to adding a new contour to a polygon.
360
+ *
361
+ addMoveTo
362
+ * @param endx the x coordinate of the first point for the new path.
363
+ * @param endy the y coordinate of the first point for the new path.
364
+ * addLineTo ( )
365
+ * addQuadTo ( )
366
+ * addBezierTo ( )
367
+ * addPath ( )
368
+ * setPath ( )
369
+ */
370
+ public void addMoveTo(float endx, float endy) {
371
+ if (paths == null) {
372
+ this.append(new RPath(endx, endy));
373
+ } else if (paths[currentPath].countCommands() == 0) {
374
+ this.paths[currentPath].lastPoint = new RPoint(endx, endy);
375
+ } else {
376
+ this.append(new RPath(endx, endy));
377
+ }
378
+ }
379
+
380
+ public void addMoveTo(RPoint p) {
381
+ addMoveTo(p.x, p.y);
382
+ }
383
+
384
+ /**
385
+ * Use this method to add a new lineTo command to the current path. This will
386
+ * add a line from the last point added to the point passed as argument.
387
+ *
388
+ addLineTo
389
+ * @param endx the x coordinate of the ending point of the line.
390
+ * @param endy the y coordinate of the ending point of the line.
391
+ * addMoveTo ( )
392
+ * addQuadTo ( )
393
+ * addBezierTo ( )
394
+ * addPath ( )
395
+ * setPath ( )
396
+ */
397
+ public void addLineTo(float endx, float endy) {
398
+ if (paths == null) {
399
+ this.append(new RPath());
400
+ }
401
+ this.paths[currentPath].addLineTo(endx, endy);
402
+ }
403
+
404
+ public void addLineTo(RPoint p) {
405
+ addLineTo(p.x, p.y);
406
+ }
407
+
408
+ /**
409
+ * Use this method to add a new quadTo command to the current path. This will
410
+ * add a quadratic bezier from the last point added with the control and
411
+ * ending points passed as arguments.
412
+ *
413
+ addQuadTo
414
+ * @param cp1x the x coordinate of the control point of the bezier.
415
+ * @param cp1y the y coordinate of the control point of the bezier.
416
+ * @param endx the x coordinate of the ending point of the bezier.
417
+ * @param endy the y coordinate of the ending point of the bezier.
418
+ * addMoveTo ( )
419
+ * addLineTo ( )
420
+ * addBezierTo ( )
421
+ * addPath ( )
422
+ * setPath ( )
423
+ */
424
+ public void addQuadTo(float cp1x, float cp1y, float endx, float endy) {
425
+ if (paths == null) {
426
+ this.append(new RPath());
427
+ }
428
+ this.paths[currentPath].addQuadTo(cp1x, cp1y, endx, endy);
429
+ }
430
+
431
+ public void addQuadTo(RPoint p1, RPoint p2) {
432
+ addQuadTo(p1.x, p1.y, p2.x, p2.y);
433
+ }
434
+
435
+ /**
436
+ * Use this method to add a new bezierTo command to the current path. This
437
+ * will add a cubic bezier from the last point added with the control and
438
+ * ending points passed as arguments.
439
+ *
440
+ addArcTo
441
+ * @param cp1x the x coordinate of the first control point of the bezier.
442
+ * @param cp1y the y coordinate of the first control point of the bezier.
443
+ * @param cp2x the x coordinate of the second control point of the bezier.
444
+ * @param cp2y the y coordinate of the second control point of the bezier.
445
+ * @param endx the x coordinate of the ending point of the bezier.
446
+ * @param endy the y coordinate of the ending point of the bezier.
447
+ * addMoveTo ( )
448
+ * addLineTo ( )
449
+ * addQuadTo ( )
450
+ * addPath ( )
451
+ * setPath ( )
452
+ */
453
+ public void addBezierTo(float cp1x, float cp1y, float cp2x, float cp2y, float endx, float endy) {
454
+ if (paths == null) {
455
+ this.append(new RPath());
456
+ }
457
+ this.paths[currentPath].addBezierTo(cp1x, cp1y, cp2x, cp2y, endx, endy);
458
+ }
459
+
460
+ public void addBezierTo(RPoint p1, RPoint p2, RPoint p3) {
461
+ addBezierTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
462
+ }
463
+
464
+ public void addClose() {
465
+ if (paths == null) {
466
+ this.append(new RPath());
467
+ }
468
+ this.paths[currentPath].addClose();
469
+ }
470
+
471
+ /**
472
+ * Use this method to create a new mesh from a given polygon.
473
+ *
474
+ toMesh
475
+ * @return RMesh, the mesh made of tristrips resulting of a tesselation of the
476
+ * polygonization followed by tesselation of the shape.
477
+ * draw ( )
478
+ */
479
+ @Override
480
+ public RMesh toMesh() {
481
+ return toPolygon().toMesh();
482
+ }
483
+
484
+ /**
485
+ * Use this method to create a new polygon from a given shape.
486
+ *
487
+ toPolygon
488
+ * @return RPolygon, the polygon resulting of the segmentation of the commands
489
+ * in each path.
490
+ * draw ( )
491
+ */
492
+ @Override
493
+ public RPolygon toPolygon() {
494
+ int numPnts = this.countPaths();
495
+
496
+ RPolygon poly = new RPolygon();
497
+
498
+ if (this.children != null) {
499
+ for (RShape children1 : this.children) {
500
+ RPolygon childPoly = children1.toPolygon();
501
+ for (RContour contour : childPoly.contours) {
502
+ poly.addContour(contour);
503
+ }
504
+ }
505
+ }
506
+
507
+ for (int i = 0; i < numPnts; i++) {
508
+ RPoint[] pnts = this.paths[i].getPoints();
509
+ RContour c = new RContour(pnts);
510
+ c.closed = this.paths[i].closed;
511
+ c.setStyle(this.paths[i]);
512
+ poly.addContour(c);
513
+ }
514
+
515
+ return poly;
516
+ }
517
+
518
+ public void polygonize() {
519
+ int numPaths = countPaths();
520
+
521
+ for (int i = 0; i < numPaths; i++) {
522
+ this.paths[i].polygonize();
523
+ }
524
+
525
+ for (int i = 0; i < countChildren(); i++) {
526
+ this.children[i].polygonize();
527
+ }
528
+ }
529
+
530
+ /**
531
+ * @return
532
+ */
533
+ @Override
534
+ public RShape toShape() {
535
+ return this;
536
+ }
537
+
538
+ /**
539
+ * Use this method to get the intersection of this polygon with the polygon
540
+ * passed in as a parameter.
541
+ *
542
+ intersection
543
+ * @param p RShape, the polygon with which to perform the intersection
544
+ * @return RShape, the intersection of the two polygons
545
+ * union ( )
546
+ * xor ( )
547
+ * diff ( )
548
+ */
549
+ public RShape intersection(RShape p) {
550
+ int numPaths = countPaths();
551
+ RPolygon ppoly = p.toPolygon();
552
+
553
+ RShape result = new RShape();
554
+
555
+ RShape temp = new RShape();
556
+ for (int i = 0; i < numPaths; i++) {
557
+ temp.addPath(this.paths[i]);
558
+ }
559
+
560
+ RPolygon resPolPaths = RClip.intersection(temp.toPolygon(), ppoly);
561
+ if (resPolPaths != null) {
562
+ RShape resPaths = resPolPaths.toShape();
563
+ for (int i = 0; i < resPaths.countPaths(); i++) {
564
+ result.addPath(resPaths.paths[i]);
565
+ }
566
+ }
567
+
568
+ for (int i = 0; i < countChildren(); i++) {
569
+ RShape resChildren = this.children[i].intersection(p);
570
+ if (resChildren != null) {
571
+ result.addChild(resChildren);
572
+ }
573
+ }
574
+
575
+ result.setStyle(this);
576
+
577
+ return result;
277
578
 
278
- /**
279
- * Use this method to count the number of paths in the shape.
280
- *
281
- * @eexample countPaths
282
- * @return
283
- * @related addPath ( )
284
- */
285
-
286
- public int countPaths() {
287
- if (this.paths == null) {
288
- return 0;
289
- }
290
-
291
- return this.paths.length;
292
- }
293
-
294
- public int countChildren() {
295
- if (this.children == null) {
296
- return 0;
297
- }
298
-
299
- return this.children.length;
300
- }
301
-
302
- /**
303
- * Use this method to add a new shape. The paths of the shape we are adding
304
- * will simply be added to the current shape.
305
- *
306
- * @eexample addShape
307
- * @param s RShape, the shape to be added.
308
- * @related setPath ( )
309
- * @related addMoveTo ( )
310
- * @invisible
311
- */
312
- public void addShape(RShape s) {
313
- for (int i = 0; i < s.countPaths(); i++) {
314
- this.append(s.paths[i]);
315
- }
316
- }
317
-
318
- /**
319
- * Use this method to create a new path. The first point of the new path
320
- * will be set to (0,0). Use addMoveTo ( ) in order to add a new path with a
321
- * different first point.
322
- *
323
- * @eexample addPath
324
- * @param s the path to be added.
325
- * @related setPath ( )
326
- * @related addMoveTo ( )
327
- */
328
- public void addPath(RPath s) {
329
- this.append(s);
330
- }
331
-
332
- public void addPath() {
333
- this.append(new RPath());
334
- }
335
-
336
- public void addChild() {
337
- this.appendChild(new RShape());
338
- }
339
-
340
- public void addChild(RShape s) {
341
- this.appendChild(s);
342
- }
343
-
344
- /**
345
- * Use this method to set the current path.
346
- *
347
- * @param indPath
348
- * @eexample setPath
349
- * @related addMoveTo ( )
350
- * @related addLineTo ( )
351
- * @related addQuadTo ( )
352
- * @related addBezierTo ( )
353
- * @related addPath ( )
354
- */
355
- public void setPath(int indPath) {
356
- this.currentPath = indPath;
357
- }
358
-
359
- /**
360
- * Use this method to add a new moveTo command to the shape. The command
361
- * moveTo acts different to normal commands, in order to make a better
362
- * analogy to its borthers classes Polygon and Mesh. MoveTo creates a new
363
- * path in the shape. It's similar to adding a new contour to a polygon.
364
- *
365
- * @eexample addMoveTo
366
- * @param endx the x coordinate of the first point for the new path.
367
- * @param endy the y coordinate of the first point for the new path.
368
- * @related addLineTo ( )
369
- * @related addQuadTo ( )
370
- * @related addBezierTo ( )
371
- * @related addPath ( )
372
- * @related setPath ( )
373
- */
374
- public void addMoveTo(float endx, float endy) {
375
- if (paths == null) {
376
- this.append(new RPath(endx, endy));
377
- } else if (paths[currentPath].countCommands() == 0) {
378
- this.paths[currentPath].lastPoint = new RPoint(endx, endy);
379
- } else {
380
- this.append(new RPath(endx, endy));
381
- }
382
- }
383
-
384
- public void addMoveTo(RPoint p) {
385
- addMoveTo(p.x, p.y);
386
- }
387
-
388
- /**
389
- * Use this method to add a new lineTo command to the current path. This
390
- * will add a line from the last point added to the point passed as
391
- * argument.
392
- *
393
- * @eexample addLineTo
394
- * @param endx the x coordinate of the ending point of the line.
395
- * @param endy the y coordinate of the ending point of the line.
396
- * @related addMoveTo ( )
397
- * @related addQuadTo ( )
398
- * @related addBezierTo ( )
399
- * @related addPath ( )
400
- * @related setPath ( )
401
- */
402
- public void addLineTo(float endx, float endy) {
403
- if (paths == null) {
404
- this.append(new RPath());
405
- }
406
- this.paths[currentPath].addLineTo(endx, endy);
407
- }
408
-
409
- public void addLineTo(RPoint p) {
410
- addLineTo(p.x, p.y);
411
- }
412
-
413
- /**
414
- * Use this method to add a new quadTo command to the current path. This
415
- * will add a quadratic bezier from the last point added with the control
416
- * and ending points passed as arguments.
417
- *
418
- * @eexample addQuadTo
419
- * @param cp1x the x coordinate of the control point of the bezier.
420
- * @param cp1y the y coordinate of the control point of the bezier.
421
- * @param endx the x coordinate of the ending point of the bezier.
422
- * @param endy the y coordinate of the ending point of the bezier.
423
- * @related addMoveTo ( )
424
- * @related addLineTo ( )
425
- * @related addBezierTo ( )
426
- * @related addPath ( )
427
- * @related setPath ( )
428
- */
429
- public void addQuadTo(float cp1x, float cp1y, float endx, float endy) {
430
- if (paths == null) {
431
- this.append(new RPath());
432
- }
433
- this.paths[currentPath].addQuadTo(cp1x, cp1y, endx, endy);
434
- }
435
-
436
- public void addQuadTo(RPoint p1, RPoint p2) {
437
- addQuadTo(p1.x, p1.y, p2.x, p2.y);
438
- }
439
-
440
- /**
441
- * Use this method to add a new bezierTo command to the current path. This
442
- * will add a cubic bezier from the last point added with the control and
443
- * ending points passed as arguments.
444
- *
445
- * @eexample addArcTo
446
- * @param cp1x the x coordinate of the first control point of the bezier.
447
- * @param cp1y the y coordinate of the first control point of the bezier.
448
- * @param cp2x the x coordinate of the second control point of the bezier.
449
- * @param cp2y the y coordinate of the second control point of the bezier.
450
- * @param endx the x coordinate of the ending point of the bezier.
451
- * @param endy the y coordinate of the ending point of the bezier.
452
- * @related addMoveTo ( )
453
- * @related addLineTo ( )
454
- * @related addQuadTo ( )
455
- * @related addPath ( )
456
- * @related setPath ( )
457
- */
458
- public void addBezierTo(float cp1x, float cp1y, float cp2x, float cp2y, float endx, float endy) {
459
- if (paths == null) {
460
- this.append(new RPath());
461
- }
462
- this.paths[currentPath].addBezierTo(cp1x, cp1y, cp2x, cp2y, endx, endy);
463
- }
464
-
465
- public void addBezierTo(RPoint p1, RPoint p2, RPoint p3) {
466
- addBezierTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
467
- }
468
-
469
- public void addClose() {
470
- if (paths == null) {
471
- this.append(new RPath());
472
- }
473
- this.paths[currentPath].addClose();
474
- }
475
-
476
- /**
477
- * Use this method to create a new mesh from a given polygon.
478
- *
479
- * @eexample toMesh
480
- * @return RMesh, the mesh made of tristrips resulting of a tesselation of
481
- * the polygonization followed by tesselation of the shape.
482
- * @related draw ( )
483
- */
484
- @Override
485
- public RMesh toMesh() {
486
- return toPolygon().toMesh();
487
- }
488
-
489
- /**
490
- * Use this method to create a new polygon from a given shape.
491
- *
492
- * @eexample toPolygon
493
- * @return RPolygon, the polygon resulting of the segmentation of the
494
- * commands in each path.
495
- * @related draw ( )
496
- */
497
- @Override
498
- public RPolygon toPolygon() {
499
- int numPnts = this.countPaths();
500
-
501
- RPolygon poly = new RPolygon();
502
-
503
- if (this.children != null) {
504
- for (RShape children1 : this.children) {
505
- RPolygon childPoly = children1.toPolygon();
506
- for (RContour contour : childPoly.contours) {
507
- poly.addContour(contour);
508
- }
509
- }
510
- }
511
-
512
- for (int i = 0; i < numPnts; i++) {
513
- RPoint[] pnts = this.paths[i].getPoints();
514
- RContour c = new RContour(pnts);
515
- c.closed = this.paths[i].closed;
516
- c.setStyle(this.paths[i]);
517
- poly.addContour(c);
518
- }
519
-
520
- return poly;
521
- }
522
-
523
- public void polygonize() {
524
- int numPaths = countPaths();
525
-
526
- for (int i = 0; i < numPaths; i++) {
527
- this.paths[i].polygonize();
528
- }
529
-
530
- for (int i = 0; i < countChildren(); i++) {
531
- this.children[i].polygonize();
532
- }
533
- }
534
-
535
- /**
536
- * @return
537
- * @invisible
538
- */
539
- @Override
540
- public RShape toShape() {
541
- return this;
542
- }
543
-
544
- /**
545
- * Use this method to get the intersection of this polygon with the polygon
546
- * passed in as a parameter.
547
- *
548
- * @eexample intersection
549
- * @param p RShape, the polygon with which to perform the intersection
550
- * @return RShape, the intersection of the two polygons
551
- * @related union ( )
552
- * @related xor ( )
553
- * @related diff ( )
554
- */
555
- public RShape intersection(RShape p) {
556
- int numPaths = countPaths();
557
- RPolygon ppoly = p.toPolygon();
558
-
559
- RShape result = new RShape();
560
-
561
- RShape temp = new RShape();
562
- for (int i = 0; i < numPaths; i++) {
563
- temp.addPath(this.paths[i]);
564
- }
565
-
566
- RPolygon resPolPaths = RClip.intersection(temp.toPolygon(), ppoly);
567
- if (resPolPaths != null) {
568
- RShape resPaths = resPolPaths.toShape();
569
- for (int i = 0; i < resPaths.countPaths(); i++) {
570
- result.addPath(resPaths.paths[i]);
571
- }
572
- }
573
-
574
- for (int i = 0; i < countChildren(); i++) {
575
- RShape resChildren = this.children[i].intersection(p);
576
- if (resChildren != null) {
577
- result.addChild(resChildren);
578
- }
579
- }
580
-
581
-
582
- result.setStyle(this);
583
-
584
-
585
- return result;
586
-
587
- /*
579
+ /*
588
580
  RPolygon result = RClip.intersection( this.toPolygon(),p.toPolygon() );
589
581
 
590
582
  if (result == null) return null;
591
583
 
592
584
  return result.toShape();
593
- */
594
- }
595
-
596
- /**
597
- * Use this method to get the union of this polygon with the polygon passed
598
- * in as a parameter.
599
- *
600
- * @eexample union
601
- * @param p RShape, the polygon with which to perform the union
602
- * @return RShape, the union of the two polygons
603
- * @related intersection ( )
604
- * @related xor ( )
605
- * @related diff ( )
606
585
  */
607
- public RShape union(RShape p) {
608
- int numPaths = countPaths();
609
- RPolygon ppoly = p.toPolygon();
610
-
611
- RShape result = new RShape();
612
-
613
- RShape temp = new RShape();
614
- for (int i = 0; i < numPaths; i++) {
615
- temp.addPath(this.paths[i]);
616
- }
617
-
618
- RPolygon resPolPaths = RClip.union(temp.toPolygon(), ppoly);
619
- if (resPolPaths != null) {
620
- RShape resPaths = resPolPaths.toShape();
621
- for (int i = 0; i < resPaths.countPaths(); i++) {
622
- result.addPath(resPaths.paths[i]);
623
- }
624
- }
625
-
626
- for (int i = 0; i < countChildren(); i++) {
627
- RShape resChildren = this.children[i].union(p);
628
- if (resChildren != null) {
629
- result.addChild(resChildren);
630
- }
631
- }
632
- result.setStyle(this);
633
- return result;
634
-
635
- /*
586
+ }
587
+
588
+ /**
589
+ * Use this method to get the union of this polygon with the polygon passed in
590
+ * as a parameter.
591
+ *
592
+ union
593
+ * @param p RShape, the polygon with which to perform the union
594
+ * @return RShape, the union of the two polygons
595
+ * intersection ( )
596
+ * xor ( )
597
+ * diff ( )
598
+ */
599
+ public RShape union(RShape p) {
600
+ int numPaths = countPaths();
601
+ RPolygon ppoly = p.toPolygon();
602
+
603
+ RShape result = new RShape();
604
+
605
+ RShape temp = new RShape();
606
+ for (int i = 0; i < numPaths; i++) {
607
+ temp.addPath(this.paths[i]);
608
+ }
609
+
610
+ RPolygon resPolPaths = RClip.union(temp.toPolygon(), ppoly);
611
+ if (resPolPaths != null) {
612
+ RShape resPaths = resPolPaths.toShape();
613
+ for (int i = 0; i < resPaths.countPaths(); i++) {
614
+ result.addPath(resPaths.paths[i]);
615
+ }
616
+ }
617
+
618
+ for (int i = 0; i < countChildren(); i++) {
619
+ RShape resChildren = this.children[i].union(p);
620
+ if (resChildren != null) {
621
+ result.addChild(resChildren);
622
+ }
623
+ }
624
+ result.setStyle(this);
625
+ return result;
626
+
627
+ /*
636
628
  RPolygon result = RClip.union( this.toPolygon(), p.toPolygon() );
637
629
 
638
630
  if (result == null) return null;
639
631
 
640
632
  return result.toShape();
641
- */
642
- }
643
-
644
- /**
645
- * Use this method to get the xor of this polygon with the polygon passed in
646
- * as a parameter.
647
- *
648
- * @eexample xor
649
- * @param p RShape, the polygon with which to perform the xor
650
- * @return RShape, the xor of the two polygons
651
- * @related union ( )
652
- * @related intersection ( )
653
- * @related diff ( )
654
633
  */
655
- public RShape xor(RShape p) {
656
- int numPaths = countPaths();
657
- RPolygon ppoly = p.toPolygon();
634
+ }
658
635
 
659
- RShape result = new RShape();
636
+ /**
637
+ * Use this method to get the xor of this polygon with the polygon passed in
638
+ * as a parameter.
639
+ *
640
+ xor
641
+ * @param p RShape, the polygon with which to perform the xor
642
+ * @return RShape, the xor of the two polygons
643
+ * union ( )
644
+ * intersection ( )
645
+ * diff ( )
646
+ */
647
+ public RShape xor(RShape p) {
648
+ int numPaths = countPaths();
649
+ RPolygon ppoly = p.toPolygon();
660
650
 
661
- RShape temp = new RShape();
662
- for (int i = 0; i < numPaths; i++) {
663
- temp.addPath(this.paths[i]);
664
- }
651
+ RShape result = new RShape();
665
652
 
666
- RPolygon resPolPaths = RClip.xor(temp.toPolygon(), ppoly);
667
- if (resPolPaths != null) {
668
- RShape resPaths = resPolPaths.toShape();
669
- for (int i = 0; i < resPaths.countPaths(); i++) {
670
- result.addPath(resPaths.paths[i]);
671
- }
672
- }
653
+ RShape temp = new RShape();
654
+ for (int i = 0; i < numPaths; i++) {
655
+ temp.addPath(this.paths[i]);
656
+ }
673
657
 
674
- for (int i = 0; i < countChildren(); i++) {
675
- RShape resChildren = this.children[i].xor(p);
676
- if (resChildren != null) {
677
- result.addChild(resChildren);
678
- }
679
- }
658
+ RPolygon resPolPaths = RClip.xor(temp.toPolygon(), ppoly);
659
+ if (resPolPaths != null) {
660
+ RShape resPaths = resPolPaths.toShape();
661
+ for (int i = 0; i < resPaths.countPaths(); i++) {
662
+ result.addPath(resPaths.paths[i]);
663
+ }
664
+ }
680
665
 
681
- result.setStyle(this);
682
-
666
+ for (int i = 0; i < countChildren(); i++) {
667
+ RShape resChildren = this.children[i].xor(p);
668
+ if (resChildren != null) {
669
+ result.addChild(resChildren);
670
+ }
671
+ }
672
+
673
+ result.setStyle(this);
683
674
 
684
- return result;
675
+ return result;
685
676
 
686
- /*
677
+ /*
687
678
  RPolygon result = RClip.xor( this.toPolygon(), p.toPolygon() );
688
679
 
689
680
  if (result == null) return null;
690
681
 
691
682
  return result.toShape();
692
- */
693
- }
694
-
695
- /**
696
- * Use this method to get the difference between this polygon and the
697
- * polygon passed in as a parameter.
698
- *
699
- * @eexample diff
700
- * @param p RShape, the polygon with which to perform the difference
701
- * @return RShape, the difference of the two polygons
702
- * @related union ( )
703
- * @related xor ( )
704
- * @related intersection ( )
705
683
  */
706
- public RShape diff(RShape p) {
707
- int numPaths = countPaths();
708
- RPolygon ppoly = p.toPolygon();
684
+ }
709
685
 
710
- RShape result = new RShape();
686
+ /**
687
+ * Use this method to get the difference between this polygon and the polygon
688
+ * passed in as a parameter.
689
+ *
690
+ diff
691
+ * @param p RShape, the polygon with which to perform the difference
692
+ * @return RShape, the difference of the two polygons
693
+ * union ( )
694
+ * xor ( )
695
+ * intersection ( )
696
+ */
697
+ public RShape diff(RShape p) {
698
+ int numPaths = countPaths();
699
+ RPolygon ppoly = p.toPolygon();
711
700
 
712
- RShape temp = new RShape();
713
- for (int i = 0; i < numPaths; i++) {
714
- temp.addPath(this.paths[i]);
715
- }
701
+ RShape result = new RShape();
716
702
 
717
- RPolygon resPolPaths = RClip.diff(temp.toPolygon(), ppoly);
718
- if (resPolPaths != null) {
719
- RShape resPaths = resPolPaths.toShape();
720
- for (int i = 0; i < resPaths.countPaths(); i++) {
721
- result.addPath(resPaths.paths[i]);
722
- }
723
- }
703
+ RShape temp = new RShape();
704
+ for (int i = 0; i < numPaths; i++) {
705
+ temp.addPath(this.paths[i]);
706
+ }
724
707
 
725
- for (int i = 0; i < countChildren(); i++) {
726
- RShape resChildren = this.children[i].diff(p);
727
- if (resChildren != null) {
728
- result.addChild(resChildren);
729
- }
730
- }
708
+ RPolygon resPolPaths = RClip.diff(temp.toPolygon(), ppoly);
709
+ if (resPolPaths != null) {
710
+ RShape resPaths = resPolPaths.toShape();
711
+ for (int i = 0; i < resPaths.countPaths(); i++) {
712
+ result.addPath(resPaths.paths[i]);
713
+ }
714
+ }
715
+
716
+ for (int i = 0; i < countChildren(); i++) {
717
+ RShape resChildren = this.children[i].diff(p);
718
+ if (resChildren != null) {
719
+ result.addChild(resChildren);
720
+ }
721
+ }
731
722
 
732
- result.setStyle(this);
733
- return result;
723
+ result.setStyle(this);
724
+ return result;
734
725
 
735
- /*
726
+ /*
736
727
  RPolygon result = RClip.diff( this.toPolygon(), p.toPolygon() );
737
728
 
738
729
  if (result == null) return null;
739
730
 
740
731
  return result.toShape();
741
- */
742
- }
743
-
744
- /**
745
- * Use this to return the start, control and end points of the shape. It
746
- * returns the points as an array of RPoint.
747
- *
748
- * @eexample RShape_getHandles
749
- * @return RPoint[], the start, control and end points returned in an array.
750
- *
751
732
  */
752
- @Override
753
- public RPoint[] getHandles() {
754
- int numPaths = countPaths();
755
-
756
- RPoint[] result = null;
757
- RPoint[] newresult;
758
- for (int i = 0; i < numPaths; i++) {
759
- RPoint[] newPoints = paths[i].getHandles();
760
- if (newPoints != null) {
761
- if (result == null) {
762
- result = new RPoint[newPoints.length];
763
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
764
- } else {
765
- newresult = new RPoint[result.length + newPoints.length];
766
- System.arraycopy(result, 0, newresult, 0, result.length);
767
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
768
- result = newresult;
769
- }
770
- }
771
- }
772
-
773
- for (int i = 0; i < countChildren(); i++) {
774
- RPoint[] newPoints = children[i].getHandles();
775
- if (newPoints != null) {
776
- if (result == null) {
777
- result = new RPoint[newPoints.length];
778
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
779
- } else {
780
- newresult = new RPoint[result.length + newPoints.length];
781
- System.arraycopy(result, 0, newresult, 0, result.length);
782
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
783
- result = newresult;
784
- }
785
- }
733
+ }
734
+
735
+ /**
736
+ * Use this to return the start, control and end points of the shape. It
737
+ * returns the points as an array of RPoint.
738
+ *
739
+ RShape_getHandles
740
+ * @return RPoint[], the start, control and end points returned in an array.
741
+ *
742
+ */
743
+ @Override
744
+ public RPoint[] getHandles() {
745
+ int numPaths = countPaths();
746
+
747
+ RPoint[] result = null;
748
+ RPoint[] newresult;
749
+ for (int i = 0; i < numPaths; i++) {
750
+ RPoint[] newPoints = paths[i].getHandles();
751
+ if (newPoints != null) {
752
+ if (result == null) {
753
+ result = new RPoint[newPoints.length];
754
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
755
+ } else {
756
+ newresult = new RPoint[result.length + newPoints.length];
757
+ System.arraycopy(result, 0, newresult, 0, result.length);
758
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
759
+ result = newresult;
786
760
  }
787
-
788
- return result;
761
+ }
789
762
  }
790
763
 
791
- /**
792
- * Use this to return a point on the curve given a certain advancement. It
793
- * returns the point as an RPoint.
794
- *
795
- * @param t
796
- * @eexample RShape_getPoints
797
- * @return RPoint[], the point on the curve.
798
- *
799
- */
800
- @Override
801
- public RPoint getPoint(float t) {
802
- float[] indAndAdv = indAndAdvAt(t);
803
- int indOfElement = (int) (indAndAdv[0]);
804
- float advOfElement = indAndAdv[1];
805
-
806
- if (indOfElement < countPaths()) {
807
- return paths[indOfElement].getPoint(advOfElement);
764
+ for (int i = 0; i < countChildren(); i++) {
765
+ RPoint[] newPoints = children[i].getHandles();
766
+ if (newPoints != null) {
767
+ if (result == null) {
768
+ result = new RPoint[newPoints.length];
769
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
770
+ } else {
771
+ newresult = new RPoint[result.length + newPoints.length];
772
+ System.arraycopy(result, 0, newresult, 0, result.length);
773
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
774
+ result = newresult;
775
+ }
776
+ }
777
+ }
778
+
779
+ return result;
780
+ }
781
+
782
+ /**
783
+ * Use this to return a point on the curve given a certain advancement. It
784
+ * returns the point as an RPoint.
785
+ *
786
+ * @param t
787
+ RShape_getPoints
788
+ * @return RPoint[], the point on the curve.
789
+ *
790
+ */
791
+ @Override
792
+ public RPoint getPoint(float t) {
793
+ float[] indAndAdv = indAndAdvAt(t);
794
+ int indOfElement = (int) (indAndAdv[0]);
795
+ float advOfElement = indAndAdv[1];
796
+
797
+ if (indOfElement < countPaths()) {
798
+ return paths[indOfElement].getPoint(advOfElement);
799
+ } else {
800
+ return children[indOfElement - countPaths()].getPoint(advOfElement);
801
+ }
802
+ }
803
+
804
+ /**
805
+ * Use this to return the points on the curve of the shape. It returns the
806
+ * points as an array of RPoint.
807
+ *
808
+ RShape_getPoints
809
+ * @return RPoint[], the points returned in an array.
810
+ *
811
+ */
812
+ @Override
813
+ public RPoint[] getPoints() {
814
+ int numPaths = countPaths();
815
+
816
+ RCommand.segmentAccOffset = RCommand.segmentOffset;
817
+ RPoint[] result = null;
818
+ RPoint[] newresult;
819
+ for (int i = 0; i < numPaths; i++) {
820
+ RPoint[] newPoints = paths[i].getPoints();
821
+ if (newPoints != null) {
822
+ if (result == null) {
823
+ result = new RPoint[newPoints.length];
824
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
808
825
  } else {
809
- return children[indOfElement - countPaths()].getPoint(advOfElement);
826
+ newresult = new RPoint[result.length + newPoints.length];
827
+ System.arraycopy(result, 0, newresult, 0, result.length);
828
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
829
+ result = newresult;
810
830
  }
831
+ }
811
832
  }
812
833
 
813
- /**
814
- * Use this to return the points on the curve of the shape. It returns the
815
- * points as an array of RPoint.
816
- *
817
- * @eexample RShape_getPoints
818
- * @return RPoint[], the points returned in an array.
819
- *
820
- */
821
- @Override
822
- public RPoint[] getPoints() {
823
- int numPaths = countPaths();
824
-
825
- RCommand.segmentAccOffset = RCommand.segmentOffset;
826
- RPoint[] result = null;
827
- RPoint[] newresult;
828
- for (int i = 0; i < numPaths; i++) {
829
- RPoint[] newPoints = paths[i].getPoints();
830
- if (newPoints != null) {
831
- if (result == null) {
832
- result = new RPoint[newPoints.length];
833
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
834
- } else {
835
- newresult = new RPoint[result.length + newPoints.length];
836
- System.arraycopy(result, 0, newresult, 0, result.length);
837
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
838
- result = newresult;
839
- }
840
- }
841
- }
842
-
843
- for (int i = 0; i < countChildren(); i++) {
844
- RPoint[] newPoints = children[i].getPoints();
845
- if (newPoints != null) {
846
- if (result == null) {
847
- result = new RPoint[newPoints.length];
848
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
849
- } else {
850
- newresult = new RPoint[result.length + newPoints.length];
851
- System.arraycopy(result, 0, newresult, 0, result.length);
852
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
853
- result = newresult;
854
- }
855
- }
834
+ for (int i = 0; i < countChildren(); i++) {
835
+ RPoint[] newPoints = children[i].getPoints();
836
+ if (newPoints != null) {
837
+ if (result == null) {
838
+ result = new RPoint[newPoints.length];
839
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
840
+ } else {
841
+ newresult = new RPoint[result.length + newPoints.length];
842
+ System.arraycopy(result, 0, newresult, 0, result.length);
843
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
844
+ result = newresult;
845
+ }
846
+ }
847
+ }
848
+
849
+ return result;
850
+ }
851
+
852
+ /**
853
+ * Use this to return a point on the curve given a certain advancement. It
854
+ * returns the point as an RPoint.
855
+ *
856
+ * @param t
857
+ RShape_getTangents
858
+ * @return RPoint[], the point on the curve.
859
+ *
860
+ */
861
+ @Override
862
+ public RPoint getTangent(float t) {
863
+ float[] indAndAdv = indAndAdvAt(t);
864
+ int indOfElement = (int) (indAndAdv[0]);
865
+ float advOfElement = indAndAdv[1];
866
+
867
+ if (indOfElement < countPaths()) {
868
+ return paths[indOfElement].getTangent(advOfElement);
869
+ } else {
870
+ return children[indOfElement - countPaths()].getTangent(advOfElement);
871
+ }
872
+ }
873
+
874
+ /**
875
+ * Use this to return a specific tangent on the curve. It returns true if the
876
+ * point passed as a parameter is inside the shape. Implementation taken from:
877
+ * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
878
+ *
879
+ * @param x the X coordinate of the point for which to test containment.
880
+ * @param y the Y coordinate of the point for which to test containment.
881
+ * @return boolean, true if the point is in the path.
882
+ *
883
+ */
884
+ public boolean contains(float x, float y) {
885
+ return contains(new RPoint(x, y));
886
+ }
887
+
888
+ /**
889
+ * Use this to return a specific tangent on the curve. It returns true if the
890
+ * point passed as a parameter is inside the shape. Implementation taken from:
891
+ * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
892
+ *
893
+ * @param p the point for which to test containment.
894
+ * @return boolean, true if the point is in the path.
895
+ *
896
+ */
897
+ @Override
898
+ public boolean contains(RPoint p) {
899
+ float testx = p.x;
900
+ float testy = p.y;
901
+
902
+ // Test for containment in bounding box
903
+ RRectangle bbox = getBounds();
904
+ float xmin = bbox.getMinX();
905
+ float xmax = bbox.getMaxX();
906
+
907
+ float ymin = bbox.getMinY();
908
+ float ymax = bbox.getMaxY();
909
+
910
+ if ((testx < xmin) || (testx > xmax) || (testy < ymin) || (testy > ymax)) {
911
+ return false;
912
+ }
913
+ // Test for containment in shape
914
+ RPoint[][] pointpaths = getPointsInPaths();
915
+ if (pointpaths == null) {
916
+ return false;
917
+ }
918
+ RPoint[] verts = pointpaths[0];
919
+ for (int k = 1; k < pointpaths.length; k++) {
920
+ verts = (RPoint[]) PApplet.append(verts, new RPoint());
921
+ verts = (RPoint[]) PApplet.concat(verts, pointpaths[k]);
922
+ }
923
+ verts = (RPoint[]) PApplet.append(verts, new RPoint());
924
+ if (verts == null) {
925
+ return false;
926
+ }
927
+ int nvert = verts.length;
928
+ int i, j;
929
+ boolean c = false;
930
+ for (i = 0, j = nvert - 1; i < nvert; j = i++) {
931
+ if (((verts[i].y > testy) != (verts[j].y > testy))
932
+ && (testx < (verts[j].x - verts[i].x) * (testy - verts[i].y) / (verts[j].y - verts[i].y) + verts[i].x)) {
933
+ c = !c;
934
+ }
935
+ }
936
+ return c;
937
+ }
938
+
939
+ /**
940
+ * Use this to return the points on the curve of the shape. It returns the
941
+ * point as an RPoint.
942
+ *
943
+ RShape_getTangents
944
+ * @return RPoint[], the points returned in an array.
945
+ *
946
+ */
947
+ @Override
948
+ public RPoint[] getTangents() {
949
+ int numPaths = countPaths();
950
+
951
+ RPoint[] result = null;
952
+ RPoint[] newresult;
953
+ for (int i = 0; i < numPaths; i++) {
954
+ RPoint[] newPoints = paths[i].getTangents();
955
+ if (newPoints != null) {
956
+ if (result == null) {
957
+ result = new RPoint[newPoints.length];
958
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
959
+ } else {
960
+ newresult = new RPoint[result.length + newPoints.length];
961
+ System.arraycopy(result, 0, newresult, 0, result.length);
962
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
963
+ result = newresult;
856
964
  }
857
-
858
- return result;
965
+ }
859
966
  }
860
967
 
861
- /**
862
- * Use this to return a point on the curve given a certain advancement. It
863
- * returns the point as an RPoint.
864
- *
865
- * @param t
866
- * @eexample RShape_getTangents
867
- * @return RPoint[], the point on the curve.
868
- *
869
- */
870
- @Override
871
- public RPoint getTangent(float t) {
872
- float[] indAndAdv = indAndAdvAt(t);
873
- int indOfElement = (int) (indAndAdv[0]);
874
- float advOfElement = indAndAdv[1];
875
-
876
- if (indOfElement < countPaths()) {
877
- return paths[indOfElement].getTangent(advOfElement);
968
+ for (int i = 0; i < countChildren(); i++) {
969
+ RPoint[] newPoints = children[i].getTangents();
970
+ if (newPoints != null) {
971
+ if (result == null) {
972
+ result = new RPoint[newPoints.length];
973
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
974
+ } else {
975
+ newresult = new RPoint[result.length + newPoints.length];
976
+ System.arraycopy(result, 0, newresult, 0, result.length);
977
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
978
+ result = newresult;
979
+ }
980
+ }
981
+ }
982
+ return result;
983
+ }
984
+
985
+ /**
986
+ * Use this to return the points of each path of the group. It returns the
987
+ * points as an array of arrays of RPoint.
988
+ *
989
+ RGroup_getPoints
990
+ * @return RPoint[], the points returned in an array.
991
+ *
992
+ */
993
+ @Override
994
+ public RPoint[][] getPointsInPaths() {
995
+ int numPaths = countPaths();
996
+
997
+ RPoint[][] result = null;
998
+ RPoint[][] newresult;
999
+ for (int i = 0; i < numPaths; i++) {
1000
+ RPoint[][] newPointPaths = paths[i].getPointsInPaths();
1001
+ if (newPointPaths != null) {
1002
+ if (result == null) {
1003
+ result = new RPoint[newPointPaths.length][];
1004
+ System.arraycopy(newPointPaths, 0, result, 0, newPointPaths.length);
878
1005
  } else {
879
- return children[indOfElement - countPaths()].getTangent(advOfElement);
1006
+ newresult = new RPoint[result.length + newPointPaths.length][];
1007
+ System.arraycopy(result, 0, newresult, 0, result.length);
1008
+ System.arraycopy(newPointPaths, 0, newresult, result.length, newPointPaths.length);
1009
+ result = newresult;
880
1010
  }
1011
+ }
881
1012
  }
882
1013
 
883
- /**
884
- * Use this to return a specific tangent on the curve. It returns true if
885
- * the point passed as a parameter is inside the shape. Implementation taken
886
- * from:
887
- * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
888
- *
889
- * @param x the X coordinate of the point for which to test containment.
890
- * @param y the Y coordinate of the point for which to test containment.
891
- * @return boolean, true if the point is in the path.
892
- *
893
- */
894
- public boolean contains(float x, float y) {
895
- return contains(new RPoint(x, y));
896
- }
897
-
898
- /**
899
- * Use this to return a specific tangent on the curve. It returns true if
900
- * the point passed as a parameter is inside the shape. Implementation taken
901
- * from:
902
- * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
903
- *
904
- * @param p the point for which to test containment.
905
- * @return boolean, true if the point is in the path.
906
- *
907
- */
908
- @Override
909
- public boolean contains(RPoint p) {
910
- float testx = p.x;
911
- float testy = p.y;
912
-
913
- // Test for containment in bounding box
914
- RRectangle bbox = getBounds();
915
- float xmin = bbox.getMinX();
916
- float xmax = bbox.getMaxX();
917
-
918
- float ymin = bbox.getMinY();
919
- float ymax = bbox.getMaxY();
920
-
921
- if ((testx < xmin) || (testx > xmax) || (testy < ymin) || (testy > ymax)) {
922
- return false;
923
- }
924
- // Test for containment in shape
925
- RPoint[][] pointpaths = getPointsInPaths();
926
- if (pointpaths == null) {
927
- return false;
928
- }
929
- RPoint[] verts = pointpaths[0];
930
- for (int k = 1; k < pointpaths.length; k++) {
931
- verts = (RPoint[]) PApplet.append(verts, new RPoint());
932
- verts = (RPoint[]) PApplet.concat(verts, pointpaths[k]);
933
- }
934
- verts = (RPoint[]) PApplet.append(verts, new RPoint());
935
- if (verts == null) {
936
- return false;
937
- }
938
- int nvert = verts.length;
939
- int i, j;
940
- boolean c = false;
941
- for (i = 0, j = nvert - 1; i < nvert; j = i++) {
942
- if (((verts[i].y > testy) != (verts[j].y > testy))
943
- && (testx < (verts[j].x - verts[i].x) * (testy - verts[i].y) / (verts[j].y - verts[i].y) + verts[i].x)) {
944
- c = !c;
945
- }
1014
+ for (int i = 0; i < countChildren(); i++) {
1015
+ RPoint[][] newPoints = children[i].getPointsInPaths();
1016
+ if (newPoints != null) {
1017
+ if (result == null) {
1018
+ result = new RPoint[newPoints.length][];
1019
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1020
+ } else {
1021
+ newresult = new RPoint[result.length + newPoints.length][];
1022
+ System.arraycopy(result, 0, newresult, 0, result.length);
1023
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1024
+ result = newresult;
1025
+ }
1026
+ }
1027
+ }
1028
+
1029
+ return result;
1030
+ }
1031
+
1032
+ /**
1033
+ *
1034
+ * @return
1035
+ */
1036
+ @Override
1037
+ public RPoint[][] getHandlesInPaths() {
1038
+ int numPaths = countPaths();
1039
+
1040
+ RPoint[][] result = null;
1041
+ RPoint[][] newresult;
1042
+ for (int i = 0; i < numPaths; i++) {
1043
+ RPoint[][] newHandlePaths = paths[i].getHandlesInPaths();
1044
+ if (newHandlePaths != null) {
1045
+ if (result == null) {
1046
+ result = new RPoint[newHandlePaths.length][];
1047
+ System.arraycopy(newHandlePaths, 0, result, 0, newHandlePaths.length);
1048
+ } else {
1049
+ newresult = new RPoint[result.length + newHandlePaths.length][];
1050
+ System.arraycopy(result, 0, newresult, 0, result.length);
1051
+ System.arraycopy(newHandlePaths, 0, newresult, result.length, newHandlePaths.length);
1052
+ result = newresult;
946
1053
  }
947
- return c;
1054
+ }
948
1055
  }
949
1056
 
950
- /**
951
- * Use this to return the points on the curve of the shape. It returns the
952
- * point as an RPoint.
953
- *
954
- * @eexample RShape_getTangents
955
- * @return RPoint[], the points returned in an array.
956
- *
957
- */
958
- @Override
959
- public RPoint[] getTangents() {
960
- int numPaths = countPaths();
961
-
962
- RPoint[] result = null;
963
- RPoint[] newresult;
964
- for (int i = 0; i < numPaths; i++) {
965
- RPoint[] newPoints = paths[i].getTangents();
966
- if (newPoints != null) {
967
- if (result == null) {
968
- result = new RPoint[newPoints.length];
969
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
970
- } else {
971
- newresult = new RPoint[result.length + newPoints.length];
972
- System.arraycopy(result, 0, newresult, 0, result.length);
973
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
974
- result = newresult;
975
- }
976
- }
977
- }
978
-
979
- for (int i = 0; i < countChildren(); i++) {
980
- RPoint[] newPoints = children[i].getTangents();
981
- if (newPoints != null) {
982
- if (result == null) {
983
- result = new RPoint[newPoints.length];
984
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
985
- } else {
986
- newresult = new RPoint[result.length + newPoints.length];
987
- System.arraycopy(result, 0, newresult, 0, result.length);
988
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
989
- result = newresult;
990
- }
991
- }
1057
+ for (int i = 0; i < countChildren(); i++) {
1058
+ RPoint[][] newPoints = children[i].getHandlesInPaths();
1059
+ if (newPoints != null) {
1060
+ if (result == null) {
1061
+ result = new RPoint[newPoints.length][];
1062
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1063
+ } else {
1064
+ newresult = new RPoint[result.length + newPoints.length][];
1065
+ System.arraycopy(result, 0, newresult, 0, result.length);
1066
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1067
+ result = newresult;
992
1068
  }
993
- return result;
1069
+ }
994
1070
  }
995
1071
 
996
- /**
997
- * Use this to return the points of each path of the group. It returns the
998
- * points as an array of arrays of RPoint.
999
- *
1000
- * @eexample RGroup_getPoints
1001
- * @return RPoint[], the points returned in an array.
1002
- *
1003
- */
1004
- @Override
1005
- public RPoint[][] getPointsInPaths() {
1006
- int numPaths = countPaths();
1072
+ return result;
1073
+ }
1007
1074
 
1008
- RPoint[][] result = null;
1009
- RPoint[][] newresult;
1010
- for (int i = 0; i < numPaths; i++) {
1011
- RPoint[][] newPointPaths = paths[i].getPointsInPaths();
1012
- if (newPointPaths != null) {
1013
- if (result == null) {
1014
- result = new RPoint[newPointPaths.length][];
1015
- System.arraycopy(newPointPaths, 0, result, 0, newPointPaths.length);
1016
- } else {
1017
- newresult = new RPoint[result.length + newPointPaths.length][];
1018
- System.arraycopy(result, 0, newresult, 0, result.length);
1019
- System.arraycopy(newPointPaths, 0, newresult, result.length, newPointPaths.length);
1020
- result = newresult;
1021
- }
1022
- }
1023
- }
1024
-
1025
- for (int i = 0; i < countChildren(); i++) {
1026
- RPoint[][] newPoints = children[i].getPointsInPaths();
1027
- if (newPoints != null) {
1028
- if (result == null) {
1029
- result = new RPoint[newPoints.length][];
1030
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1031
- } else {
1032
- newresult = new RPoint[result.length + newPoints.length][];
1033
- System.arraycopy(result, 0, newresult, 0, result.length);
1034
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1035
- result = newresult;
1036
- }
1037
- }
1038
- }
1039
-
1040
- return result;
1075
+ @Override
1076
+ public RPoint[][] getTangentsInPaths() {
1077
+ int numPaths = countPaths();
1078
+ if (numPaths == 0) {
1079
+ return null;
1041
1080
  }
1042
1081
 
1043
- /**
1044
- *
1045
- * @return
1046
- */
1047
- @Override
1048
- public RPoint[][] getHandlesInPaths() {
1049
- int numPaths = countPaths();
1050
-
1051
- RPoint[][] result = null;
1052
- RPoint[][] newresult;
1053
- for (int i = 0; i < numPaths; i++) {
1054
- RPoint[][] newHandlePaths = paths[i].getHandlesInPaths();
1055
- if (newHandlePaths != null) {
1056
- if (result == null) {
1057
- result = new RPoint[newHandlePaths.length][];
1058
- System.arraycopy(newHandlePaths, 0, result, 0, newHandlePaths.length);
1059
- } else {
1060
- newresult = new RPoint[result.length + newHandlePaths.length][];
1061
- System.arraycopy(result, 0, newresult, 0, result.length);
1062
- System.arraycopy(newHandlePaths, 0, newresult, result.length, newHandlePaths.length);
1063
- result = newresult;
1064
- }
1065
- }
1082
+ RPoint[][] result = null;
1083
+ RPoint[][] newresult;
1084
+ for (int i = 0; i < numPaths; i++) {
1085
+ RPoint[][] newTangentPaths = paths[i].getTangentsInPaths();
1086
+ if (newTangentPaths != null) {
1087
+ if (result == null) {
1088
+ result = new RPoint[newTangentPaths.length][];
1089
+ System.arraycopy(newTangentPaths, 0, result, 0, newTangentPaths.length);
1090
+ } else {
1091
+ newresult = new RPoint[result.length + newTangentPaths.length][];
1092
+ System.arraycopy(result, 0, newresult, 0, result.length);
1093
+ System.arraycopy(newTangentPaths, 0, newresult, result.length, newTangentPaths.length);
1094
+ result = newresult;
1066
1095
  }
1096
+ }
1097
+ }
1067
1098
 
1068
- for (int i = 0; i < countChildren(); i++) {
1069
- RPoint[][] newPoints = children[i].getHandlesInPaths();
1070
- if (newPoints != null) {
1071
- if (result == null) {
1072
- result = new RPoint[newPoints.length][];
1073
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1074
- } else {
1075
- newresult = new RPoint[result.length + newPoints.length][];
1076
- System.arraycopy(result, 0, newresult, 0, result.length);
1077
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1078
- result = newresult;
1079
- }
1080
- }
1099
+ for (int i = 0; i < countChildren(); i++) {
1100
+ RPoint[][] newPoints = children[i].getTangentsInPaths();
1101
+ if (newPoints != null) {
1102
+ if (result == null) {
1103
+ result = new RPoint[newPoints.length][];
1104
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1105
+ } else {
1106
+ newresult = new RPoint[result.length + newPoints.length][];
1107
+ System.arraycopy(result, 0, newresult, 0, result.length);
1108
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1109
+ result = newresult;
1081
1110
  }
1082
-
1083
- return result;
1111
+ }
1084
1112
  }
1085
1113
 
1086
- @Override
1087
- public RPoint[][] getTangentsInPaths() {
1088
- int numPaths = countPaths();
1089
- if (numPaths == 0) {
1090
- return null;
1091
- }
1114
+ return result;
1115
+ }
1092
1116
 
1093
- RPoint[][] result = null;
1094
- RPoint[][] newresult;
1095
- for (int i = 0; i < numPaths; i++) {
1096
- RPoint[][] newTangentPaths = paths[i].getTangentsInPaths();
1097
- if (newTangentPaths != null) {
1098
- if (result == null) {
1099
- result = new RPoint[newTangentPaths.length][];
1100
- System.arraycopy(newTangentPaths, 0, result, 0, newTangentPaths.length);
1101
- } else {
1102
- newresult = new RPoint[result.length + newTangentPaths.length][];
1103
- System.arraycopy(result, 0, newresult, 0, result.length);
1104
- System.arraycopy(newTangentPaths, 0, newresult, result.length, newTangentPaths.length);
1105
- result = newresult;
1106
- }
1107
- }
1108
- }
1117
+ public RShape[] splitPaths(float t) {
1118
+ RShape[] result = new RShape[2];
1119
+ result[0] = new RShape();
1120
+ result[1] = new RShape();
1109
1121
 
1110
- for (int i = 0; i < countChildren(); i++) {
1111
- RPoint[][] newPoints = children[i].getTangentsInPaths();
1112
- if (newPoints != null) {
1113
- if (result == null) {
1114
- result = new RPoint[newPoints.length][];
1115
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1116
- } else {
1117
- newresult = new RPoint[result.length + newPoints.length][];
1118
- System.arraycopy(result, 0, newresult, 0, result.length);
1119
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1120
- result = newresult;
1121
- }
1122
- }
1123
- }
1122
+ for (int i = 0; i < countPaths(); i++) {
1123
+ RPath[] splittedPaths = paths[i].split(t);
1124
+ if (splittedPaths != null) {
1125
+ result[0].addPath(splittedPaths[0]);
1126
+ result[1].addPath(splittedPaths[1]);
1127
+ }
1128
+ }
1124
1129
 
1125
- return result;
1130
+ for (int i = 0; i < countChildren(); i++) {
1131
+ RShape[] splittedPaths = children[i].splitPaths(t);
1132
+ if (splittedPaths != null) {
1133
+ result[0].addChild(splittedPaths[0]);
1134
+ result[1].addChild(splittedPaths[1]);
1135
+ }
1126
1136
  }
1127
1137
 
1128
- public RShape[] splitPaths(float t) {
1129
- RShape[] result = new RShape[2];
1130
- result[0] = new RShape();
1131
- result[1] = new RShape();
1138
+ result[0].setStyle(this);
1139
+ result[1].setStyle(this);
1140
+ return result;
1141
+ }
1132
1142
 
1133
- for (int i = 0; i < countPaths(); i++) {
1134
- RPath[] splittedPaths = paths[i].split(t);
1135
- if (splittedPaths != null) {
1136
- result[0].addPath(splittedPaths[0]);
1137
- result[1].addPath(splittedPaths[1]);
1138
- }
1139
- }
1143
+ /**
1144
+ * Use this to insert a split point into the shape.
1145
+ *
1146
+ insertHandle
1147
+ * @param t the parameter of advancement on the curve. t must have values
1148
+ * between 0 and 1.
1149
+ *
1150
+ */
1151
+ public void insertHandle(float t) {
1152
+ if ((t == 0F) || (t == 1F)) {
1153
+ return;
1154
+ }
1140
1155
 
1141
- for (int i = 0; i < countChildren(); i++) {
1142
- RShape[] splittedPaths = children[i].splitPaths(t);
1143
- if (splittedPaths != null) {
1144
- result[0].addChild(splittedPaths[0]);
1145
- result[1].addChild(splittedPaths[1]);
1146
- }
1147
- }
1156
+ float[] indAndAdv = indAndAdvAt(t);
1157
+ int indOfElement = (int) (indAndAdv[0]);
1158
+ float advOfElement = indAndAdv[1];
1148
1159
 
1149
- result[0].setStyle(this);
1150
- result[1].setStyle(this);
1151
- return result;
1160
+ if (indOfElement < countPaths()) {
1161
+ paths[indOfElement].insertHandle(advOfElement);
1162
+ } else {
1163
+ children[indOfElement - countPaths()].insertHandle(advOfElement);
1152
1164
  }
1165
+ // Clear the cache
1166
+ lenCurves = null;
1167
+ lenCurve = -1F;
1168
+ }
1153
1169
 
1154
- /**
1155
- * Use this to insert a split point into the shape.
1156
- *
1157
- * @eexample insertHandle
1158
- * @param t the parameter of advancement on the curve. t must have values
1159
- * between 0 and 1.
1160
- *
1161
- */
1162
- public void insertHandle(float t) {
1163
- if ((t == 0F) || (t == 1F)) {
1164
- return;
1165
- }
1166
-
1167
- float[] indAndAdv = indAndAdvAt(t);
1168
- int indOfElement = (int) (indAndAdv[0]);
1169
- float advOfElement = indAndAdv[1];
1170
+ /**
1171
+ * Use this to insert a split point into each command of the shape.
1172
+ *
1173
+ insertHandleInPaths
1174
+ * @param t the parameter of advancement on the curve. t must have values
1175
+ * between 0 and 1.
1176
+ *
1177
+ */
1178
+ public void insertHandleInPaths(float t) {
1179
+ if ((t == 0F) || (t == 1F)) {
1180
+ return;
1181
+ }
1182
+
1183
+ int numPaths = countPaths();
1184
+ if (numPaths == 0) {
1185
+ return;
1186
+ }
1187
+
1188
+ for (int i = 0; i < numPaths; i++) {
1189
+ paths[i].insertHandleInPaths(t);
1190
+ }
1191
+
1192
+ // Clear the cache
1193
+ lenCurves = null;
1194
+ lenCurve = -1F;
1195
+ }
1196
+
1197
+ public RShape[] split(float t) {
1198
+ RShape[] result = new RShape[2];
1199
+ result[0] = new RShape();
1200
+ result[1] = new RShape();
1201
+
1202
+ if (t == 0.0F) {
1203
+ result[0] = new RShape();
1204
+ result[0].setStyle(this);
1205
+
1206
+ result[1] = new RShape(this);
1207
+ result[1].setStyle(this);
1208
+
1209
+ return result;
1210
+ }
1211
+
1212
+ if (t == 1.0F) {
1213
+ result[0] = new RShape(this);
1214
+ result[0].setStyle(this);
1215
+
1216
+ result[1] = new RShape();
1217
+ result[1].setStyle(this);
1218
+
1219
+ return result;
1220
+ }
1221
+
1222
+ float[] indAndAdv = indAndAdvAt(t);
1223
+ int indOfElement = (int) (indAndAdv[0]);
1224
+ float advOfElement = indAndAdv[1];
1225
+
1226
+ if (indOfElement < countPaths()) {
1227
+ RPath[] splittedShapes = paths[indOfElement].split(advOfElement);
1228
+
1229
+ result[0] = new RShape();
1230
+ for (int i = 0; i < indOfElement; i++) {
1231
+ result[0].addPath(new RPath(paths[i]));
1232
+ }
1233
+ result[0].addPath(new RPath(splittedShapes[0]));
1234
+ result[0].setStyle(this);
1235
+
1236
+ result[1] = new RShape();
1237
+ result[1].addPath(new RPath(splittedShapes[1]));
1238
+ for (int i = indOfElement + 1; i < countPaths(); i++) {
1239
+ result[1].addPath(new RPath(paths[i]));
1240
+ }
1241
+
1242
+ for (int i = 0; i < countChildren(); i++) {
1243
+ result[1].appendChild(new RShape(this.children[i]));
1244
+ }
1245
+ result[1].setStyle(this);
1246
+
1247
+ return result;
1248
+ } else {
1249
+ indOfElement -= countPaths();
1250
+
1251
+ // Add the elements before the cut point
1252
+ for (int i = 0; i < indOfElement; i++) {
1253
+ result[0].addChild(new RShape(children[i]));
1254
+ }
1255
+
1256
+ // Add the cut point element cutted
1257
+ RShape[] splittedChild = children[indOfElement].split(advOfElement);
1258
+ result[0].addChild(new RShape(splittedChild[0]));
1259
+ result[1].addChild(new RShape(splittedChild[1]));
1260
+
1261
+ // Add the elements after the cut point
1262
+ for (int i = indOfElement + 1; i < countChildren(); i++) {
1263
+ result[1].addChild(new RShape(children[i]));
1264
+ }
1265
+
1266
+ result[0].setStyle(this);
1267
+ result[1].setStyle(this);
1268
+
1269
+ return result;
1270
+ }
1271
+ }
1272
+
1273
+ /**
1274
+ * Use this method to get the points of intersection between this shape and
1275
+ * another shape passed in as a parameter.
1276
+ *
1277
+ * @param other the path with which to check for intersections
1278
+ * @return
1279
+ */
1280
+ public RPoint[] getIntersections(RShape other) {
1281
+ // TODO: when we will be able to intersect between all
1282
+ // geometric elements the polygonization will not be necessary
1283
+ RShape shp = new RShape(this);
1284
+ shp.polygonize();
1170
1285
 
1171
- if (indOfElement < countPaths()) {
1172
- paths[indOfElement].insertHandle(advOfElement);
1286
+ RShape otherPol = new RShape(other);
1287
+ otherPol.polygonize();
1288
+ return shp.polygonIntersectionPoints(otherPol);
1289
+ }
1290
+
1291
+ RPoint[] getIntersections(RCommand other) {
1292
+ // TODO: when we will be able to intersect between all
1293
+ // geometric elements the polygonization will not be necessary
1294
+ RShape shp = new RShape(this);
1295
+ shp.polygonize();
1296
+
1297
+ return shp.polygonIntersectionPoints(other);
1298
+ }
1299
+
1300
+ RPoint[] polygonIntersectionPoints(RCommand other) {
1301
+ int numPaths = countPaths();
1302
+
1303
+ RPoint[] result = null;
1304
+ RPoint[] newresult;
1305
+ for (int i = 0; i < numPaths; i++) {
1306
+ RPoint[] newPoints = paths[i].intersectionPoints(other);
1307
+ if (newPoints != null) {
1308
+ if (result == null) {
1309
+ result = new RPoint[newPoints.length];
1310
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1173
1311
  } else {
1174
- children[indOfElement - countPaths()].insertHandle(advOfElement);
1175
- }
1176
- // Clear the cache
1177
- lenCurves = null;
1178
- lenCurve = -1F;
1179
- }
1180
-
1181
- /**
1182
- * Use this to insert a split point into each command of the shape.
1183
- *
1184
- * @eexample insertHandleInPaths
1185
- * @param t the parameter of advancement on the curve. t must have values
1186
- * between 0 and 1.
1187
- *
1188
- */
1189
- public void insertHandleInPaths(float t) {
1190
- if ((t == 0F) || (t == 1F)) {
1191
- return;
1192
- }
1193
-
1194
- int numPaths = countPaths();
1195
- if (numPaths == 0) {
1196
- return;
1312
+ newresult = new RPoint[result.length + newPoints.length];
1313
+ System.arraycopy(result, 0, newresult, 0, result.length);
1314
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1315
+ result = newresult;
1197
1316
  }
1317
+ }
1318
+ }
1198
1319
 
1199
- for (int i = 0; i < numPaths; i++) {
1200
- paths[i].insertHandleInPaths(t);
1320
+ for (int i = 0; i < countChildren(); i++) {
1321
+ RPoint[] newPoints = children[i].polygonIntersectionPoints(other);
1322
+ if (newPoints != null) {
1323
+ if (result == null) {
1324
+ result = new RPoint[newPoints.length];
1325
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1326
+ } else {
1327
+ newresult = new RPoint[result.length + newPoints.length];
1328
+ System.arraycopy(result, 0, newresult, 0, result.length);
1329
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1330
+ result = newresult;
1201
1331
  }
1202
-
1203
- // Clear the cache
1204
- lenCurves = null;
1205
- lenCurve = -1F;
1332
+ }
1206
1333
  }
1207
1334
 
1208
- public RShape[] split(float t) {
1209
- RShape[] result = new RShape[2];
1210
- result[0] = new RShape();
1211
- result[1] = new RShape();
1335
+ return result;
1336
+ }
1212
1337
 
1213
- if (t == 0.0F) {
1214
- result[0] = new RShape();
1215
- result[0].setStyle(this);
1338
+ RPoint[] polygonIntersectionPoints(RPath other) {
1339
+ int numChildren = countChildren();
1340
+ int numPaths = countPaths();
1216
1341
 
1217
- result[1] = new RShape(this);
1218
- result[1].setStyle(this);
1342
+ RPoint[] result = null;
1343
+ RPoint[] newresult;
1219
1344
 
1220
- return result;
1345
+ for (int i = 0; i < numPaths; i++) {
1346
+ RPoint[] newPoints = paths[i].intersectionPoints(other);
1347
+ if (newPoints != null) {
1348
+ if (result == null) {
1349
+ result = new RPoint[newPoints.length];
1350
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1351
+ } else {
1352
+ newresult = new RPoint[result.length + newPoints.length];
1353
+ System.arraycopy(result, 0, newresult, 0, result.length);
1354
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1355
+ result = newresult;
1221
1356
  }
1357
+ }
1358
+ }
1222
1359
 
1223
- if (t == 1.0F) {
1224
- result[0] = new RShape(this);
1225
- result[0].setStyle(this);
1226
-
1227
- result[1] = new RShape();
1228
- result[1].setStyle(this);
1229
-
1230
- return result;
1360
+ for (int i = 0; i < numChildren; i++) {
1361
+ RPoint[] newPoints = children[i].polygonIntersectionPoints(other);
1362
+ if (newPoints != null) {
1363
+ if (result == null) {
1364
+ result = new RPoint[newPoints.length];
1365
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1366
+ } else {
1367
+ newresult = new RPoint[result.length + newPoints.length];
1368
+ System.arraycopy(result, 0, newresult, 0, result.length);
1369
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1370
+ result = newresult;
1231
1371
  }
1372
+ }
1373
+ }
1232
1374
 
1233
- float[] indAndAdv = indAndAdvAt(t);
1234
- int indOfElement = (int) (indAndAdv[0]);
1235
- float advOfElement = indAndAdv[1];
1236
-
1237
- if (indOfElement < countPaths()) {
1238
- RPath[] splittedShapes = paths[indOfElement].split(advOfElement);
1375
+ return result;
1376
+ }
1239
1377
 
1240
- result[0] = new RShape();
1241
- for (int i = 0; i < indOfElement; i++) {
1242
- result[0].addPath(new RPath(paths[i]));
1243
- }
1244
- result[0].addPath(new RPath(splittedShapes[0]));
1245
- result[0].setStyle(this);
1378
+ RPoint[] polygonIntersectionPoints(RShape other) {
1379
+ int numChildren = countChildren();
1380
+ int numPaths = countPaths();
1246
1381
 
1247
- result[1] = new RShape();
1248
- result[1].addPath(new RPath(splittedShapes[1]));
1249
- for (int i = indOfElement + 1; i < countPaths(); i++) {
1250
- result[1].addPath(new RPath(paths[i]));
1251
- }
1382
+ RPoint[] result = null;
1383
+ RPoint[] newresult;
1252
1384
 
1253
- for (int i = 0; i < countChildren(); i++) {
1254
- result[1].appendChild(new RShape(this.children[i]));
1255
- }
1256
- result[1].setStyle(this);
1257
-
1258
- return result;
1385
+ for (int i = 0; i < numPaths; i++) {
1386
+ RPoint[] newPoints = other.polygonIntersectionPoints(paths[i]);
1387
+ if (newPoints != null) {
1388
+ if (result == null) {
1389
+ result = new RPoint[newPoints.length];
1390
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1259
1391
  } else {
1260
- indOfElement -= countPaths();
1261
-
1262
- // Add the elements before the cut point
1263
- for (int i = 0; i < indOfElement; i++) {
1264
- result[0].addChild(new RShape(children[i]));
1265
- }
1266
-
1267
- // Add the cut point element cutted
1268
- RShape[] splittedChild = children[indOfElement].split(advOfElement);
1269
- result[0].addChild(new RShape(splittedChild[0]));
1270
- result[1].addChild(new RShape(splittedChild[1]));
1271
-
1272
- // Add the elements after the cut point
1273
- for (int i = indOfElement + 1; i < countChildren(); i++) {
1274
- result[1].addChild(new RShape(children[i]));
1275
- }
1276
-
1277
- result[0].setStyle(this);
1278
- result[1].setStyle(this);
1392
+ newresult = new RPoint[result.length + newPoints.length];
1393
+ System.arraycopy(result, 0, newresult, 0, result.length);
1394
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1395
+ result = newresult;
1396
+ }
1397
+ }
1398
+ }
1279
1399
 
1280
- return result;
1400
+ for (int i = 0; i < numChildren; i++) {
1401
+ RPoint[] newPoints = other.polygonIntersectionPoints(children[i]);
1402
+ if (newPoints != null) {
1403
+ if (result == null) {
1404
+ result = new RPoint[newPoints.length];
1405
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1406
+ } else {
1407
+ newresult = new RPoint[result.length + newPoints.length];
1408
+ System.arraycopy(result, 0, newresult, 0, result.length);
1409
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1410
+ result = newresult;
1281
1411
  }
1412
+ }
1282
1413
  }
1283
1414
 
1284
- /**
1285
- * Use this method to get the points of intersection between this shape and
1286
- * another shape passed in as a parameter.
1287
- *
1288
- * @param other the path with which to check for intersections
1289
- * @return
1290
- */
1291
- public RPoint[] getIntersections(RShape other) {
1292
- // TODO: when we will be able to intersect between all
1293
- // geometric elements the polygonization will not be necessary
1294
- RShape shp = new RShape(this);
1295
- shp.polygonize();
1415
+ return result;
1416
+ }
1296
1417
 
1297
- RShape otherPol = new RShape(other);
1298
- otherPol.polygonize();
1299
- return shp.polygonIntersectionPoints(otherPol);
1300
- }
1418
+ /**
1419
+ * Use this method to get the closest or intersection points of the shape with
1420
+ * another shape passed as argument.
1421
+ *
1422
+ * @param other the path with which to check for intersections
1423
+ * @return
1424
+ */
1425
+ public RClosest getClosest(RShape other) {
1426
+ // TODO: when we will be able to intersect between all
1427
+ // geometric elements the polygonization will not be necessary
1428
+ RShape shp = new RShape(this);
1429
+ shp.polygonize();
1301
1430
 
1302
- RPoint[] getIntersections(RCommand other) {
1303
- // TODO: when we will be able to intersect between all
1304
- // geometric elements the polygonization will not be necessary
1305
- RShape shp = new RShape(this);
1306
- shp.polygonize();
1431
+ RShape otherPol = new RShape(other);
1432
+ otherPol.polygonize();
1433
+ return shp.polygonClosestPoints(otherPol);
1434
+ }
1307
1435
 
1308
- return shp.polygonIntersectionPoints(other);
1309
- }
1436
+ RClosest getClosest(RCommand other) {
1437
+ // TODO: when we will be able to intersect between all
1438
+ // geometric elements the polygonization will not be necessary
1439
+ RShape shp = new RShape(this);
1440
+ shp.polygonize();
1310
1441
 
1311
- RPoint[] polygonIntersectionPoints(RCommand other) {
1312
- int numPaths = countPaths();
1442
+ return shp.polygonClosestPoints(other);
1443
+ }
1313
1444
 
1314
- RPoint[] result = null;
1315
- RPoint[] newresult;
1316
- for (int i = 0; i < numPaths; i++) {
1317
- RPoint[] newPoints = paths[i].intersectionPoints(other);
1318
- if (newPoints != null) {
1319
- if (result == null) {
1320
- result = new RPoint[newPoints.length];
1321
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1322
- } else {
1323
- newresult = new RPoint[result.length + newPoints.length];
1324
- System.arraycopy(result, 0, newresult, 0, result.length);
1325
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1326
- result = newresult;
1327
- }
1328
- }
1329
- }
1445
+ RClosest polygonClosestPoints(RCommand other) {
1446
+ int numPaths = countPaths();
1330
1447
 
1331
- for (int i = 0; i < countChildren(); i++) {
1332
- RPoint[] newPoints = children[i].polygonIntersectionPoints(other);
1333
- if (newPoints != null) {
1334
- if (result == null) {
1335
- result = new RPoint[newPoints.length];
1336
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1337
- } else {
1338
- newresult = new RPoint[result.length + newPoints.length];
1339
- System.arraycopy(result, 0, newresult, 0, result.length);
1340
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1341
- result = newresult;
1342
- }
1343
- }
1344
- }
1448
+ RClosest result = new RClosest();
1345
1449
 
1346
- return result;
1450
+ for (int i = 0; i < numPaths; i++) {
1451
+ RClosest currResult = paths[i].closestPoints(other);
1452
+ result.update(currResult);
1347
1453
  }
1348
1454
 
1349
- RPoint[] polygonIntersectionPoints(RPath other) {
1350
- int numChildren = countChildren();
1351
- int numPaths = countPaths();
1455
+ for (int i = 0; i < countChildren(); i++) {
1456
+ RClosest currResult = children[i].polygonClosestPoints(other);
1457
+ result.update(currResult);
1458
+ }
1352
1459
 
1353
- RPoint[] result = null;
1354
- RPoint[] newresult;
1460
+ return result;
1461
+ }
1355
1462
 
1356
- for (int i = 0; i < numPaths; i++) {
1357
- RPoint[] newPoints = paths[i].intersectionPoints(other);
1358
- if (newPoints != null) {
1359
- if (result == null) {
1360
- result = new RPoint[newPoints.length];
1361
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1362
- } else {
1363
- newresult = new RPoint[result.length + newPoints.length];
1364
- System.arraycopy(result, 0, newresult, 0, result.length);
1365
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1366
- result = newresult;
1367
- }
1368
- }
1369
- }
1463
+ RClosest polygonClosestPoints(RPath other) {
1464
+ int numChildren = countChildren();
1465
+ int numPaths = countPaths();
1370
1466
 
1371
- for (int i = 0; i < numChildren; i++) {
1372
- RPoint[] newPoints = children[i].polygonIntersectionPoints(other);
1373
- if (newPoints != null) {
1374
- if (result == null) {
1375
- result = new RPoint[newPoints.length];
1376
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1377
- } else {
1378
- newresult = new RPoint[result.length + newPoints.length];
1379
- System.arraycopy(result, 0, newresult, 0, result.length);
1380
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1381
- result = newresult;
1382
- }
1383
- }
1384
- }
1467
+ RClosest result = new RClosest();
1385
1468
 
1386
- return result;
1469
+ for (int i = 0; i < numPaths; i++) {
1470
+ RClosest currClosest = paths[i].closestPoints(other);
1471
+ result.update(currClosest);
1387
1472
  }
1388
1473
 
1389
- RPoint[] polygonIntersectionPoints(RShape other) {
1390
- int numChildren = countChildren();
1391
- int numPaths = countPaths();
1474
+ for (int i = 0; i < numChildren; i++) {
1475
+ RClosest currClosest = children[i].polygonClosestPoints(other);
1476
+ result.update(currClosest);
1477
+ }
1392
1478
 
1393
- RPoint[] result = null;
1394
- RPoint[] newresult;
1479
+ return result;
1480
+ }
1395
1481
 
1396
- for (int i = 0; i < numPaths; i++) {
1397
- RPoint[] newPoints = other.polygonIntersectionPoints(paths[i]);
1398
- if (newPoints != null) {
1399
- if (result == null) {
1400
- result = new RPoint[newPoints.length];
1401
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1402
- } else {
1403
- newresult = new RPoint[result.length + newPoints.length];
1404
- System.arraycopy(result, 0, newresult, 0, result.length);
1405
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1406
- result = newresult;
1407
- }
1408
- }
1409
- }
1482
+ RClosest polygonClosestPoints(RShape other) {
1483
+ int numChildren = countChildren();
1484
+ int numPaths = countPaths();
1410
1485
 
1411
- for (int i = 0; i < numChildren; i++) {
1412
- RPoint[] newPoints = other.polygonIntersectionPoints(children[i]);
1413
- if (newPoints != null) {
1414
- if (result == null) {
1415
- result = new RPoint[newPoints.length];
1416
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
1417
- } else {
1418
- newresult = new RPoint[result.length + newPoints.length];
1419
- System.arraycopy(result, 0, newresult, 0, result.length);
1420
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
1421
- result = newresult;
1422
- }
1423
- }
1424
- }
1486
+ RClosest result = new RClosest();
1425
1487
 
1426
- return result;
1488
+ for (int i = 0; i < numPaths; i++) {
1489
+ RClosest currClosest = other.polygonClosestPoints(paths[i]);
1490
+ result.update(currClosest);
1427
1491
  }
1428
1492
 
1429
- /**
1430
- * Use this method to get the closest or intersection points of the shape
1431
- * with another shape passed as argument.
1432
- *
1433
- * @param other the path with which to check for intersections
1434
- * @return */
1435
- public RClosest getClosest(RShape other) {
1436
- // TODO: when we will be able to intersect between all
1437
- // geometric elements the polygonization will not be necessary
1438
- RShape shp = new RShape(this);
1439
- shp.polygonize();
1440
-
1441
- RShape otherPol = new RShape(other);
1442
- otherPol.polygonize();
1443
- return shp.polygonClosestPoints(otherPol);
1493
+ for (int i = 0; i < numChildren; i++) {
1494
+ RClosest currClosest = other.polygonClosestPoints(children[i]);
1495
+ result.update(currClosest);
1444
1496
  }
1445
1497
 
1446
- RClosest getClosest(RCommand other) {
1447
- // TODO: when we will be able to intersect between all
1448
- // geometric elements the polygonization will not be necessary
1449
- RShape shp = new RShape(this);
1450
- shp.polygonize();
1451
-
1452
- return shp.polygonClosestPoints(other);
1453
- }
1498
+ return result;
1499
+ }
1454
1500
 
1455
- RClosest polygonClosestPoints(RCommand other) {
1456
- int numPaths = countPaths();
1501
+ /**
1502
+ * Use this method to adapt a group of of figures to a shape.
1503
+ *
1504
+ * @param wght
1505
+ * @param lngthOffset
1506
+ RGroup_adapt
1507
+ * @param shp the path to which to adapt
1508
+ */
1509
+ public void adapt(RShape shp, float wght, float lngthOffset) throws RuntimeException {
1510
+ RRectangle c = this.getBounds();
1511
+ float xmin = c.getMinX();
1512
+ float xmax = c.getMaxX();
1457
1513
 
1458
- RClosest result = new RClosest();
1514
+ int numChildren = countChildren();
1459
1515
 
1460
- for (int i = 0; i < numPaths; i++) {
1461
- RClosest currResult = paths[i].closestPoints(other);
1462
- result.update(currResult);
1516
+ switch (RG.adaptorType) {
1517
+ case RG.BYPOINT:
1518
+ RPoint[] ps = this.getHandles();
1519
+ if (ps != null) {
1520
+ for (RPoint p1 : ps) {
1521
+ float px = p1.x;
1522
+ float py = p1.y;
1523
+ float t = ((px - xmin) / (xmax - xmin) + lngthOffset) % 1.001F;
1524
+ float amp = (py);
1525
+ RPoint tg = shp.getTangent(t);
1526
+ RPoint p = shp.getPoint(t);
1527
+ float angle = (float) Math.atan2(tg.y, tg.x) - (float) Math.PI / 2F;
1528
+ p1.x = p.x + wght * amp * (float) Math.cos(angle);
1529
+ p1.y = p.y + wght * amp * (float) Math.sin(angle);
1530
+ }
1463
1531
  }
1532
+ break;
1533
+ case RG.BYELEMENTINDEX:
1534
+ for (int i = 0; i < numChildren; i++) {
1535
+ RShape elem = this.children[i];
1536
+ RRectangle elemc = elem.getBounds();
1464
1537
 
1465
- for (int i = 0; i < countChildren(); i++) {
1466
- RClosest currResult = children[i].polygonClosestPoints(other);
1467
- result.update(currResult);
1468
- }
1538
+ float px = (elemc.bottomRight.x + elemc.topLeft.x) / 2F;
1539
+ float py = (elemc.bottomRight.y - elemc.topLeft.y) / 2F;
1540
+ float t = ((float) i / (float) numChildren + lngthOffset) % 1F;
1469
1541
 
1470
- return result;
1471
- }
1542
+ RPoint tg = shp.getTangent(t);
1543
+ RPoint p = shp.getPoint(t);
1544
+ float angle = (float) Math.atan2(tg.y, tg.x);
1472
1545
 
1473
- RClosest polygonClosestPoints(RPath other) {
1474
- int numChildren = countChildren();
1475
- int numPaths = countPaths();
1546
+ RPoint pletter = new RPoint(px, py);
1547
+ p.sub(pletter);
1476
1548
 
1477
- RClosest result = new RClosest();
1549
+ RMatrix mtx = new RMatrix();
1550
+ mtx.translate(p);
1551
+ mtx.rotate(angle, pletter);
1552
+ mtx.scale(wght, pletter);
1478
1553
 
1479
- for (int i = 0; i < numPaths; i++) {
1480
- RClosest currClosest = paths[i].closestPoints(other);
1481
- result.update(currClosest);
1554
+ elem.transform(mtx);
1482
1555
  }
1556
+ break;
1483
1557
 
1558
+ case RG.BYELEMENTPOSITION:
1484
1559
  for (int i = 0; i < numChildren; i++) {
1485
- RClosest currClosest = children[i].polygonClosestPoints(other);
1486
- result.update(currClosest);
1487
- }
1560
+ RShape elem = this.children[i];
1561
+ RRectangle elemc = elem.getBounds();
1488
1562
 
1489
- return result;
1490
- }
1563
+ float px = (elemc.bottomRight.x + elemc.topLeft.x) / 2F;
1564
+ float py = (elemc.bottomRight.y - elemc.topLeft.y) / 2F;
1565
+ float t = ((px - xmin) / (xmax - xmin) + lngthOffset) % 1F;
1491
1566
 
1492
- RClosest polygonClosestPoints(RShape other) {
1493
- int numChildren = countChildren();
1494
- int numPaths = countPaths();
1567
+ RPoint tg = shp.getTangent(t);
1568
+ RPoint p = shp.getPoint(t);
1569
+ float angle = (float) Math.atan2(tg.y, tg.x);
1495
1570
 
1496
- RClosest result = new RClosest();
1571
+ RPoint pletter = new RPoint(px, py);
1572
+ p.sub(pletter);
1497
1573
 
1498
- for (int i = 0; i < numPaths; i++) {
1499
- RClosest currClosest = other.polygonClosestPoints(paths[i]);
1500
- result.update(currClosest);
1501
- }
1574
+ RMatrix mtx = new RMatrix();
1575
+ mtx.translate(p);
1576
+ mtx.rotate(angle, pletter);
1577
+ mtx.scale(wght, pletter);
1502
1578
 
1503
- for (int i = 0; i < numChildren; i++) {
1504
- RClosest currClosest = other.polygonClosestPoints(children[i]);
1505
- result.update(currClosest);
1579
+ elem.transform(mtx);
1506
1580
  }
1581
+ break;
1507
1582
 
1508
- return result;
1583
+ default:
1584
+ throw new RuntimeException("Unknown adaptor type : " + RG.adaptorType + ". The method RG.setAdaptor() only accepts RG.BYPOINT or RG.BYELEMENT as parameter values.");
1509
1585
  }
1586
+ }
1510
1587
 
1511
- /**
1512
- * Use this method to adapt a group of of figures to a shape.
1513
- *
1514
- * @param wght
1515
- * @param lngthOffset
1516
- * @eexample RGroup_adapt
1517
- * @param shp the path to which to adapt
1518
- */
1519
- public void adapt(RShape shp, float wght, float lngthOffset) throws RuntimeException {
1520
- RRectangle c = this.getBounds();
1521
- float xmin = c.getMinX();
1522
- float xmax = c.getMaxX();
1523
-
1524
- int numChildren = countChildren();
1525
-
1526
- switch (RG.adaptorType) {
1527
- case RG.BYPOINT:
1528
- RPoint[] ps = this.getHandles();
1529
- if (ps != null) {
1530
- for (RPoint p1 : ps) {
1531
- float px = p1.x;
1532
- float py = p1.y;
1533
- float t = ((px - xmin) / (xmax - xmin) + lngthOffset) % 1.001F;
1534
- float amp = (py);
1535
- RPoint tg = shp.getTangent(t);
1536
- RPoint p = shp.getPoint(t);
1537
- float angle = (float) Math.atan2(tg.y, tg.x) - (float) Math.PI / 2F;
1538
- p1.x = p.x + wght * amp * (float) Math.cos(angle);
1539
- p1.y = p.y + wght * amp * (float) Math.sin(angle);
1540
- }
1541
- }
1542
- break;
1543
- case RG.BYELEMENTINDEX:
1544
- for (int i = 0; i < numChildren; i++) {
1545
- RShape elem = this.children[i];
1546
- RRectangle elemc = elem.getBounds();
1547
-
1548
- float px = (elemc.bottomRight.x + elemc.topLeft.x) / 2F;
1549
- float py = (elemc.bottomRight.y - elemc.topLeft.y) / 2F;
1550
- float t = ((float) i / (float) numChildren + lngthOffset) % 1F;
1551
-
1552
- RPoint tg = shp.getTangent(t);
1553
- RPoint p = shp.getPoint(t);
1554
- float angle = (float) Math.atan2(tg.y, tg.x);
1555
-
1556
- RPoint pletter = new RPoint(px, py);
1557
- p.sub(pletter);
1588
+ public void adapt(RShape shp) throws RuntimeException {
1589
+ adapt(shp, RG.adaptorScale, RG.adaptorLengthOffset);
1590
+ }
1558
1591
 
1559
- RMatrix mtx = new RMatrix();
1560
- mtx.translate(p);
1561
- mtx.rotate(angle, pletter);
1562
- mtx.scale(wght, pletter);
1592
+ /**
1593
+ * Use this method to get the type of element this is.
1594
+ *
1595
+ RShape_getType
1596
+ * @return int, will allways return RGeomElem.SHAPE
1597
+ */
1598
+ @Override
1599
+ public int getType() {
1600
+ return type;
1601
+ }
1563
1602
 
1564
- elem.transform(mtx);
1565
- }
1566
- break;
1567
-
1568
- case RG.BYELEMENTPOSITION:
1569
- for (int i = 0; i < numChildren; i++) {
1570
- RShape elem = this.children[i];
1571
- RRectangle elemc = elem.getBounds();
1572
-
1573
- float px = (elemc.bottomRight.x + elemc.topLeft.x) / 2F;
1574
- float py = (elemc.bottomRight.y - elemc.topLeft.y) / 2F;
1575
- float t = ((px - xmin) / (xmax - xmin) + lngthOffset) % 1F;
1576
-
1577
- RPoint tg = shp.getTangent(t);
1578
- RPoint p = shp.getPoint(t);
1579
- float angle = (float) Math.atan2(tg.y, tg.x);
1580
-
1581
- RPoint pletter = new RPoint(px, py);
1582
- p.sub(pletter);
1583
-
1584
- RMatrix mtx = new RMatrix();
1585
- mtx.translate(p);
1586
- mtx.rotate(angle, pletter);
1587
- mtx.scale(wght, pletter);
1588
-
1589
- elem.transform(mtx);
1590
- }
1591
- break;
1592
-
1593
- default:
1594
- throw new RuntimeException("Unknown adaptor type : " + RG.adaptorType + ". The method RG.setAdaptor() only accepts RG.BYPOINT or RG.BYELEMENT as parameter values.");
1595
- }
1603
+ @Override
1604
+ public void print() {
1605
+ System.out.println("paths [count " + this.countPaths() + "]: ");
1606
+ for (int i = 0; i < countPaths(); i++) {
1607
+ System.out.println("--- path " + i + " ---");
1608
+ paths[i].print();
1609
+ System.out.println("---------------");
1596
1610
  }
1597
-
1598
- public void adapt(RShape shp) throws RuntimeException {
1599
- adapt(shp, RG.adaptorScale, RG.adaptorLengthOffset);
1611
+ System.out.println("children [count " + this.countChildren() + "]: ");
1612
+ for (int i = 0; i < countChildren(); i++) {
1613
+ System.out.println("--- child " + i + " ---");
1614
+ children[i].print();
1615
+ System.out.println("---------------");
1600
1616
  }
1601
1617
 
1602
- /**
1603
- * Use this method to get the type of element this is.
1604
- *
1605
- * @eexample RShape_getType
1606
- * @return int, will allways return RGeomElem.SHAPE
1607
- */
1608
- @Override
1609
- public int getType() {
1610
- return type;
1611
- }
1612
-
1613
- @Override
1614
- public void print() {
1615
- System.out.println("paths [count " + this.countPaths() + "]: ");
1616
- for (int i = 0; i < countPaths(); i++) {
1617
- System.out.println("--- path " + i + " ---");
1618
- paths[i].print();
1619
- System.out.println("---------------");
1620
- }
1621
- System.out.println("children [count " + this.countChildren() + "]: ");
1622
- for (int i = 0; i < countChildren(); i++) {
1623
- System.out.println("--- child " + i + " ---");
1624
- children[i].print();
1625
- System.out.println("---------------");
1626
- }
1618
+ }
1627
1619
 
1620
+ /**
1621
+ *
1622
+ * @param g
1623
+ */
1624
+ @Override
1625
+ public void draw(PGraphics g) {
1626
+ if (!RG.ignoreStyles) {
1627
+ saveContext(g);
1628
+ setContext(g);
1628
1629
  }
1629
1630
 
1630
- /**
1631
- *
1632
- * @param g
1633
- */
1634
- @Override
1635
- public void draw(PGraphics g) {
1636
- if (!RG.ignoreStyles) {
1637
- saveContext(g);
1638
- setContext(g);
1639
- }
1640
-
1641
- this.drawPaths(g);
1631
+ this.drawPaths(g);
1642
1632
 
1643
- for (int i = 0; i < countChildren(); i++) {
1644
- this.children[i].draw(g);
1645
- }
1633
+ for (int i = 0; i < countChildren(); i++) {
1634
+ this.children[i].draw(g);
1635
+ }
1646
1636
 
1647
- if (!RG.ignoreStyles) {
1648
- restoreContext(g);
1649
- }
1637
+ if (!RG.ignoreStyles) {
1638
+ restoreContext(g);
1650
1639
  }
1640
+ }
1651
1641
 
1652
- @Override
1653
- public void draw(PApplet g) {
1654
- if (!RG.ignoreStyles) {
1655
- saveContext(g);
1656
- setContext(g);
1657
- }
1642
+ @Override
1643
+ public void draw(PApplet g) {
1644
+ if (!RG.ignoreStyles) {
1645
+ saveContext(g);
1646
+ setContext(g);
1647
+ }
1658
1648
 
1659
- this.drawPaths(g);
1649
+ this.drawPaths(g);
1660
1650
 
1661
- for (int i = 0; i < countChildren(); i++) {
1662
- this.children[i].draw(g);
1663
- }
1651
+ for (int i = 0; i < countChildren(); i++) {
1652
+ this.children[i].draw(g);
1653
+ }
1664
1654
 
1665
- if (!RG.ignoreStyles) {
1666
- restoreContext(g);
1667
- }
1655
+ if (!RG.ignoreStyles) {
1656
+ restoreContext(g);
1668
1657
  }
1658
+ }
1669
1659
 
1670
- /**
1671
- * Use this method to draw the shape.
1672
- *
1673
- * @eexample drawShape
1674
- * @param g PGraphics, the graphics object on which to draw the shape
1675
- */
1676
- private void drawPaths(PGraphics g) {
1677
- /*
1660
+ /**
1661
+ * Use this method to draw the shape.
1662
+ *
1663
+ drawShape
1664
+ * @param g PGraphics, the graphics object on which to draw the shape
1665
+ */
1666
+ private void drawPaths(PGraphics g) {
1667
+ /*
1678
1668
  try{
1679
1669
  Class declaringClass = g.getClass().getMethod("breakShape", new Class[0]).getDeclaringClass();
1680
1670
  if(declaringClass == Class.forName("processing.core.PGraphics")){
@@ -1701,12 +1691,12 @@ public class RShape extends RGeomElem {
1701
1691
  drawUsingInternalTesselator(g);
1702
1692
 
1703
1693
  }
1704
- */
1705
- drawUsingBreakShape(g);
1706
- }
1694
+ */
1695
+ drawUsingBreakShape(g);
1696
+ }
1707
1697
 
1708
- private void drawPaths(PApplet g) {
1709
- /*
1698
+ private void drawPaths(PApplet g) {
1699
+ /*
1710
1700
  try{
1711
1701
  Class declaringClass = g.g.getClass().getMethod("breakShape", new Class[0]).getDeclaringClass();
1712
1702
  if(declaringClass == Class.forName("processing.core.PGraphics")){
@@ -1734,319 +1724,319 @@ public class RShape extends RGeomElem {
1734
1724
  drawUsingInternalTesselator(g);
1735
1725
 
1736
1726
  }
1737
- */
1738
- drawUsingBreakShape(g);
1739
- }
1740
-
1741
- // ----------------------
1742
- // --- Private Methods ---
1743
- // ----------------------
1744
- @Override
1745
- protected void calculateCurveLengths() {
1746
- lenCurves = new float[countPaths() + countChildren()];
1747
- lenCurve = 0F;
1748
- for (int i = 0; i < countPaths(); i++) {
1749
- lenCurves[i] = paths[i].getCurveLength();
1750
- lenCurve += lenCurves[i];
1751
- }
1727
+ */
1728
+ drawUsingBreakShape(g);
1729
+ }
1730
+
1731
+ // ----------------------
1732
+ // --- Private Methods ---
1733
+ // ----------------------
1734
+ @Override
1735
+ protected void calculateCurveLengths() {
1736
+ lenCurves = new float[countPaths() + countChildren()];
1737
+ lenCurve = 0F;
1738
+ for (int i = 0; i < countPaths(); i++) {
1739
+ lenCurves[i] = paths[i].getCurveLength();
1740
+ lenCurve += lenCurves[i];
1741
+ }
1742
+
1743
+ for (int i = 0; i < countChildren(); i++) {
1744
+ lenCurves[i + countPaths()] = children[i].getCurveLength();
1745
+ lenCurve += lenCurves[i + countPaths()];
1746
+ }
1747
+ }
1748
+
1749
+ private float[] indAndAdvAt(float t) {
1750
+ int indOfElement = 0;
1751
+ float[] lengthsCurves = getCurveLengths();
1752
+ float lengthCurve = getCurveLength();
1753
+
1754
+ /* Calculate the amount of advancement t mapped to each command */
1755
+ /* We use a simple algorithm where we give to each command the same amount of advancement */
1756
+ /* A more useful way would be to give to each command an advancement proportional to the length of the command */
1757
+ float accumulatedAdvancement = lengthsCurves[indOfElement] / lengthCurve;
1758
+ float prevAccumulatedAdvancement = 0F;
1759
+
1760
+ /* Find in what command the advancement point is */
1761
+ while (t > accumulatedAdvancement) {
1762
+ indOfElement++;
1763
+ prevAccumulatedAdvancement = accumulatedAdvancement;
1764
+ accumulatedAdvancement += (lengthsCurves[indOfElement] / lengthCurve);
1765
+ }
1766
+
1767
+ float advOfElement = (t - prevAccumulatedAdvancement) / (lengthsCurves[indOfElement] / lengthCurve);
1768
+
1769
+ float[] indAndAdv = new float[2];
1770
+
1771
+ indAndAdv[0] = indOfElement;
1772
+ indAndAdv[1] = PApplet.constrain(advOfElement, 0.0f, 1.0f);
1773
+
1774
+ return indAndAdv;
1775
+ }
1776
+
1777
+ private void appendChild(RShape nextshape) {
1778
+ RShape[] newshapes;
1779
+ if (children == null) {
1780
+ newshapes = new RShape[1];
1781
+ newshapes[0] = nextshape;
1782
+ currentChild = 0;
1783
+ } else {
1784
+ newshapes = new RShape[this.children.length + 1];
1785
+ System.arraycopy(this.children, 0, newshapes, 0, this.children.length);
1786
+ newshapes[this.children.length] = nextshape;
1787
+ currentChild++;
1788
+ }
1789
+ this.children = newshapes;
1790
+ }
1791
+
1792
+ private void append(RPath nextpath) {
1793
+ RPath[] newpaths;
1794
+ if (paths == null) {
1795
+ newpaths = new RPath[1];
1796
+ newpaths[0] = nextpath;
1797
+ currentPath = 0;
1798
+ } else {
1799
+ newpaths = new RPath[this.paths.length + 1];
1800
+ System.arraycopy(this.paths, 0, newpaths, 0, this.paths.length);
1801
+ newpaths[this.paths.length] = nextpath;
1802
+ currentPath++;
1803
+ }
1804
+ this.paths = newpaths;
1805
+ }
1806
+
1807
+ private void drawUsingInternalTesselator(PGraphics g) {
1808
+ int numPaths = countPaths();
1809
+
1810
+ if (numPaths != 0) {
1811
+ if (isIn(g)) {
1812
+
1813
+ // Save the information about the current context
1814
+ boolean strokeBefore = g.stroke;
1815
+ int strokeColorBefore = g.strokeColor;
1816
+ float strokeWeightBefore = g.strokeWeight;
1817
+ boolean fillBefore = g.fill;
1818
+ int fillColorBefore = g.fillColor;
1819
+
1820
+ // By default always drawy with an ADAPTATIVE segmentator
1821
+ int lastSegmentator = RCommand.segmentType;
1822
+ RCommand.setSegmentator(RCommand.ADAPTATIVE);
1823
+
1824
+ // Check whether to draw the fill or not
1825
+ if (g.fill) {
1826
+ // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
1827
+ // 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
1752
1828
 
1753
- for (int i = 0; i < countChildren(); i++) {
1754
- lenCurves[i + countPaths()] = children[i].getCurveLength();
1755
- lenCurve += lenCurves[i + countPaths()];
1756
- }
1757
- }
1829
+ // This is here because when rendering meshes we get unwanted lines between the triangles
1830
+ g.noStroke();
1831
+ try {
1832
+ g.noSmooth();
1833
+ } catch (Exception e) {
1834
+ }
1758
1835
 
1759
- private float[] indAndAdvAt(float t) {
1760
- int indOfElement = 0;
1761
- float[] lengthsCurves = getCurveLengths();
1762
- float lengthCurve = getCurveLength();
1836
+ RMesh tempMesh = this.toMesh();
1837
+ tempMesh.draw(g);
1763
1838
 
1764
- /* Calculate the amount of advancement t mapped to each command */
1765
- /* We use a simple algorithm where we give to each command the same amount of advancement */
1766
- /* A more useful way would be to give to each command an advancement proportional to the length of the command */
1767
- float accumulatedAdvancement = lengthsCurves[indOfElement] / lengthCurve;
1768
- float prevAccumulatedAdvancement = 0F;
1839
+ // Restore the old context
1840
+ g.stroke(strokeColorBefore);
1841
+ if (!strokeBefore) {
1842
+ g.noStroke();
1843
+ }
1769
1844
 
1770
- /* Find in what command the advancement point is */
1771
- while (t > accumulatedAdvancement) {
1772
- indOfElement++;
1773
- prevAccumulatedAdvancement = accumulatedAdvancement;
1774
- accumulatedAdvancement += (lengthsCurves[indOfElement] / lengthCurve);
1775
1845
  }
1776
1846
 
1777
- float advOfElement = (t - prevAccumulatedAdvancement) / (lengthsCurves[indOfElement] / lengthCurve);
1778
-
1779
- float[] indAndAdv = new float[2];
1780
-
1781
- indAndAdv[0] = indOfElement;
1782
- indAndAdv[1] = PApplet.constrain(advOfElement, 0.0f, 1.0f);
1783
-
1784
- return indAndAdv;
1785
- }
1847
+ // Check whether to draw the stroke
1848
+ g.noFill();
1849
+ if (!strokeBefore) {
1850
+ // If there is no stroke to draw
1851
+ // we will still draw one the color of the fill in order to have antialiasing
1852
+ g.stroke(g.fillColor);
1853
+ g.strokeWeight(1F);
1854
+ }
1786
1855
 
1787
- private void appendChild(RShape nextshape) {
1788
- RShape[] newshapes;
1789
- if (children == null) {
1790
- newshapes = new RShape[1];
1791
- newshapes[0] = nextshape;
1792
- currentChild = 0;
1793
- } else {
1794
- newshapes = new RShape[this.children.length + 1];
1795
- System.arraycopy(this.children, 0, newshapes, 0, this.children.length);
1796
- newshapes[this.children.length] = nextshape;
1797
- currentChild++;
1856
+ for (int i = 0; i < numPaths; i++) {
1857
+ paths[i].draw(g);
1798
1858
  }
1799
- this.children = newshapes;
1800
- }
1801
1859
 
1802
- private void append(RPath nextpath) {
1803
- RPath[] newpaths;
1804
- if (paths == null) {
1805
- newpaths = new RPath[1];
1806
- newpaths[0] = nextpath;
1807
- currentPath = 0;
1860
+ // Restore the fill state and stroke state and color
1861
+ if (fillBefore) {
1862
+ g.fill(fillColorBefore);
1808
1863
  } else {
1809
- newpaths = new RPath[this.paths.length + 1];
1810
- System.arraycopy(this.paths, 0, newpaths, 0, this.paths.length);
1811
- newpaths[this.paths.length] = nextpath;
1812
- currentPath++;
1864
+ g.noFill();
1813
1865
  }
1814
- this.paths = newpaths;
1815
- }
1816
-
1817
- private void drawUsingInternalTesselator(PGraphics g) {
1818
- int numPaths = countPaths();
1819
-
1820
- if (numPaths != 0) {
1821
- if (isIn(g)) {
1822
-
1823
- // Save the information about the current context
1824
- boolean strokeBefore = g.stroke;
1825
- int strokeColorBefore = g.strokeColor;
1826
- float strokeWeightBefore = g.strokeWeight;
1827
- boolean fillBefore = g.fill;
1828
- int fillColorBefore = g.fillColor;
1829
-
1830
- // By default always drawy with an ADAPTATIVE segmentator
1831
- int lastSegmentator = RCommand.segmentType;
1832
- RCommand.setSegmentator(RCommand.ADAPTATIVE);
1833
-
1834
- // Check whether to draw the fill or not
1835
- if (g.fill) {
1836
- // Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
1837
- // 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
1838
-
1839
- // This is here because when rendering meshes we get unwanted lines between the triangles
1840
- g.noStroke();
1841
- try {
1842
- g.noSmooth();
1843
- } catch (Exception e) {
1844
- }
1845
-
1846
- RMesh tempMesh = this.toMesh();
1847
- tempMesh.draw(g);
1848
-
1849
- // Restore the old context
1850
- g.stroke(strokeColorBefore);
1851
- if (!strokeBefore) {
1852
- g.noStroke();
1853
- }
1854
-
1855
- }
1856
-
1857
- // Check whether to draw the stroke
1858
- g.noFill();
1859
- if (!strokeBefore) {
1860
- // If there is no stroke to draw
1861
- // we will still draw one the color of the fill in order to have antialiasing
1862
- g.stroke(g.fillColor);
1863
- g.strokeWeight(1F);
1864
- }
1865
-
1866
- for (int i = 0; i < numPaths; i++) {
1867
- paths[i].draw(g);
1868
- }
1869
-
1870
- // Restore the fill state and stroke state and color
1871
- if (fillBefore) {
1872
- g.fill(fillColorBefore);
1873
- } else {
1874
- g.noFill();
1875
- }
1876
- g.strokeWeight(strokeWeightBefore);
1877
- g.stroke(strokeColorBefore);
1878
- if (!strokeBefore) {
1879
- g.noStroke();
1880
- }
1881
-
1882
- // Restore the user set segmentator
1883
- RCommand.setSegmentator(lastSegmentator);
1884
- }
1866
+ g.strokeWeight(strokeWeightBefore);
1867
+ g.stroke(strokeColorBefore);
1868
+ if (!strokeBefore) {
1869
+ g.noStroke();
1885
1870
  }
1871
+
1872
+ // Restore the user set segmentator
1873
+ RCommand.setSegmentator(lastSegmentator);
1874
+ }
1886
1875
  }
1876
+ }
1887
1877
 
1888
- private void drawUsingInternalTesselator(PApplet p) {
1889
- int numPaths = countPaths();
1878
+ private void drawUsingInternalTesselator(PApplet p) {
1879
+ int numPaths = countPaths();
1890
1880
 
1891
- if (numPaths != 0) {
1892
- if (isIn(p)) {
1893
- // Save the information about the current context
1894
- boolean strokeBefore = p.g.stroke;
1895
- int strokeColorBefore = p.g.strokeColor;
1896
- float strokeWeightBefore = p.g.strokeWeight;
1897
- boolean fillBefore = p.g.fill;
1898
- int fillColorBefore = p.g.fillColor;
1881
+ if (numPaths != 0) {
1882
+ if (isIn(p)) {
1883
+ // Save the information about the current context
1884
+ boolean strokeBefore = p.g.stroke;
1885
+ int strokeColorBefore = p.g.strokeColor;
1886
+ float strokeWeightBefore = p.g.strokeWeight;
1887
+ boolean fillBefore = p.g.fill;
1888
+ int fillColorBefore = p.g.fillColor;
1899
1889
 
1900
- // By default always drawy with an ADAPTATIVE segmentator
1901
- int lastSegmentator = RCommand.segmentType;
1902
- RCommand.setSegmentator(RCommand.ADAPTATIVE);
1890
+ // By default always drawy with an ADAPTATIVE segmentator
1891
+ int lastSegmentator = RCommand.segmentType;
1892
+ RCommand.setSegmentator(RCommand.ADAPTATIVE);
1903
1893
 
1904
- // Check whether to draw the fill or not
1905
- if (p.g.fill) {
1894
+ // Check whether to draw the fill or not
1895
+ if (p.g.fill) {
1906
1896
  // Since we are drawing the different tristrips we must turn off the stroke
1907
- // or make it the same color as the fill
1908
- // NOTE: there's currently no way of drawing the outline of a mesh,
1909
- // since no information is kept about what vertices are at the edge
1910
-
1911
- // This is here because when rendering meshes we get unwanted lines between the triangles
1912
- p.noStroke();
1913
- try {
1914
- p.noSmooth();
1915
- } catch (Exception e) {
1916
- }
1917
-
1918
- RMesh tempMesh = this.toMesh();
1919
- if (tempMesh != null) {
1920
- tempMesh.draw(p);
1921
- }
1922
-
1923
- // Restore the old context
1924
- p.stroke(strokeColorBefore);
1925
- p.strokeWeight(strokeWeightBefore);
1926
- if (!strokeBefore) {
1927
- p.noStroke();
1928
- }
1929
-
1930
- }
1931
-
1932
- // Check whether to draw the stroke
1933
- p.noFill();
1934
- if ((fillBefore) || strokeBefore) {
1935
- if (!strokeBefore) {
1936
- // If there is no stroke to draw
1937
- // we will still draw one the color
1938
- // of the fill in order to have antialiasing
1939
- p.stroke(fillColorBefore);
1940
- p.strokeWeight(1F);
1941
- }
1942
-
1943
- for (int i = 0; i < numPaths; i++) {
1944
- paths[i].draw(p);
1945
- }
1946
-
1947
- // Restore the old context
1948
- if (fillBefore) {
1949
- p.fill(fillColorBefore);
1950
- }
1951
- p.strokeWeight(strokeWeightBefore);
1952
- p.stroke(strokeColorBefore);
1953
- if (!strokeBefore) {
1954
- p.noStroke();
1955
- }
1956
- }
1957
-
1958
- // Restore the user set segmentator
1959
- RCommand.setSegmentator(lastSegmentator);
1960
- }
1961
- }
1962
- }
1897
+ // or make it the same color as the fill
1898
+ // NOTE: there's currently no way of drawing the outline of a mesh,
1899
+ // since no information is kept about what vertices are at the edge
1900
+
1901
+ // This is here because when rendering meshes we get unwanted lines between the triangles
1902
+ p.noStroke();
1903
+ try {
1904
+ p.noSmooth();
1905
+ } catch (Exception e) {
1906
+ }
1907
+
1908
+ RMesh tempMesh = this.toMesh();
1909
+ if (tempMesh != null) {
1910
+ tempMesh.draw(p);
1911
+ }
1912
+
1913
+ // Restore the old context
1914
+ p.stroke(strokeColorBefore);
1915
+ p.strokeWeight(strokeWeightBefore);
1916
+ if (!strokeBefore) {
1917
+ p.noStroke();
1918
+ }
1919
+
1920
+ }
1921
+
1922
+ // Check whether to draw the stroke
1923
+ p.noFill();
1924
+ if ((fillBefore) || strokeBefore) {
1925
+ if (!strokeBefore) {
1926
+ // If there is no stroke to draw
1927
+ // we will still draw one the color
1928
+ // of the fill in order to have antialiasing
1929
+ p.stroke(fillColorBefore);
1930
+ p.strokeWeight(1F);
1931
+ }
1932
+
1933
+ for (int i = 0; i < numPaths; i++) {
1934
+ paths[i].draw(p);
1935
+ }
1936
+
1937
+ // Restore the old context
1938
+ if (fillBefore) {
1939
+ p.fill(fillColorBefore);
1940
+ }
1941
+ p.strokeWeight(strokeWeightBefore);
1942
+ p.stroke(strokeColorBefore);
1943
+ if (!strokeBefore) {
1944
+ p.noStroke();
1945
+ }
1946
+ }
1947
+
1948
+ // Restore the user set segmentator
1949
+ RCommand.setSegmentator(lastSegmentator);
1950
+ }
1951
+ }
1952
+ }
1953
+
1954
+ private void drawUsingBreakShape(PGraphics g) {
1955
+ int numPaths = countPaths();
1956
+ if (numPaths != 0) {
1957
+ if (isIn(g)) {
1958
+ boolean closed = false;
1959
+ boolean useContours = (numPaths > 1);
1960
+ g.beginShape();
1961
+ for (int i = 0; i < numPaths; i++) {
1962
+ if (useContours && i > 0) {
1963
+ g.beginContour();
1964
+ }
1963
1965
 
1964
- private void drawUsingBreakShape(PGraphics g) {
1965
- int numPaths = countPaths();
1966
- if (numPaths != 0) {
1967
- if (isIn(g)) {
1968
- boolean closed = false;
1969
- boolean useContours = (numPaths > 1);
1970
- g.beginShape();
1971
- for (int i = 0; i < numPaths; i++) {
1972
- if (useContours && i > 0) {
1973
- g.beginContour();
1974
- }
1975
-
1976
- RPath path = paths[i];
1977
- closed |= path.closed;
1978
-
1979
- for (int j = 0; j < path.countCommands(); j++) {
1980
- RPoint[] pnts = path.commands[j].getHandles();
1981
- if (j == 0) {
1982
- g.vertex(pnts[0].x, pnts[0].y);
1983
- }
1984
- switch (path.commands[j].getCommandType()) {
1985
- case RCommand.LINETO:
1986
- g.vertex(pnts[1].x, pnts[1].y);
1987
- break;
1988
- case RCommand.QUADBEZIERTO:
1989
- g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[2].x, pnts[2].y);
1990
- break;
1991
- case RCommand.CUBICBEZIERTO:
1992
- g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[3].x, pnts[3].y);
1993
- break;
1994
- }
1995
- }
1996
-
1997
- if (useContours && i > 0) {
1998
- g.endContour();
1999
- }
2000
-
2001
- }
2002
- g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
1966
+ RPath path = paths[i];
1967
+ closed |= path.closed;
2003
1968
 
1969
+ for (int j = 0; j < path.countCommands(); j++) {
1970
+ RPoint[] pnts = path.commands[j].getHandles();
1971
+ if (j == 0) {
1972
+ g.vertex(pnts[0].x, pnts[0].y);
1973
+ }
1974
+ switch (path.commands[j].getCommandType()) {
1975
+ case RCommand.LINETO:
1976
+ g.vertex(pnts[1].x, pnts[1].y);
1977
+ break;
1978
+ case RCommand.QUADBEZIERTO:
1979
+ g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[2].x, pnts[2].y);
1980
+ break;
1981
+ case RCommand.CUBICBEZIERTO:
1982
+ g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[3].x, pnts[3].y);
1983
+ break;
2004
1984
  }
1985
+ }
1986
+
1987
+ if (useContours && i > 0) {
1988
+ g.endContour();
1989
+ }
1990
+
2005
1991
  }
2006
- }
1992
+ g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
2007
1993
 
2008
- private void drawUsingBreakShape(PApplet g) {
2009
- int numPaths = countPaths();
2010
- if (numPaths != 0) {
2011
- if (isIn(g)) {
2012
- boolean closed = false;
2013
- boolean useContours = (numPaths > 1);
2014
- g.beginShape();
2015
- for (int i = 0; i < numPaths; i++) {
2016
- if (useContours && i > 0) {
2017
- g.beginContour();
2018
- }
2019
-
2020
- RPath path = paths[i];
2021
- closed |= path.closed;
2022
- float firstx = 0;
2023
- float firsty = 0;
2024
- for (int j = 0; j < path.countCommands(); j++) {
2025
- RPoint[] pnts = path.commands[j].getHandles();
2026
- if (j == 0) {
2027
- g.vertex(pnts[0].x, pnts[0].y);
2028
- }
2029
- switch (path.commands[j].getCommandType()) {
2030
- case RCommand.LINETO:
2031
- g.vertex(pnts[1].x, pnts[1].y);
2032
- break;
2033
- case RCommand.QUADBEZIERTO:
2034
- g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[2].x, pnts[2].y);
2035
- break;
2036
- case RCommand.CUBICBEZIERTO:
2037
- g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[3].x, pnts[3].y);
2038
- break;
2039
- }
2040
- }
2041
- if (useContours && i > 0) {
2042
- g.endContour();
2043
- }
2044
-
2045
- }
2046
- g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
1994
+ }
1995
+ }
1996
+ }
2047
1997
 
1998
+ private void drawUsingBreakShape(PApplet g) {
1999
+ int numPaths = countPaths();
2000
+ if (numPaths != 0) {
2001
+ if (isIn(g)) {
2002
+ boolean closed = false;
2003
+ boolean useContours = (numPaths > 1);
2004
+ g.beginShape();
2005
+ for (int i = 0; i < numPaths; i++) {
2006
+ if (useContours && i > 0) {
2007
+ g.beginContour();
2008
+ }
2009
+
2010
+ RPath path = paths[i];
2011
+ closed |= path.closed;
2012
+ float firstx = 0;
2013
+ float firsty = 0;
2014
+ for (int j = 0; j < path.countCommands(); j++) {
2015
+ RPoint[] pnts = path.commands[j].getHandles();
2016
+ if (j == 0) {
2017
+ g.vertex(pnts[0].x, pnts[0].y);
2048
2018
  }
2019
+ switch (path.commands[j].getCommandType()) {
2020
+ case RCommand.LINETO:
2021
+ g.vertex(pnts[1].x, pnts[1].y);
2022
+ break;
2023
+ case RCommand.QUADBEZIERTO:
2024
+ g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[2].x, pnts[2].y);
2025
+ break;
2026
+ case RCommand.CUBICBEZIERTO:
2027
+ g.bezierVertex(pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[3].x, pnts[3].y);
2028
+ break;
2029
+ }
2030
+ }
2031
+ if (useContours && i > 0) {
2032
+ g.endContour();
2033
+ }
2034
+
2049
2035
  }
2036
+ g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
2037
+
2038
+ }
2050
2039
  }
2040
+ }
2051
2041
 
2052
2042
  }