geomerative 1.1.0-java → 2.0.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.mvn/extensions.xml +1 -1
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -1
  5. data/CHANGELOG.md +3 -0
  6. data/COPYING.md +1 -1
  7. data/README.md +0 -1
  8. data/Rakefile +2 -15
  9. data/docs/_includes/header.html +6 -6
  10. data/docs/_includes/icon-github.svg +3 -1
  11. data/docs/_includes/icon-twitter.svg +3 -1
  12. data/docs/_includes/navigation.html +18 -18
  13. data/docs/_sass/_base.scss +79 -79
  14. data/docs/_sass/_layout.scss +137 -137
  15. data/docs/_sass/_syntax-highlighting.scss +64 -64
  16. data/docs/index.html +18 -18
  17. data/examples/data/bot1.svg +1 -1
  18. data/examples/data/lion.svg +156 -156
  19. data/examples/data/ruby.svg +1 -1
  20. data/geomerative.gemspec +1 -2
  21. data/lib/geomerative/version.rb +1 -1
  22. data/mvnw +234 -0
  23. data/mvnw.cmd +145 -0
  24. data/pom.rb +14 -13
  25. data/pom.xml +14 -13
  26. data/src/geomerative/FastRClip.java +2149 -2156
  27. data/src/geomerative/RClip.java +2237 -2539
  28. data/src/geomerative/RClosest.java +33 -31
  29. data/src/geomerative/RCommand.java +1750 -1758
  30. data/src/geomerative/RContour.java +290 -292
  31. data/src/geomerative/RFont.java +277 -246
  32. data/src/geomerative/RG.java +722 -727
  33. data/src/geomerative/RGeomElem.java +967 -960
  34. data/src/geomerative/RGroup.java +508 -467
  35. data/src/geomerative/RMatrix.java +304 -289
  36. data/src/geomerative/RMesh.java +241 -229
  37. data/src/geomerative/RPath.java +924 -925
  38. data/src/geomerative/RPoint.java +391 -391
  39. data/src/geomerative/RPolygon.java +998 -988
  40. data/src/geomerative/RRectangle.java +43 -52
  41. data/src/geomerative/RSVG.java +480 -516
  42. data/src/geomerative/RShape.java +1767 -1777
  43. data/src/geomerative/RStrip.java +173 -176
  44. data/src/geomerative/RStyle.java +197 -194
  45. data/src/org/apache/batik/svggen/font/Font.java +141 -142
  46. data/src/org/apache/batik/svggen/font/Glyph.java +102 -71
  47. data/src/org/apache/batik/svggen/font/Point.java +12 -12
  48. data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +14 -12
  49. data/src/org/apache/batik/svggen/font/table/ClassDef.java +12 -12
  50. data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +27 -24
  51. data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +20 -17
  52. data/src/org/apache/batik/svggen/font/table/CmapFormat.java +43 -43
  53. data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +33 -26
  54. data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +25 -20
  55. data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +106 -96
  56. data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +36 -32
  57. data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +69 -49
  58. data/src/org/apache/batik/svggen/font/table/CmapTable.java +50 -50
  59. data/src/org/apache/batik/svggen/font/table/Coverage.java +19 -19
  60. data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +30 -27
  61. data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +26 -24
  62. data/src/org/apache/batik/svggen/font/table/CvtTable.java +16 -16
  63. data/src/org/apache/batik/svggen/font/table/Device.java +32 -32
  64. data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +39 -39
  65. data/src/org/apache/batik/svggen/font/table/Feature.java +26 -23
  66. data/src/org/apache/batik/svggen/font/table/FeatureList.java +37 -35
  67. data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +22 -22
  68. data/src/org/apache/batik/svggen/font/table/FeatureTags.java +4 -3
  69. data/src/org/apache/batik/svggen/font/table/FpgmTable.java +9 -9
  70. data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +134 -132
  71. data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +123 -122
  72. data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +44 -44
  73. data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +110 -109
  74. data/src/org/apache/batik/svggen/font/table/GlyfTable.java +46 -46
  75. data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +25 -13
  76. data/src/org/apache/batik/svggen/font/table/GposTable.java +26 -23
  77. data/src/org/apache/batik/svggen/font/table/GsubTable.java +85 -82
  78. data/src/org/apache/batik/svggen/font/table/HeadTable.java +131 -131
  79. data/src/org/apache/batik/svggen/font/table/HheaTable.java +80 -80
  80. data/src/org/apache/batik/svggen/font/table/HmtxTable.java +50 -49
  81. data/src/org/apache/batik/svggen/font/table/KernSubtable.java +29 -27
  82. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +35 -32
  83. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +28 -26
  84. data/src/org/apache/batik/svggen/font/table/KernTable.java +36 -31
  85. data/src/org/apache/batik/svggen/font/table/KerningPair.java +27 -23
  86. data/src/org/apache/batik/svggen/font/table/LangSys.java +28 -26
  87. data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +22 -22
  88. data/src/org/apache/batik/svggen/font/table/Ligature.java +24 -24
  89. data/src/org/apache/batik/svggen/font/table/LigatureSet.java +24 -24
  90. data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +9 -9
  91. data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +30 -30
  92. data/src/org/apache/batik/svggen/font/table/LocaTable.java +37 -37
  93. data/src/org/apache/batik/svggen/font/table/Lookup.java +41 -40
  94. data/src/org/apache/batik/svggen/font/table/LookupList.java +34 -34
  95. data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +7 -5
  96. data/src/org/apache/batik/svggen/font/table/MaxpTable.java +96 -96
  97. data/src/org/apache/batik/svggen/font/table/NameRecord.java +64 -65
  98. data/src/org/apache/batik/svggen/font/table/NameTable.java +33 -33
  99. data/src/org/apache/batik/svggen/font/table/Os2Table.java +196 -196
  100. data/src/org/apache/batik/svggen/font/table/Panose.java +14 -12
  101. data/src/org/apache/batik/svggen/font/table/PostTable.java +338 -338
  102. data/src/org/apache/batik/svggen/font/table/PrepTable.java +9 -9
  103. data/src/org/apache/batik/svggen/font/table/Program.java +15 -15
  104. data/src/org/apache/batik/svggen/font/table/RangeRecord.java +26 -25
  105. data/src/org/apache/batik/svggen/font/table/Script.java +38 -38
  106. data/src/org/apache/batik/svggen/font/table/ScriptList.java +42 -42
  107. data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +22 -22
  108. data/src/org/apache/batik/svggen/font/table/ScriptTags.java +2 -1
  109. data/src/org/apache/batik/svggen/font/table/SingleSubst.java +15 -16
  110. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +33 -33
  111. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +32 -32
  112. data/src/org/apache/batik/svggen/font/table/Table.java +171 -170
  113. data/src/org/apache/batik/svggen/font/table/TableDirectory.java +55 -55
  114. data/src/org/apache/batik/svggen/font/table/TableFactory.java +92 -93
  115. metadata +10 -11
  116. data/.travis.yml +0 -9
@@ -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
  }