geomerative 0.4.3-java → 2.1.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.mvn/extensions.xml +1 -1
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -1
  5. data/CHANGELOG.md +19 -1
  6. data/COPYING.md +1 -1
  7. data/README.md +2 -2
  8. data/Rakefile +2 -15
  9. data/docs/_config.yml +8 -0
  10. data/docs/_includes/head.html +7 -6
  11. data/docs/_includes/header.html +6 -6
  12. data/docs/_includes/icon-github.svg +3 -1
  13. data/docs/_includes/icon-twitter.svg +3 -1
  14. data/docs/_includes/navigation.html +24 -0
  15. data/docs/_sass/_base.scss +79 -79
  16. data/docs/_sass/_layout.scss +137 -137
  17. data/docs/_sass/_syntax-highlighting.scss +64 -64
  18. data/docs/index.html +18 -18
  19. data/examples/README.md +1 -1
  20. data/examples/data/bot1.svg +1 -1
  21. data/examples/data/lion.svg +156 -156
  22. data/examples/data/ruby.svg +1 -1
  23. data/examples/jruby_merge.rb +1 -1
  24. data/examples/{f_agent.rb → library/f_agent/f_agent.rb} +0 -0
  25. data/examples/{font_agent.rb → library/font_agent/font_agent.rb} +2 -1
  26. data/examples/text_on_geomerative_path.rb +3 -2
  27. data/examples/typo_deform.rb +2 -2
  28. data/examples/typo_extra_bright.rb +1 -1
  29. data/geomerative.gemspec +3 -6
  30. data/lib/geomerative/version.rb +1 -1
  31. data/lib/geomerative.jar +0 -0
  32. data/lib/geomerative.rb +10 -10
  33. data/mvnw +234 -0
  34. data/mvnw.cmd +145 -0
  35. data/pom.rb +14 -16
  36. data/pom.xml +13 -19
  37. data/src/geomerative/FastRClip.java +2050 -2334
  38. data/src/geomerative/RClip.java +2237 -2539
  39. data/src/geomerative/RClosest.java +33 -31
  40. data/src/geomerative/RCommand.java +1750 -1758
  41. data/src/geomerative/RContour.java +290 -292
  42. data/src/geomerative/RFont.java +277 -246
  43. data/src/geomerative/RG.java +722 -727
  44. data/src/geomerative/RGeomElem.java +967 -962
  45. data/src/geomerative/RGroup.java +508 -467
  46. data/src/geomerative/RMatrix.java +304 -289
  47. data/src/geomerative/RMesh.java +241 -229
  48. data/src/geomerative/RPath.java +924 -926
  49. data/src/geomerative/RPoint.java +391 -391
  50. data/src/geomerative/RPolygon.java +1017 -1013
  51. data/src/geomerative/RRectangle.java +43 -52
  52. data/src/geomerative/RSVG.java +480 -516
  53. data/src/geomerative/RShape.java +1767 -1777
  54. data/src/geomerative/RStrip.java +173 -176
  55. data/src/geomerative/RStyle.java +197 -194
  56. data/src/module-info.java +4 -0
  57. data/src/org/apache/batik/svggen/font/Font.java +141 -142
  58. data/src/org/apache/batik/svggen/font/Glyph.java +102 -71
  59. data/src/org/apache/batik/svggen/font/Point.java +12 -12
  60. data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +14 -12
  61. data/src/org/apache/batik/svggen/font/table/ClassDef.java +12 -12
  62. data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +27 -24
  63. data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +20 -17
  64. data/src/org/apache/batik/svggen/font/table/CmapFormat.java +43 -43
  65. data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +33 -26
  66. data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +25 -20
  67. data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +106 -96
  68. data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +36 -32
  69. data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +69 -49
  70. data/src/org/apache/batik/svggen/font/table/CmapTable.java +50 -50
  71. data/src/org/apache/batik/svggen/font/table/Coverage.java +19 -19
  72. data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +30 -27
  73. data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +26 -24
  74. data/src/org/apache/batik/svggen/font/table/CvtTable.java +16 -16
  75. data/src/org/apache/batik/svggen/font/table/Device.java +32 -32
  76. data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +39 -39
  77. data/src/org/apache/batik/svggen/font/table/Feature.java +26 -23
  78. data/src/org/apache/batik/svggen/font/table/FeatureList.java +37 -35
  79. data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +22 -22
  80. data/src/org/apache/batik/svggen/font/table/FeatureTags.java +4 -3
  81. data/src/org/apache/batik/svggen/font/table/FpgmTable.java +9 -9
  82. data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +134 -132
  83. data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +123 -122
  84. data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +44 -44
  85. data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +110 -109
  86. data/src/org/apache/batik/svggen/font/table/GlyfTable.java +46 -46
  87. data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +25 -13
  88. data/src/org/apache/batik/svggen/font/table/GposTable.java +26 -23
  89. data/src/org/apache/batik/svggen/font/table/GsubTable.java +85 -82
  90. data/src/org/apache/batik/svggen/font/table/HeadTable.java +131 -131
  91. data/src/org/apache/batik/svggen/font/table/HheaTable.java +80 -80
  92. data/src/org/apache/batik/svggen/font/table/HmtxTable.java +50 -49
  93. data/src/org/apache/batik/svggen/font/table/KernSubtable.java +29 -27
  94. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +35 -32
  95. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +28 -26
  96. data/src/org/apache/batik/svggen/font/table/KernTable.java +36 -31
  97. data/src/org/apache/batik/svggen/font/table/KerningPair.java +27 -23
  98. data/src/org/apache/batik/svggen/font/table/LangSys.java +28 -26
  99. data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +22 -22
  100. data/src/org/apache/batik/svggen/font/table/Ligature.java +24 -24
  101. data/src/org/apache/batik/svggen/font/table/LigatureSet.java +24 -24
  102. data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +9 -9
  103. data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +30 -30
  104. data/src/org/apache/batik/svggen/font/table/LocaTable.java +37 -37
  105. data/src/org/apache/batik/svggen/font/table/Lookup.java +41 -40
  106. data/src/org/apache/batik/svggen/font/table/LookupList.java +34 -34
  107. data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +7 -5
  108. data/src/org/apache/batik/svggen/font/table/MaxpTable.java +96 -96
  109. data/src/org/apache/batik/svggen/font/table/NameRecord.java +64 -65
  110. data/src/org/apache/batik/svggen/font/table/NameTable.java +33 -33
  111. data/src/org/apache/batik/svggen/font/table/Os2Table.java +196 -196
  112. data/src/org/apache/batik/svggen/font/table/Panose.java +14 -12
  113. data/src/org/apache/batik/svggen/font/table/PostTable.java +338 -338
  114. data/src/org/apache/batik/svggen/font/table/PrepTable.java +9 -9
  115. data/src/org/apache/batik/svggen/font/table/Program.java +15 -15
  116. data/src/org/apache/batik/svggen/font/table/RangeRecord.java +26 -25
  117. data/src/org/apache/batik/svggen/font/table/Script.java +38 -38
  118. data/src/org/apache/batik/svggen/font/table/ScriptList.java +42 -42
  119. data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +22 -22
  120. data/src/org/apache/batik/svggen/font/table/ScriptTags.java +2 -1
  121. data/src/org/apache/batik/svggen/font/table/SingleSubst.java +15 -16
  122. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +33 -33
  123. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +32 -32
  124. data/src/org/apache/batik/svggen/font/table/Table.java +171 -170
  125. data/src/org/apache/batik/svggen/font/table/TableDirectory.java +55 -55
  126. data/src/org/apache/batik/svggen/font/table/TableFactory.java +92 -93
  127. metadata +18 -19
  128. data/.travis.yml +0 -10
  129. data/calculate_torsional_angle.rb +0 -17
@@ -28,495 +28,494 @@ import processing.core.PGraphics;
28
28
  * Paths are ordered lists of commands (RCommand) which define the outlines of
29
29
  * shapes. Paths can be self-intersecting.
30
30
  *
31
- * @eexample RPath
32
- * @usage Geometry
33
- * @related RCommand
34
- * @related RPolygon
35
- * @extended
31
+ RPath
32
+ * Geometry
33
+ * RCommand
34
+ * RPolygon
35
+
36
36
  *
37
37
  */
38
38
  public class RPath extends RGeomElem {
39
39
 
40
- /**
41
- * @invisible
42
- */
43
- public int type = RGeomElem.SUBSHAPE;
44
-
45
- /**
46
- * Array of RCommand objects holding the commands of the path.
47
- *
48
- * @eexample commands
49
- * @related RCommand
50
- * @related countCommands ( )
51
- */
52
- public RCommand[] commands;
53
-
54
- /**
55
- * Last point from where to add the next command. Initialized to (0, 0).
56
- *
57
- * @eexample lastPoint
58
- * @related RPoint
59
- * @invisible
60
- */
61
- public RPoint lastPoint;
62
-
63
- boolean closed = false;
64
-
65
- /**
66
- * Create a new empty path.
67
- *
68
- * @eexample RPath
69
- */
70
- public RPath() {
71
- this.lastPoint = new RPoint();
72
- }
73
-
74
- /**
75
- * Create a new path, given an array of points.
76
- *
77
- * @eexample RPath
78
- * @param points the points of the new path
79
- */
80
- public RPath(RPoint[] points) {
81
- if (points == null) {
82
- return;
83
- }
84
- this.lastPoint = points[0];
85
-
86
- for (int i = 1; i < points.length; i++) {
87
- this.addLineTo(points[i]);
88
- }
89
-
40
+ /**
41
+ *
42
+ */
43
+ public int type = RGeomElem.SUBSHAPE;
44
+
45
+ /**
46
+ * Array of RCommand objects holding the commands of the path.
47
+ *
48
+ commands
49
+ * RCommand
50
+ * countCommands ( )
51
+ */
52
+ public RCommand[] commands;
53
+
54
+ /**
55
+ * Last point from where to add the next command. Initialized to (0, 0).
56
+ *
57
+ lastPoint
58
+ * RPoint
59
+ *
60
+ */
61
+ public RPoint lastPoint;
62
+
63
+ boolean closed = false;
64
+
65
+ /**
66
+ * Create a new empty path.
67
+ *
68
+ RPath
69
+ */
70
+ public RPath() {
71
+ this.lastPoint = new RPoint();
72
+ }
73
+
74
+ /**
75
+ * Create a new path, given an array of points.
76
+ *
77
+ RPath
78
+ * @param points the points of the new path
79
+ */
80
+ public RPath(RPoint[] points) {
81
+ if (points == null) {
82
+ return;
90
83
  }
84
+ this.lastPoint = points[0];
91
85
 
92
- /**
93
- * Create a new path, given the coordinates of the first point.
94
- *
95
- * @eexample RPath
96
- * @param x x coordinate of the first point of the new path
97
- * @param y y coordinate of the first point of the new path
98
- */
99
- public RPath(float x, float y) {
100
- this.lastPoint = new RPoint(x, y);
86
+ for (int i = 1; i < points.length; i++) {
87
+ this.addLineTo(points[i]);
101
88
  }
102
89
 
103
- /**
104
- * Create a new path, given the first point.
105
- *
106
- * @eexample RPath
107
- * @param p first point of the new path
108
- */
109
- public RPath(RPoint p) {
110
- this.lastPoint = p;
90
+ }
91
+
92
+ /**
93
+ * Create a new path, given the coordinates of the first point.
94
+ *
95
+ RPath
96
+ * @param x x coordinate of the first point of the new path
97
+ * @param y y coordinate of the first point of the new path
98
+ */
99
+ public RPath(float x, float y) {
100
+ this.lastPoint = new RPoint(x, y);
101
+ }
102
+
103
+ /**
104
+ * Create a new path, given the first point.
105
+ *
106
+ RPath
107
+ * @param p first point of the new path
108
+ */
109
+ public RPath(RPoint p) {
110
+ this.lastPoint = p;
111
+ }
112
+
113
+ /**
114
+ * Copy a path.
115
+ *
116
+ RPath
117
+ * @param s path to be copied
118
+ */
119
+ public RPath(RPath s) {
120
+ int numCommands = s.countCommands();
121
+ if (numCommands != 0) {
122
+ lastPoint = new RPoint(s.commands[0].startPoint);
123
+ for (int i = 0; i < numCommands; i++) {
124
+ this.append(new RCommand(s.commands[i], lastPoint));
125
+ lastPoint = commands[i].endPoint;
126
+ }
111
127
  }
112
-
113
- /**
114
- * Copy a path.
115
- *
116
- * @eexample RPath
117
- * @param s path to be copied
118
- */
119
- public RPath(RPath s) {
120
- int numCommands = s.countCommands();
121
- if (numCommands != 0) {
122
- lastPoint = new RPoint(s.commands[0].startPoint);
123
- for (int i = 0; i < numCommands; i++) {
124
- this.append(new RCommand(s.commands[i], lastPoint));
125
- lastPoint = commands[i].endPoint;
126
- }
127
- }
128
-
129
- closed = s.closed;
130
- setStyle(s);
131
- }
132
-
133
- public RPath(RCommand c) {
134
- this();
135
- this.addCommand(c);
128
+ closed = s.closed;
129
+ setStyle(s);
130
+ }
131
+
132
+ public RPath(RCommand c) {
133
+ this();
134
+ this.addCommand(c);
135
+ }
136
+
137
+ /**
138
+ * Use this method to count the number of commands in the contour.
139
+ *
140
+ countCommands
141
+ * @return int, the number commands in the contour
142
+ */
143
+ public int countCommands() {
144
+ if (this.commands == null) {
145
+ return 0;
136
146
  }
137
147
 
138
- /**
139
- * Use this method to count the number of commands in the contour.
140
- *
141
- * @eexample countCommands
142
- * @return int, the number commands in the contour
143
- */
144
- public int countCommands() {
145
- if (this.commands == null) {
146
- return 0;
148
+ return this.commands.length;
149
+ }
150
+
151
+ /**
152
+ * Use this to return the start, control and end points of the path. It
153
+ * returns the points in the way of an array of RPoint.
154
+ *
155
+ getHandles
156
+ * @return RPoint[], the start, control and end points returned in an array.
157
+ *
158
+ */
159
+ @Override
160
+ public RPoint[] getHandles() {
161
+ int numCommands = countCommands();
162
+
163
+ RPoint[] result = null;
164
+ RPoint[] newresult;
165
+ for (int i = 0; i < numCommands; i++) {
166
+ RPoint[] newPoints = commands[i].getHandles();
167
+ if (newPoints != null) {
168
+ if (result == null) {
169
+ result = new RPoint[newPoints.length];
170
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
171
+ } else {
172
+ int overlap = 0;
173
+ if (newPoints[0] == result[result.length - 1]) {
174
+ overlap = 1;
175
+ }
176
+ newresult = new RPoint[result.length + newPoints.length - overlap];
177
+ System.arraycopy(result, 0, newresult, 0, result.length);
178
+ System.arraycopy(newPoints, overlap, newresult, result.length, newPoints.length - overlap);
179
+ result = newresult;
147
180
  }
148
-
149
- return this.commands.length;
181
+ }
150
182
  }
151
-
152
- /**
153
- * Use this to return the start, control and end points of the path. It
154
- * returns the points in the way of an array of RPoint.
155
- *
156
- * @eexample getHandles
157
- * @return RPoint[], the start, control and end points returned in an array.
158
- *
159
- */
160
- @Override
161
- public RPoint[] getHandles() {
162
- int numCommands = countCommands();
163
-
164
- RPoint[] result = null;
165
- RPoint[] newresult;
166
- for (int i = 0; i < numCommands; i++) {
167
- RPoint[] newPoints = commands[i].getHandles();
168
- if (newPoints != null) {
169
- if (result == null) {
170
- result = new RPoint[newPoints.length];
171
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
172
- } else {
173
- int overlap = 0;
174
- if (newPoints[0] == result[result.length - 1]) {
175
- overlap = 1;
176
- }
177
- newresult = new RPoint[result.length + newPoints.length - overlap];
178
- System.arraycopy(result, 0, newresult, 0, result.length);
179
- System.arraycopy(newPoints, overlap, newresult, result.length, newPoints.length - overlap);
180
- result = newresult;
181
- }
182
- }
183
- }
184
- return result;
183
+ return result;
184
+ }
185
+
186
+ /**
187
+ * Use this to return the points on the curve. It returns the points in the
188
+ * way of an array of RPoint.
189
+ *
190
+ getPoints
191
+ * @return RPoint[], the vertices returned in an array.
192
+ *
193
+ */
194
+ @Override
195
+ public RPoint[] getPoints() {
196
+ int numCommands = countCommands();
197
+ if (numCommands == 0) {
198
+ return null;
185
199
  }
186
200
 
187
- /**
188
- * Use this to return the points on the curve. It returns the points in the
189
- * way of an array of RPoint.
190
- *
191
- * @eexample getPoints
192
- * @return RPoint[], the vertices returned in an array.
193
- *
194
- */
195
- @Override
196
- public RPoint[] getPoints() {
197
- int numCommands = countCommands();
198
- if (numCommands == 0) {
199
- return null;
200
- }
201
-
202
- // Add the curve points of each command
203
- // First set the accumulated offset to the value of the inital offset
204
- RCommand.segmentAccOffset = RCommand.segmentOffset;
205
- RPoint[] result = null;
206
- RPoint[] newresult;
207
- for (int i = 0; i < numCommands; i++) {
208
- RPoint[] newPoints = commands[i].getPoints(false);
209
- if (newPoints != null) {
210
- if (result == null) {
211
- result = new RPoint[newPoints.length];
212
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
213
- } else {
214
- // Check for overlapping
215
- // Overlapping happens when the last point of the last command
216
- // is the same as the first point of the current command
217
- RPoint lastp = result[result.length - 1];
218
- RPoint firstp = newPoints[0];
219
- int overlap = 0;
220
- if ((lastp.x == firstp.x) && (lastp.y == firstp.y)) {
221
- overlap = 1;
222
- }
223
- newresult = new RPoint[result.length + newPoints.length - overlap];
224
- System.arraycopy(result, 0, newresult, 0, result.length);
225
- System.arraycopy(newPoints, overlap, newresult, result.length, newPoints.length - overlap);
226
- result = newresult;
227
- }
228
- }
229
- }
230
- // Always add last point
201
+ // Add the curve points of each command
202
+ // First set the accumulated offset to the value of the inital offset
203
+ RCommand.segmentAccOffset = RCommand.segmentOffset;
204
+ RPoint[] result = null;
205
+ RPoint[] newresult;
206
+ for (int i = 0; i < numCommands; i++) {
207
+ RPoint[] newPoints = commands[i].getPoints(false);
208
+ if (newPoints != null) {
231
209
  if (result == null) {
232
- return result;
210
+ result = new RPoint[newPoints.length];
211
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
212
+ } else {
213
+ // Check for overlapping
214
+ // Overlapping happens when the last point of the last command
215
+ // is the same as the first point of the current command
216
+ RPoint lastp = result[result.length - 1];
217
+ RPoint firstp = newPoints[0];
218
+ int overlap = 0;
219
+ if ((lastp.x == firstp.x) && (lastp.y == firstp.y)) {
220
+ overlap = 1;
221
+ }
222
+ newresult = new RPoint[result.length + newPoints.length - overlap];
223
+ System.arraycopy(result, 0, newresult, 0, result.length);
224
+ System.arraycopy(newPoints, overlap, newresult, result.length, newPoints.length - overlap);
225
+ result = newresult;
233
226
  }
234
- newresult = new RPoint[result.length + 1];
235
- System.arraycopy(result, 0, newresult, 0, result.length);
236
- newresult[newresult.length - 1] = new RPoint(commands[numCommands - 1].endPoint);
237
- return newresult;
227
+ }
238
228
  }
239
-
240
- /**
241
- * Use this to return the points of each path of the path. It returns the
242
- * points in the way of an array of array of RPoint.
243
- *
244
- * @eexample RGroup_getPoints
245
- * @return RPoint[], the points returned in an array.
246
- *
247
- */
248
- @Override
249
- public RPoint[][] getPointsInPaths() {
250
- RPoint[][] result = {this.getPoints()};
251
- return result;
229
+ // Always add last point
230
+ if (result == null) {
231
+ return result;
252
232
  }
253
-
254
- /**
255
- * Use this to return the handles of each path of the path. It returns the
256
- * handles in the way of an array of array of RPoint.
257
- *
258
- * @eexample RGroup_getHandles
259
- * @return RPoint[], the handles returned in an array.
260
- *
261
- */
262
- @Override
263
- public RPoint[][] getHandlesInPaths() {
264
- RPoint[][] result = {this.getHandles()};
265
- return result;
233
+ newresult = new RPoint[result.length + 1];
234
+ System.arraycopy(result, 0, newresult, 0, result.length);
235
+ newresult[newresult.length - 1] = new RPoint(commands[numCommands - 1].endPoint);
236
+ return newresult;
237
+ }
238
+
239
+ /**
240
+ * Use this to return the points of each path of the path. It returns the
241
+ * points in the way of an array of array of RPoint.
242
+ *
243
+ RGroup_getPoints
244
+ * @return RPoint[], the points returned in an array.
245
+ *
246
+ */
247
+ @Override
248
+ public RPoint[][] getPointsInPaths() {
249
+ RPoint[][] result = {this.getPoints()};
250
+ return result;
251
+ }
252
+
253
+ /**
254
+ * Use this to return the handles of each path of the path. It returns the
255
+ * handles in the way of an array of array of RPoint.
256
+ *
257
+ RGroup_getHandles
258
+ * @return RPoint[], the handles returned in an array.
259
+ *
260
+ */
261
+ @Override
262
+ public RPoint[][] getHandlesInPaths() {
263
+ RPoint[][] result = {this.getHandles()};
264
+ return result;
265
+ }
266
+
267
+ /**
268
+ * Use this to return the tangents of each path of the path. It returns the
269
+ * tangents in the way of an array of array of RPoint.
270
+ *
271
+ RGroup_getTangents
272
+ * @return RPoint[], the tangents returned in an array.
273
+ *
274
+ */
275
+ @Override
276
+ public RPoint[][] getTangentsInPaths() {
277
+ RPoint[][] result = {this.getTangents()};
278
+ return result;
279
+ }
280
+
281
+ @Override
282
+ protected void calculateCurveLengths() {
283
+ lenCurves = new float[countCommands()];
284
+ lenCurve = 0F;
285
+ for (int i = 0; i < countCommands(); i++) {
286
+ lenCurves[i] = commands[i].getCurveLength();
287
+ lenCurve += lenCurves[i];
266
288
  }
267
-
268
- /**
269
- * Use this to return the tangents of each path of the path. It returns the
270
- * tangents in the way of an array of array of RPoint.
271
- *
272
- * @eexample RGroup_getTangents
273
- * @return RPoint[], the tangents returned in an array.
274
- *
275
- */
276
- @Override
277
- public RPoint[][] getTangentsInPaths() {
278
- RPoint[][] result = {this.getTangents()};
279
- return result;
289
+ }
290
+
291
+ /**
292
+ * Use this to return the tangents on the curve. It returns the vectors in the
293
+ * way of an array of RPoint.
294
+ *
295
+ getTangents
296
+ * @return RPoint[], the tangent vectors returned in an array.
297
+ *
298
+ */
299
+ @Override
300
+ public RPoint[] getTangents() {
301
+ int numCommands = countCommands();
302
+ if (numCommands == 0) {
303
+ return null;
280
304
  }
281
305
 
282
- @Override
283
- protected void calculateCurveLengths() {
284
- lenCurves = new float[countCommands()];
285
- lenCurve = 0F;
286
- for (int i = 0; i < countCommands(); i++) {
287
- lenCurves[i] = commands[i].getCurveLength();
288
- lenCurve += lenCurves[i];
306
+ RPoint[] result = null;
307
+ RPoint[] newresult;
308
+ for (int i = 0; i < numCommands; i++) {
309
+ RPoint[] newTangents = commands[i].getTangents();
310
+ if (newTangents != null) {
311
+ if (newTangents.length != 1) {
312
+ int overlap = 1;
313
+ if (result == null) {
314
+ result = new RPoint[newTangents.length];
315
+ System.arraycopy(newTangents, 0, result, 0, newTangents.length);
316
+ } else {
317
+ newresult = new RPoint[result.length + newTangents.length - overlap];
318
+ System.arraycopy(result, 0, newresult, 0, result.length);
319
+ System.arraycopy(newTangents, overlap, newresult, result.length, newTangents.length - overlap);
320
+ result = newresult;
321
+ }
289
322
  }
323
+ }
290
324
  }
291
-
292
- /**
293
- * Use this to return the tangents on the curve. It returns the vectors in
294
- * the way of an array of RPoint.
295
- *
296
- * @eexample getTangents
297
- * @return RPoint[], the tangent vectors returned in an array.
298
- *
299
- */
300
- @Override
301
- public RPoint[] getTangents() {
302
- int numCommands = countCommands();
303
- if (numCommands == 0) {
304
- return null;
305
- }
306
-
307
- RPoint[] result = null;
308
- RPoint[] newresult;
309
- for (int i = 0; i < numCommands; i++) {
310
- RPoint[] newTangents = commands[i].getTangents();
311
- if (newTangents != null) {
312
- if (newTangents.length != 1) {
313
- int overlap = 1;
314
- if (result == null) {
315
- result = new RPoint[newTangents.length];
316
- System.arraycopy(newTangents, 0, result, 0, newTangents.length);
317
- } else {
318
- newresult = new RPoint[result.length + newTangents.length - overlap];
319
- System.arraycopy(result, 0, newresult, 0, result.length);
320
- System.arraycopy(newTangents, overlap, newresult, result.length, newTangents.length - overlap);
321
- result = newresult;
322
- }
323
- }
324
- }
325
- }
326
- return result;
325
+ return result;
326
+ }
327
+
328
+ /**
329
+ * Use this to return the intersection points between this path and a command.
330
+ * Returns null if no intersection exists.
331
+ *
332
+ * @param other
333
+ * @return RPoint[], the intersection points returned in an array.
334
+ *
335
+ */
336
+ public RPoint[] intersectionPoints(RCommand other) {
337
+ int numCommands = countCommands();
338
+ if (numCommands == 0) {
339
+ return null;
327
340
  }
328
341
 
329
- /**
330
- * Use this to return the intersection points between this path and a
331
- * command. Returns null if no intersection exists.
332
- *
333
- * @param other
334
- * @return RPoint[], the intersection points returned in an array.
335
- *
336
- */
337
- public RPoint[] intersectionPoints(RCommand other) {
338
- int numCommands = countCommands();
339
- if (numCommands == 0) {
340
- return null;
341
- }
342
-
343
- RPoint[] result = null;
344
- RPoint[] newresult;
345
- for (int i = 0; i < numCommands; i++) {
346
- RPoint[] newPoints = commands[i].intersectionPoints(other);
347
- if (newPoints != null) {
348
- if (result == null) {
349
- result = new RPoint[newPoints.length];
350
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
351
- } else {
352
- newresult = new RPoint[result.length + newPoints.length];
353
- System.arraycopy(result, 0, newresult, 0, result.length);
354
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
355
- result = newresult;
356
- }
357
- }
342
+ RPoint[] result = null;
343
+ RPoint[] newresult;
344
+ for (int i = 0; i < numCommands; i++) {
345
+ RPoint[] newPoints = commands[i].intersectionPoints(other);
346
+ if (newPoints != null) {
347
+ if (result == null) {
348
+ result = new RPoint[newPoints.length];
349
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
350
+ } else {
351
+ newresult = new RPoint[result.length + newPoints.length];
352
+ System.arraycopy(result, 0, newresult, 0, result.length);
353
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
354
+ result = newresult;
358
355
  }
359
- return result;
356
+ }
360
357
  }
361
-
362
- /**
363
- * Use this to return the intersection points between two paths. Returns
364
- * null if no intersection exists.
365
- *
366
- * @param other
367
- * @return RPoint[], the intersection points returned in an array.
368
- *
369
- */
370
- public RPoint[] intersectionPoints(RPath other) {
371
- int numCommands = countCommands();
372
- int numOtherCommands = other.countCommands();
373
-
374
- if (numCommands == 0) {
375
- return null;
376
- }
377
-
378
- RPoint[] result = null;
379
- RPoint[] newresult;
380
-
381
- for (int j = 0; j < numOtherCommands; j++) {
382
- for (int i = 0; i < numCommands; i++) {
383
- RPoint[] newPoints = commands[i].intersectionPoints(other.commands[j]);
384
- if (newPoints != null) {
385
- if (result == null) {
386
- result = new RPoint[newPoints.length];
387
- System.arraycopy(newPoints, 0, result, 0, newPoints.length);
388
- } else {
389
- newresult = new RPoint[result.length + newPoints.length];
390
- System.arraycopy(result, 0, newresult, 0, result.length);
391
- System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
392
- result = newresult;
393
- }
394
- }
395
- }
396
- }
397
-
398
- return result;
358
+ return result;
359
+ }
360
+
361
+ /**
362
+ * Use this to return the intersection points between two paths. Returns null
363
+ * if no intersection exists.
364
+ *
365
+ * @param other
366
+ * @return RPoint[], the intersection points returned in an array.
367
+ *
368
+ */
369
+ public RPoint[] intersectionPoints(RPath other) {
370
+ int numCommands = countCommands();
371
+ int numOtherCommands = other.countCommands();
372
+
373
+ if (numCommands == 0) {
374
+ return null;
399
375
  }
400
376
 
401
- /**
402
- * Use this to find the closest or intersection points between this path and
403
- * a command.
404
- *
405
- * @param other
406
- * @return RPoint[], the intersection points returned in an array.
407
- *
408
- */
409
- public RClosest closestPoints(RCommand other) {
410
- int numCommands = countCommands();
411
- if (numCommands == 0) {
412
- return null;
377
+ RPoint[] result = null;
378
+ RPoint[] newresult;
379
+
380
+ for (int j = 0; j < numOtherCommands; j++) {
381
+ for (int i = 0; i < numCommands; i++) {
382
+ RPoint[] newPoints = commands[i].intersectionPoints(other.commands[j]);
383
+ if (newPoints != null) {
384
+ if (result == null) {
385
+ result = new RPoint[newPoints.length];
386
+ System.arraycopy(newPoints, 0, result, 0, newPoints.length);
387
+ } else {
388
+ newresult = new RPoint[result.length + newPoints.length];
389
+ System.arraycopy(result, 0, newresult, 0, result.length);
390
+ System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
391
+ result = newresult;
392
+ }
413
393
  }
394
+ }
395
+ }
414
396
 
415
- // TODO: get here the max value of an integer
416
- float minDist = 100000;
397
+ return result;
398
+ }
399
+
400
+ /**
401
+ * Use this to find the closest or intersection points between this path and a
402
+ * command.
403
+ *
404
+ * @param other
405
+ * @return RPoint[], the intersection points returned in an array.
406
+ *
407
+ */
408
+ public RClosest closestPoints(RCommand other) {
409
+ int numCommands = countCommands();
410
+ if (numCommands == 0) {
411
+ return null;
412
+ }
417
413
 
418
- RClosest result = new RClosest();
414
+ // TODO: get here the max value of an integer
415
+ float minDist = 100000;
419
416
 
420
- for (int i = 0; i < numCommands; i++) {
421
- RClosest currResult = commands[i].closestPoints(other);
417
+ RClosest result = new RClosest();
422
418
 
423
- result.update(currResult);
424
- }
419
+ for (int i = 0; i < numCommands; i++) {
420
+ RClosest currResult = commands[i].closestPoints(other);
425
421
 
426
- return result;
422
+ result.update(currResult);
427
423
  }
428
424
 
429
- /**
430
- * Use this to return the intersection points between two paths. Returns
431
- * null if no intersection exists.
432
- *
433
- * @param other
434
- * @return RPoint[], the intersection points returned in an array.
435
- *
436
- */
437
- public RClosest closestPoints(RPath other) {
438
- int numCommands = countCommands();
439
- int numOtherCommands = other.countCommands();
440
-
441
- if (numCommands == 0) {
442
- return null;
443
- }
444
-
445
- // TODO: get here the max value of an integer
446
- float minDist = 100000;
425
+ return result;
426
+ }
427
+
428
+ /**
429
+ * Use this to return the intersection points between two paths. Returns null
430
+ * if no intersection exists.
431
+ *
432
+ * @param other
433
+ * @return RPoint[], the intersection points returned in an array.
434
+ *
435
+ */
436
+ public RClosest closestPoints(RPath other) {
437
+ int numCommands = countCommands();
438
+ int numOtherCommands = other.countCommands();
439
+
440
+ if (numCommands == 0) {
441
+ return null;
442
+ }
447
443
 
448
- RClosest result = new RClosest();
444
+ // TODO: get here the max value of an integer
445
+ float minDist = 100000;
449
446
 
450
- for (int j = 0; j < numOtherCommands; j++) {
451
- for (int i = 0; i < numCommands; i++) {
452
- RClosest currResult = commands[i].closestPoints(other.commands[j]);
453
- result.update(currResult);
454
- }
455
- }
447
+ RClosest result = new RClosest();
456
448
 
457
- return result;
449
+ for (int j = 0; j < numOtherCommands; j++) {
450
+ for (int i = 0; i < numCommands; i++) {
451
+ RClosest currResult = commands[i].closestPoints(other.commands[j]);
452
+ result.update(currResult);
453
+ }
458
454
  }
459
455
 
460
- /**
461
- * Return a specific point on the curve. It returns the RPoint for a given
462
- * advancement parameter t on the curve.
463
- *
464
- * @eexample getPoint
465
- * @param t the parameter of advancement on the curve. t must have values
466
- * between 0 and 1.
467
- * @return RPoint, the vertice returned.
468
- *
469
- */
470
- @Override
471
- public RPoint getPoint(float t) {
472
- int numCommands = countCommands();
473
- if (numCommands == 0) {
474
- return new RPoint();
475
- }
476
-
477
- if (t == 0.0F) {
478
- return commands[0].getPoint(0F);
479
- }
480
- if (t == 1.0F) {
481
- return commands[numCommands - 1].getPoint(1F);
482
- }
483
-
484
- float[] indAndAdv = indAndAdvAt(t);
485
- int indOfElement = (int) (indAndAdv[0]);
486
- float advOfElement = indAndAdv[1];
456
+ return result;
457
+ }
458
+
459
+ /**
460
+ * Return a specific point on the curve. It returns the RPoint for a given
461
+ * advancement parameter t on the curve.
462
+ *
463
+ getPoint
464
+ * @param t the parameter of advancement on the curve. t must have values
465
+ * between 0 and 1.
466
+ * @return RPoint, the vertice returned.
467
+ *
468
+ */
469
+ @Override
470
+ public RPoint getPoint(float t) {
471
+ int numCommands = countCommands();
472
+ if (numCommands == 0) {
473
+ return new RPoint();
474
+ }
487
475
 
488
- return commands[indOfElement].getPoint(advOfElement);
476
+ if (t == 0.0F) {
477
+ return commands[0].getPoint(0F);
478
+ }
479
+ if (t == 1.0F) {
480
+ return commands[numCommands - 1].getPoint(1F);
489
481
  }
490
482
 
491
- /**
492
- * Use this to return a specific tangent on the curve. It returns the RPoint
493
- * tangent for a given advancement parameter t on the curve.
494
- *
495
- * @eexample getPoint
496
- * @param t float, the parameter of advancement on the curve. t must have
497
- * values between 0 and 1.
498
- * @return RPoint, the vertice returned.
499
- *
500
- */
501
- @Override
502
- public RPoint getTangent(float t) {
503
- int numCommands = countCommands();
504
- if (numCommands == 0) {
505
- return new RPoint();
506
- }
483
+ float[] indAndAdv = indAndAdvAt(t);
484
+ int indOfElement = (int) (indAndAdv[0]);
485
+ float advOfElement = indAndAdv[1];
486
+
487
+ return commands[indOfElement].getPoint(advOfElement);
488
+ }
489
+
490
+ /**
491
+ * Use this to return a specific tangent on the curve. It returns the RPoint
492
+ * tangent for a given advancement parameter t on the curve.
493
+ *
494
+ getPoint
495
+ * @param t float, the parameter of advancement on the curve. t must have
496
+ * values between 0 and 1.
497
+ * @return RPoint, the vertice returned.
498
+ *
499
+ */
500
+ @Override
501
+ public RPoint getTangent(float t) {
502
+ int numCommands = countCommands();
503
+ if (numCommands == 0) {
504
+ return new RPoint();
505
+ }
507
506
 
508
- if (t == 0.0F) {
509
- return commands[0].getTangent(0F);
510
- }
511
- if (t == 1.0F) {
512
- return commands[numCommands - 1].getTangent(1F);
513
- }
507
+ if (t == 0.0F) {
508
+ return commands[0].getTangent(0F);
509
+ }
510
+ if (t == 1.0F) {
511
+ return commands[numCommands - 1].getTangent(1F);
512
+ }
514
513
 
515
- float[] indAndAdv = indAndAdvAt(t);
516
- int indOfElement = (int) (indAndAdv[0]);
517
- float advOfElement = indAndAdv[1];
514
+ float[] indAndAdv = indAndAdvAt(t);
515
+ int indOfElement = (int) (indAndAdv[0]);
516
+ float advOfElement = indAndAdv[1];
518
517
 
519
- /* This takes the medium between two intersecting commands, sometimes this is not wanted
518
+ /* This takes the medium between two intersecting commands, sometimes this is not wanted
520
519
  if(advOfElement==1.0F){
521
520
  int indNextCommand = (indOfElement + 1) % numCommands;
522
521
  result = commands[indOfElement].getTangent(advOfElement);
@@ -532,453 +531,452 @@ public class RPath extends RGeomElem {
532
531
  }else{
533
532
  result = commands[indOfElement].getTangent(advOfElement);
534
533
  }
535
- */
536
- return commands[indOfElement].getTangent(advOfElement);
537
- }
538
-
539
- /**
540
- * Use this to return a specific tangent on the curve. It returns true if
541
- * the point passed as a parameter is inside the path. Implementation taken
542
- * from:
543
- * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
544
- *
545
- * @param p the point for which to test containement..
546
- * @return boolean, true if the point is in the path.
547
- *
548
534
  */
549
- @Override
550
- public boolean contains(RPoint p) {
551
- float testx = p.x;
552
- float testy = p.y;
553
-
554
- // Test for containment in bounding box
555
- RRectangle bbox = getBounds();
556
- float xmin = bbox.getMinX();
557
- float xmax = bbox.getMaxX();
558
-
559
- float ymin = bbox.getMinY();
560
- float ymax = bbox.getMaxY();
561
-
562
- if ((testx < xmin) || (testx > xmax) || (testy < ymin) || (testy > ymax)) {
563
- return false;
564
- }
565
-
566
- // Test for containment in path
567
- RPoint[] verts = getPoints();
568
-
569
- if (verts == null) {
570
- return false;
571
- }
572
-
573
- int nvert = verts.length;
574
- int i;
575
- int j;
576
- boolean c = false;
577
- for (i = 0, j = nvert - 1; i < nvert; j = i++) {
578
- if (((verts[i].y > testy) != (verts[j].y > testy))
579
- && (testx < (verts[j].x - verts[i].x) * (testy - verts[i].y) / (verts[j].y - verts[i].y) + verts[i].x)) {
580
- c = !c;
581
- }
582
- }
583
- return c;
535
+ return commands[indOfElement].getTangent(advOfElement);
536
+ }
537
+
538
+ /**
539
+ * Use this to return a specific tangent on the curve. It returns true if the
540
+ * point passed as a parameter is inside the path. Implementation taken from:
541
+ * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
542
+ *
543
+ * @param p the point for which to test containement..
544
+ * @return boolean, true if the point is in the path.
545
+ *
546
+ */
547
+ @Override
548
+ public boolean contains(RPoint p) {
549
+ float testx = p.x;
550
+ float testy = p.y;
551
+
552
+ // Test for containment in bounding box
553
+ RRectangle bbox = getBounds();
554
+ float xmin = bbox.getMinX();
555
+ float xmax = bbox.getMaxX();
556
+
557
+ float ymin = bbox.getMinY();
558
+ float ymax = bbox.getMaxY();
559
+
560
+ if ((testx < xmin) || (testx > xmax) || (testy < ymin) || (testy > ymax)) {
561
+ return false;
584
562
  }
585
563
 
586
- /**
587
- * Use this to insert a split point into the path.
588
- *
589
- * @eexample insertHandle
590
- * @param t float, the parameter of advancement on the curve. t must have
591
- * values between 0 and 1.
592
- *
593
- */
594
- public void insertHandle(float t) {
595
- if ((t == 0F) || (t == 1F)) {
596
- return;
597
- }
598
-
599
- float[] indAndAdv = indAndAdvAt(t);
600
- int indOfElement = (int) (indAndAdv[0]);
601
- float advOfElement = indAndAdv[1];
602
-
603
- // Split the affected command and reconstruct each of the shapes
604
- RCommand[] splittedCommands = commands[indOfElement].split(advOfElement);
605
-
606
- if (splittedCommands[0] == null || splittedCommands[1] == null) {
607
- return;
608
- }
609
-
610
- // Extract the splitted command
611
- extract(indOfElement);
612
-
613
- // Insert the splittedCommands
614
- insert(splittedCommands[1], indOfElement);
615
- insert(splittedCommands[0], indOfElement);
564
+ // Test for containment in path
565
+ RPoint[] verts = getPoints();
616
566
 
617
- // Clear the cache
618
- lenCurves = null;
619
- lenCurve = -1F;
567
+ if (verts == null) {
568
+ return false;
620
569
  }
621
570
 
622
- /**
623
- * Use this to insert a split point into each command of the path.
624
- *
625
- * @eexample insertHandleInPaths
626
- * @param t float, the parameter of advancement on the curve. t must have
627
- * values between 0 and 1.
628
- *
629
- */
630
- public void insertHandleInPaths(float t) {
631
- if ((t == 0F) || (t == 1F)) {
632
- return;
633
- }
634
-
635
- int numCommands = countCommands();
636
-
637
- for (int i = 0; i < numCommands * 2; i += 2) {
638
- // Split the affected command and reconstruct each of the shapes
639
- RCommand[] splittedCommands = commands[i].split(t);
640
-
641
- if (splittedCommands[0] == null || splittedCommands[1] == null) {
642
- return;
643
- }
644
-
645
- // Extract the splitted command
646
- extract(i);
647
-
648
- // Insert the splittedCommands
649
- insert(splittedCommands[1], i);
650
- insert(splittedCommands[0], i);
651
- }
652
-
653
- // Clear the cache
654
- lenCurves = null;
655
- lenCurve = -1F;
571
+ int nvert = verts.length;
572
+ int i;
573
+ int j;
574
+ boolean c = false;
575
+ for (i = 0, j = nvert - 1; i < nvert; j = i++) {
576
+ if (((verts[i].y > testy) != (verts[j].y > testy))
577
+ && (testx < (verts[j].x - verts[i].x) * (testy - verts[i].y) / (verts[j].y - verts[i].y) + verts[i].x)) {
578
+ c = !c;
579
+ }
580
+ }
581
+ return c;
582
+ }
583
+
584
+ /**
585
+ * Use this to insert a split point into the path.
586
+ *
587
+ insertHandle
588
+ * @param t float, the parameter of advancement on the curve. t must have
589
+ * values between 0 and 1.
590
+ *
591
+ */
592
+ public void insertHandle(float t) {
593
+ if ((t == 0F) || (t == 1F)) {
594
+ return;
656
595
  }
657
596
 
658
- /**
659
- * Use this to split a path into two separate new paths.
660
- *
661
- * @eexample split
662
- * @param t float, the parameter of advancement on the curve. t must have
663
- * values between 0 and 1.
664
- * @return RPath[], an array of two RPath.
665
- *
666
- */
667
- public RPath[] split(float t) {
668
- RPath[] result = new RPath[2];
669
-
670
- int numCommands = countCommands();
671
- if (numCommands == 0) {
672
- return null;
673
- }
674
-
675
- if (t == 0.0F) {
676
- result[0] = new RPath();
677
- result[1] = new RPath(this);
678
- result[0].setStyle(this);
679
- result[1].setStyle(this);
680
-
681
- return result;
682
- }
683
-
684
- if (t == 1.0F) {
685
- result[0] = new RPath(this);
686
- result[1] = new RPath();
687
- result[0].setStyle(this);
688
- result[1].setStyle(this);
689
-
690
- return result;
691
- }
692
-
693
- float[] indAndAdv = indAndAdvAt(t);
694
- int indOfElement = (int) (indAndAdv[0]);
695
- float advOfElement = indAndAdv[1];
696
-
697
- // Split the affected command and reconstruct each of the shapes
698
- RCommand[] splittedCommands = commands[indOfElement].split(advOfElement);
699
-
700
- result[0] = new RPath();
701
- for (int i = 0; i < indOfElement; i++) {
702
- result[0].addCommand(new RCommand(commands[i]));
703
- }
704
- result[0].addCommand(new RCommand(splittedCommands[0]));
705
- result[0].setStyle(this);
597
+ float[] indAndAdv = indAndAdvAt(t);
598
+ int indOfElement = (int) (indAndAdv[0]);
599
+ float advOfElement = indAndAdv[1];
706
600
 
707
- result[1] = new RPath();
708
- for (int i = indOfElement + 1; i < countCommands(); i++) {
709
- result[1].addCommand(new RCommand(commands[i]));
710
- }
711
- result[1].addCommand(new RCommand(splittedCommands[1]));
712
- result[1].setStyle(this);
601
+ // Split the affected command and reconstruct each of the shapes
602
+ RCommand[] splittedCommands = commands[indOfElement].split(advOfElement);
713
603
 
714
- return result;
604
+ if (splittedCommands[0] == null || splittedCommands[1] == null) {
605
+ return;
715
606
  }
716
607
 
717
- public void polygonize() {
718
- RPoint[] points = getPoints();
719
-
720
- if (points == null) {
721
- this.commands = null;
722
- } else {
723
- RPath result = new RPath(points[0]);
724
- for (int i = 1; i < points.length; i++) {
725
- result.addLineTo(points[i]);
726
- }
727
- this.commands = result.commands;
728
- }
608
+ // Extract the splitted command
609
+ extract(indOfElement);
610
+
611
+ // Insert the splittedCommands
612
+ insert(splittedCommands[1], indOfElement);
613
+ insert(splittedCommands[0], indOfElement);
614
+
615
+ // Clear the cache
616
+ lenCurves = null;
617
+ lenCurve = -1F;
618
+ }
619
+
620
+ /**
621
+ * Use this to insert a split point into each command of the path.
622
+ *
623
+ insertHandleInPaths
624
+ * @param t float, the parameter of advancement on the curve. t must have
625
+ * values between 0 and 1.
626
+ *
627
+ */
628
+ public void insertHandleInPaths(float t) {
629
+ if ((t == 0F) || (t == 1F)) {
630
+ return;
729
631
  }
730
632
 
731
- /**
732
- * Use this method to draw the path.
733
- *
734
- * @eexample drawPath
735
- * @param g PGraphics, the graphics object on which to draw the path
736
- */
737
- @Override
738
- public void draw(PGraphics g) {
739
- countCommands();
633
+ int numCommands = countCommands();
740
634
 
741
- // By default always draw with an adaptative segmentator
742
- int lastSegmentator = RCommand.segmentType;
743
- RCommand.setSegmentator(RCommand.ADAPTATIVE);
635
+ for (int i = 0; i < numCommands * 2; i += 2) {
636
+ // Split the affected command and reconstruct each of the shapes
637
+ RCommand[] splittedCommands = commands[i].split(t);
744
638
 
745
- RPoint[] points = getPoints();
639
+ if (splittedCommands[0] == null || splittedCommands[1] == null) {
640
+ return;
641
+ }
746
642
 
747
- if (points == null) {
748
- return;
749
- }
750
-
751
- g.beginShape();
752
- for (RPoint point : points) {
753
- g.vertex(point.x, point.y);
754
- }
755
- g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
643
+ // Extract the splitted command
644
+ extract(i);
756
645
 
757
- // Restore the user set segmentator
758
- RCommand.setSegmentator(lastSegmentator);
646
+ // Insert the splittedCommands
647
+ insert(splittedCommands[1], i);
648
+ insert(splittedCommands[0], i);
759
649
  }
760
650
 
761
- /**
762
- *
763
- * @param g
764
- */
765
- @Override
766
- public void draw(PApplet g) {
767
- countCommands();
768
-
769
- // By default always draw with an adaptative segmentator
770
- int lastSegmentator = RCommand.segmentType;
771
- RCommand.setSegmentator(RCommand.ADAPTATIVE);
772
-
773
- RPoint[] points = getPoints();
774
- RCommand.setSegmentator(lastSegmentator);
775
- if (points == null) {
776
- return;
777
- }
778
- g.beginShape();
779
- for (RPoint point : points) {
780
- g.vertex(point.x, point.y);
781
- }
782
- g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
783
-
784
- // Restore the user set segmentator
785
- RCommand.setSegmentator(lastSegmentator);
651
+ // Clear the cache
652
+ lenCurves = null;
653
+ lenCurve = -1F;
654
+ }
655
+
656
+ /**
657
+ * Use this to split a path into two separate new paths.
658
+ *
659
+ split
660
+ * @param t float, the parameter of advancement on the curve. t must have
661
+ * values between 0 and 1.
662
+ * @return RPath[], an array of two RPath.
663
+ *
664
+ */
665
+ public RPath[] split(float t) {
666
+ RPath[] result = new RPath[2];
667
+
668
+ int numCommands = countCommands();
669
+ if (numCommands == 0) {
670
+ return null;
786
671
  }
787
672
 
788
- /**
789
- * Use this method to add new commands to the contour.
790
- *
791
- * @param p
792
- * @eexample addCommand
793
- * @invisible
794
- */
795
- public final void addCommand(RCommand p) {
796
- this.append(p);
673
+ if (t == 0.0F) {
674
+ result[0] = new RPath();
675
+ result[1] = new RPath(this);
676
+ result[0].setStyle(this);
677
+ result[1].setStyle(this);
797
678
 
798
- lastPoint = commands[commands.length - 1].endPoint;
679
+ return result;
799
680
  }
800
681
 
801
- /**
802
- * Add a new cubic bezier to the path. The first point of the bezier will be
803
- * the last point added to the path.
804
- *
805
- * @eexample addBezierTo
806
- * @param cp1 first control point
807
- * @param cp2 second control point
808
- * @param end end point
809
- */
810
- public void addBezierTo(RPoint cp1, RPoint cp2, RPoint end) {
811
- this.addCommand(RCommand.createBezier4(lastPoint, cp1, cp2, end));
812
- }
813
-
814
- /**
815
- * Add a new cubic bezier to the path. The first point of the bezier will be
816
- * the last point added to the path.
817
- *
818
- * @eexample addBezierTo
819
- * @param cp1x the x coordinate of the first control point
820
- * @param cp1y the y coordinate of the first control point
821
- * @param cp2x the x coordinate of the second control point
822
- * @param cp2y the y coordinate of the second control point
823
- * @param endx the x coordinate of the end point
824
- * @param endy the y coordinate of the end point
825
- */
826
- public void addBezierTo(float cp1x, float cp1y, float cp2x, float cp2y, float endx, float endy) {
827
- RPoint cp1 = new RPoint(cp1x, cp1y);
828
- RPoint cp2 = new RPoint(cp2x, cp2y);
829
- RPoint end = new RPoint(endx, endy);
682
+ if (t == 1.0F) {
683
+ result[0] = new RPath(this);
684
+ result[1] = new RPath();
685
+ result[0].setStyle(this);
686
+ result[1].setStyle(this);
830
687
 
831
- addBezierTo(cp1, cp2, end);
688
+ return result;
832
689
  }
833
690
 
834
- /**
835
- * Add a new quadratic bezier to the path. The first point of the bezier
836
- * will be the last point added to the path.
837
- *
838
- * @eexample addQuadTo
839
- * @param cp1 first control point
840
- * @param end end point
841
- */
842
- public void addQuadTo(RPoint cp1, RPoint end) {
843
- this.addCommand(RCommand.createBezier3(lastPoint, cp1, end));
844
- }
691
+ float[] indAndAdv = indAndAdvAt(t);
692
+ int indOfElement = (int) (indAndAdv[0]);
693
+ float advOfElement = indAndAdv[1];
845
694
 
846
- /**
847
- * Add a new quadratic bezier to the path. The first point of the bezier
848
- * will be the last point added to the path.
849
- *
850
- * @eexample addQuadTo
851
- * @param cp1x the x coordinate of the first control point
852
- * @param cp1y the y coordinate of the first control point
853
- * @param endx the x coordinate of the end point
854
- * @param endy the y coordinate of the end point
855
- */
856
- public void addQuadTo(float cp1x, float cp1y, float endx, float endy) {
857
- RPoint cp1 = new RPoint(cp1x, cp1y);
858
- RPoint end = new RPoint(endx, endy);
695
+ // Split the affected command and reconstruct each of the shapes
696
+ RCommand[] splittedCommands = commands[indOfElement].split(advOfElement);
859
697
 
860
- addQuadTo(cp1, end);
698
+ result[0] = new RPath();
699
+ for (int i = 0; i < indOfElement; i++) {
700
+ result[0].addCommand(new RCommand(commands[i]));
861
701
  }
702
+ result[0].addCommand(new RCommand(splittedCommands[0]));
703
+ result[0].setStyle(this);
862
704
 
863
- /**
864
- * Add a new line to the path. The first point of the line will be the last
865
- * point added to the path.
866
- *
867
- * @eexample addLineTo
868
- * @param end end point
869
- */
870
- public final void addLineTo(RPoint end) {
871
- this.addCommand(RCommand.createLine(lastPoint, end));
705
+ result[1] = new RPath();
706
+ for (int i = indOfElement + 1; i < countCommands(); i++) {
707
+ result[1].addCommand(new RCommand(commands[i]));
872
708
  }
873
-
874
- /**
875
- * Add a new line to the path. The first point of the line will be the last
876
- * point added to the path.
877
- *
878
- * @eexample addLineTo
879
- * @param endx the x coordinate of the end point
880
- * @param endy the y coordinate of the end point
881
- */
882
- public void addLineTo(float endx, float endy) {
883
- RPoint end = new RPoint(endx, endy);
884
- addLineTo(end);
709
+ result[1].addCommand(new RCommand(splittedCommands[1]));
710
+ result[1].setStyle(this);
711
+
712
+ return result;
713
+ }
714
+
715
+ public void polygonize() {
716
+ RPoint[] points = getPoints();
717
+
718
+ if (points == null) {
719
+ this.commands = null;
720
+ } else {
721
+ RPath result = new RPath(points[0]);
722
+ for (int i = 1; i < points.length; i++) {
723
+ result.addLineTo(points[i]);
724
+ }
725
+ this.commands = result.commands;
885
726
  }
886
-
887
- public void addClose() {
888
- if (commands == null) {
889
- return;
890
- }
891
-
892
- if ((commands[commands.length - 1].endPoint.x == commands[0].startPoint.x) && (commands[commands.length - 1].endPoint.y == commands[0].startPoint.y)) {
893
- commands[commands.length - 1].endPoint = new RPoint(commands[0].startPoint.x, commands[0].startPoint.y);
894
- lastPoint = commands[commands.length - 1].endPoint;
895
- } else {
896
- addLineTo(new RPoint(commands[0].startPoint.x, commands[0].startPoint.y));
897
- }
898
-
899
- closed = true;
727
+ }
728
+
729
+ /**
730
+ * Use this method to draw the path.
731
+ *
732
+ drawPath
733
+ * @param g PGraphics, the graphics object on which to draw the path
734
+ */
735
+ @Override
736
+ public void draw(PGraphics g) {
737
+ countCommands();
738
+
739
+ // By default always draw with an adaptative segmentator
740
+ int lastSegmentator = RCommand.segmentType;
741
+ RCommand.setSegmentator(RCommand.ADAPTATIVE);
742
+
743
+ RPoint[] points = getPoints();
744
+
745
+ if (points == null) {
746
+ return;
900
747
  }
901
748
 
902
- /**
903
- * @return @invisible
904
- */
905
- @Override
906
- public RPolygon toPolygon() {
907
- return this.toShape().toPolygon();
749
+ g.beginShape();
750
+ for (RPoint point : points) {
751
+ g.vertex(point.x, point.y);
908
752
  }
909
-
910
- /**
911
- * @return @invisible
912
- */
913
- @Override
914
- public RShape toShape() {
915
- return new RShape(this);
753
+ g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
754
+
755
+ // Restore the user set segmentator
756
+ RCommand.setSegmentator(lastSegmentator);
757
+ }
758
+
759
+ /**
760
+ *
761
+ * @param g
762
+ */
763
+ @Override
764
+ public void draw(PApplet g) {
765
+ countCommands();
766
+
767
+ // By default always draw with an adaptative segmentator
768
+ int lastSegmentator = RCommand.segmentType;
769
+ RCommand.setSegmentator(RCommand.ADAPTATIVE);
770
+
771
+ RPoint[] points = getPoints();
772
+ RCommand.setSegmentator(lastSegmentator);
773
+ if (points == null) {
774
+ return;
916
775
  }
917
-
918
- /**
919
- * @return @invisible
920
- */
921
- @Override
922
- public RMesh toMesh() {
923
- return this.toPolygon().toMesh();
776
+ g.beginShape();
777
+ for (RPoint point : points) {
778
+ g.vertex(point.x, point.y);
779
+ }
780
+ g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
781
+
782
+ // Restore the user set segmentator
783
+ RCommand.setSegmentator(lastSegmentator);
784
+ }
785
+
786
+ /**
787
+ * Use this method to add new commands to the contour.
788
+ *
789
+ * @param p
790
+ addCommand
791
+ *
792
+ */
793
+ public final void addCommand(RCommand p) {
794
+ this.append(p);
795
+
796
+ lastPoint = commands[commands.length - 1].endPoint;
797
+ }
798
+
799
+ /**
800
+ * Add a new cubic bezier to the path. The first point of the bezier will be
801
+ * the last point added to the path.
802
+ *
803
+ addBezierTo
804
+ * @param cp1 first control point
805
+ * @param cp2 second control point
806
+ * @param end end point
807
+ */
808
+ public void addBezierTo(RPoint cp1, RPoint cp2, RPoint end) {
809
+ this.addCommand(RCommand.createBezier4(lastPoint, cp1, cp2, end));
810
+ }
811
+
812
+ /**
813
+ * Add a new cubic bezier to the path. The first point of the bezier will be
814
+ * the last point added to the path.
815
+ *
816
+ addBezierTo
817
+ * @param cp1x the x coordinate of the first control point
818
+ * @param cp1y the y coordinate of the first control point
819
+ * @param cp2x the x coordinate of the second control point
820
+ * @param cp2y the y coordinate of the second control point
821
+ * @param endx the x coordinate of the end point
822
+ * @param endy the y coordinate of the end point
823
+ */
824
+ public void addBezierTo(float cp1x, float cp1y, float cp2x, float cp2y, float endx, float endy) {
825
+ RPoint cp1 = new RPoint(cp1x, cp1y);
826
+ RPoint cp2 = new RPoint(cp2x, cp2y);
827
+ RPoint end = new RPoint(endx, endy);
828
+
829
+ addBezierTo(cp1, cp2, end);
830
+ }
831
+
832
+ /**
833
+ * Add a new quadratic bezier to the path. The first point of the bezier will
834
+ * be the last point added to the path.
835
+ *
836
+ addQuadTo
837
+ * @param cp1 first control point
838
+ * @param end end point
839
+ */
840
+ public void addQuadTo(RPoint cp1, RPoint end) {
841
+ this.addCommand(RCommand.createBezier3(lastPoint, cp1, end));
842
+ }
843
+
844
+ /**
845
+ * Add a new quadratic bezier to the path. The first point of the bezier will
846
+ * be the last point added to the path.
847
+ *
848
+ addQuadTo
849
+ * @param cp1x the x coordinate of the first control point
850
+ * @param cp1y the y coordinate of the first control point
851
+ * @param endx the x coordinate of the end point
852
+ * @param endy the y coordinate of the end point
853
+ */
854
+ public void addQuadTo(float cp1x, float cp1y, float endx, float endy) {
855
+ RPoint cp1 = new RPoint(cp1x, cp1y);
856
+ RPoint end = new RPoint(endx, endy);
857
+
858
+ addQuadTo(cp1, end);
859
+ }
860
+
861
+ /**
862
+ * Add a new line to the path. The first point of the line will be the last
863
+ * point added to the path.
864
+ *
865
+ addLineTo
866
+ * @param end end point
867
+ */
868
+ public final void addLineTo(RPoint end) {
869
+ this.addCommand(RCommand.createLine(lastPoint, end));
870
+ }
871
+
872
+ /**
873
+ * Add a new line to the path. The first point of the line will be the last
874
+ * point added to the path.
875
+ *
876
+ addLineTo
877
+ * @param endx the x coordinate of the end point
878
+ * @param endy the y coordinate of the end point
879
+ */
880
+ public void addLineTo(float endx, float endy) {
881
+ RPoint end = new RPoint(endx, endy);
882
+ addLineTo(end);
883
+ }
884
+
885
+ public void addClose() {
886
+ if (commands == null) {
887
+ return;
924
888
  }
925
889
 
926
- /**
927
- * Use this method to get the type of element this is.
928
- *
929
- * @eexample RPolygon_getType
930
- * @return int, will allways return RGeomElem.POLYGON
931
- */
932
- @Override
933
- public int getType() {
934
- return type;
890
+ if ((commands[commands.length - 1].endPoint.x == commands[0].startPoint.x) && (commands[commands.length - 1].endPoint.y == commands[0].startPoint.y)) {
891
+ commands[commands.length - 1].endPoint = new RPoint(commands[0].startPoint.x, commands[0].startPoint.y);
892
+ lastPoint = commands[commands.length - 1].endPoint;
893
+ } else {
894
+ addLineTo(new RPoint(commands[0].startPoint.x, commands[0].startPoint.y));
935
895
  }
936
896
 
937
- @Override
938
- public void print() {
939
- for (int i = 0; i < countCommands(); i++) {
940
- String commandType = "";
941
- switch (commands[i].commandType) {
942
- case RCommand.LINETO:
943
- commandType = "LINETO";
944
- break;
945
-
946
- case RCommand.CUBICBEZIERTO:
947
- commandType = "BEZIERTO";
948
- break;
949
-
950
- case RCommand.QUADBEZIERTO:
951
- commandType = "QUADBEZIERTO";
952
- break;
953
- }
954
-
955
- System.out.println("cmd type: " + commandType);
956
- System.out.print("start point: ");
957
- commands[i].startPoint.print();
958
- System.out.print("\n");
959
- System.out.print("end point: ");
960
- commands[i].endPoint.print();
961
- System.out.print("\n");
962
- if (commands[i].controlPoints != null) {
963
- System.out.println("control points: ");
964
- for (RPoint controlPoint : commands[i].controlPoints) {
965
- controlPoint.print();
966
- System.out.print(" ");
967
- System.out.print("\n");
968
- }
969
- }
970
- System.out.print("\n");
897
+ closed = true;
898
+ }
899
+
900
+ /**
901
+ * @return
902
+ */
903
+ @Override
904
+ public RPolygon toPolygon() {
905
+ return this.toShape().toPolygon();
906
+ }
907
+
908
+ /**
909
+ * @return
910
+ */
911
+ @Override
912
+ public RShape toShape() {
913
+ return new RShape(this);
914
+ }
915
+
916
+ /**
917
+ * @return
918
+ */
919
+ @Override
920
+ public RMesh toMesh() {
921
+ return this.toPolygon().toMesh();
922
+ }
923
+
924
+ /**
925
+ * Use this method to get the type of element this is.
926
+ *
927
+ RPolygon_getType
928
+ * @return int, will allways return RGeomElem.POLYGON
929
+ */
930
+ @Override
931
+ public int getType() {
932
+ return type;
933
+ }
934
+
935
+ @Override
936
+ public void print() {
937
+ for (int i = 0; i < countCommands(); i++) {
938
+ String commandType = "";
939
+ switch (commands[i].commandType) {
940
+ case RCommand.LINETO:
941
+ commandType = "LINETO";
942
+ break;
943
+
944
+ case RCommand.CUBICBEZIERTO:
945
+ commandType = "BEZIERTO";
946
+ break;
947
+
948
+ case RCommand.QUADBEZIERTO:
949
+ commandType = "QUADBEZIERTO";
950
+ break;
951
+ }
952
+
953
+ System.out.println("cmd type: " + commandType);
954
+ System.out.print("start point: ");
955
+ commands[i].startPoint.print();
956
+ System.out.print("\n");
957
+ System.out.print("end point: ");
958
+ commands[i].endPoint.print();
959
+ System.out.print("\n");
960
+ if (commands[i].controlPoints != null) {
961
+ System.out.println("control points: ");
962
+ for (RPoint controlPoint : commands[i].controlPoints) {
963
+ controlPoint.print();
964
+ System.out.print(" ");
965
+ System.out.print("\n");
971
966
  }
967
+ }
968
+ System.out.print("\n");
972
969
  }
973
-
974
- /**
975
- * Use this method to transform the shape.
976
- *
977
- * @eexample RPath_transform
978
- * @param m RMatrix, the matrix defining the affine transformation
979
- * @related draw ( )
980
- */
981
- // OPT: not transform the EndPoint since it's equal to the next StartPoint
970
+ }
971
+
972
+ /**
973
+ * Use this method to transform the shape.
974
+ *
975
+ RPath_transform
976
+ * @param m RMatrix, the matrix defining the affine transformation
977
+ * draw ( )
978
+ */
979
+ // OPT: not transform the EndPoint since it's equal to the next StartPoint
982
980
  /*
983
981
  public void transform(RMatrix m){
984
982
  RPoint[] ps = getHandles();
@@ -1000,101 +998,101 @@ public class RPath extends RGeomElem {
1000
998
  }
1001
999
 
1002
1000
  }
1003
- */
1004
- private float[] indAndAdvAt(float t) {
1005
- int indOfElement = 0;
1006
- float[] lengthsCurves = getCurveLengths();
1007
- float lengthCurve = getCurveLength();
1008
-
1009
- /* Calculate the amount of advancement t mapped to each command */
1010
- /* We use a simple algorithm where we give to each command the same amount of advancement */
1011
- /* A more useful way would be to give to each command an advancement proportional to the length of the command */
1012
- /* Old method with uniform advancement per command
1001
+ */
1002
+ private float[] indAndAdvAt(float t) {
1003
+ int indOfElement = 0;
1004
+ float[] lengthsCurves = getCurveLengths();
1005
+ float lengthCurve = getCurveLength();
1006
+
1007
+ /* Calculate the amount of advancement t mapped to each command */
1008
+ /* We use a simple algorithm where we give to each command the same amount of advancement */
1009
+ /* A more useful way would be to give to each command an advancement proportional to the length of the command */
1010
+ /* Old method with uniform advancement per command
1013
1011
  float advPerCommand;
1014
1012
  advPerCommand = 1F / numPaths;
1015
1013
  indOfElement = (int)(Math.floor(t / advPerCommand)) % numPaths;
1016
1014
  advOfElement = (t*numPaths - indOfElement);
1017
- */
1018
- float accumulatedAdvancement = lengthsCurves[indOfElement] / lengthCurve;
1019
- float prevAccumulatedAdvancement = 0F;
1020
-
1021
- /* Find in what command the advancement point is */
1022
- while (t > accumulatedAdvancement) {
1023
- indOfElement++;
1024
- prevAccumulatedAdvancement = accumulatedAdvancement;
1025
- accumulatedAdvancement += (lengthsCurves[indOfElement] / lengthCurve);
1026
- }
1015
+ */
1016
+ float accumulatedAdvancement = lengthsCurves[indOfElement] / lengthCurve;
1017
+ float prevAccumulatedAdvancement = 0F;
1018
+
1019
+ /* Find in what command the advancement point is */
1020
+ while (t > accumulatedAdvancement) {
1021
+ indOfElement++;
1022
+ prevAccumulatedAdvancement = accumulatedAdvancement;
1023
+ accumulatedAdvancement += (lengthsCurves[indOfElement] / lengthCurve);
1024
+ }
1027
1025
 
1028
- float advOfElement = (t - prevAccumulatedAdvancement) / (lengthsCurves[indOfElement] / lengthCurve);
1026
+ float advOfElement = (t - prevAccumulatedAdvancement) / (lengthsCurves[indOfElement] / lengthCurve);
1029
1027
 
1030
- float[] indAndAdv = new float[2];
1028
+ float[] indAndAdv = new float[2];
1031
1029
 
1032
- indAndAdv[0] = indOfElement;
1033
- indAndAdv[1] = advOfElement;
1030
+ indAndAdv[0] = indOfElement;
1031
+ indAndAdv[1] = advOfElement;
1034
1032
 
1035
- return indAndAdv;
1036
- }
1033
+ return indAndAdv;
1034
+ }
1037
1035
 
1038
- private void append(RCommand nextcommand) {
1039
- RCommand[] newcommands;
1040
- if (commands == null) {
1041
- newcommands = new RCommand[1];
1042
- newcommands[0] = nextcommand;
1043
- } else {
1044
- newcommands = new RCommand[this.commands.length + 1];
1045
- System.arraycopy(this.commands, 0, newcommands, 0, this.commands.length);
1046
- newcommands[this.commands.length] = nextcommand;
1047
- }
1048
- this.commands = newcommands;
1036
+ private void append(RCommand nextcommand) {
1037
+ RCommand[] newcommands;
1038
+ if (commands == null) {
1039
+ newcommands = new RCommand[1];
1040
+ newcommands[0] = nextcommand;
1041
+ } else {
1042
+ newcommands = new RCommand[this.commands.length + 1];
1043
+ System.arraycopy(this.commands, 0, newcommands, 0, this.commands.length);
1044
+ newcommands[this.commands.length] = nextcommand;
1049
1045
  }
1046
+ this.commands = newcommands;
1047
+ }
1050
1048
 
1051
- private void insert(RCommand newcommand, int i) throws RuntimeException {
1052
- if (i < 0) {
1053
- throw new RuntimeException("Negative values for indexes are not valid.");
1054
- }
1055
-
1056
- RCommand[] newcommands;
1057
- if (commands == null) {
1058
- newcommands = new RCommand[1];
1059
- newcommands[0] = newcommand;
1060
- } else {
1061
- if (i > commands.length) {
1062
- throw new RuntimeException("Index out of the bounds. You are trying to insert an element with an index higher than the number of commands in the group.");
1063
- }
1064
-
1065
- newcommands = new RCommand[this.commands.length + 1];
1066
- System.arraycopy(this.commands, 0, newcommands, 0, i);
1067
- newcommands[i] = newcommand;
1068
- System.arraycopy(this.commands, i, newcommands, i + 1, this.commands.length - i);
1069
- }
1070
- this.commands = newcommands;
1049
+ private void insert(RCommand newcommand, int i) throws RuntimeException {
1050
+ if (i < 0) {
1051
+ throw new RuntimeException("Negative values for indexes are not valid.");
1071
1052
  }
1072
1053
 
1073
- private void extract(int i) throws RuntimeException {
1074
- RCommand[] newcommands;
1075
- if (commands == null) {
1076
- throw new RuntimeException("The group is empty. No commands to remove.");
1077
- } else {
1078
- if (i < 0) {
1079
- throw new RuntimeException("Negative values for indexes are not valid.");
1080
- }
1081
- if (i > commands.length - 1) {
1082
- throw new RuntimeException("Index out of the bounds of the group. You are trying to erase an element with an index higher than the number of commands in the group.");
1083
- }
1084
- if (commands.length == 1) {
1085
- newcommands = null;
1086
- } else if (i == 0) {
1087
- newcommands = new RCommand[this.commands.length - 1];
1088
- System.arraycopy(this.commands, 1, newcommands, 0, this.commands.length - 1);
1089
- } else if (i == commands.length - 1) {
1090
- newcommands = new RCommand[this.commands.length - 1];
1091
- System.arraycopy(this.commands, 0, newcommands, 0, this.commands.length - 1);
1092
- } else {
1093
- newcommands = new RCommand[this.commands.length - 1];
1094
- System.arraycopy(this.commands, 0, newcommands, 0, i);
1095
- System.arraycopy(this.commands, i + 1, newcommands, i, this.commands.length - i - 1);
1096
- }
1097
- }
1098
- this.commands = newcommands;
1054
+ RCommand[] newcommands;
1055
+ if (commands == null) {
1056
+ newcommands = new RCommand[1];
1057
+ newcommands[0] = newcommand;
1058
+ } else {
1059
+ if (i > commands.length) {
1060
+ throw new RuntimeException("Index out of the bounds. You are trying to insert an element with an index higher than the number of commands in the group.");
1061
+ }
1062
+
1063
+ newcommands = new RCommand[this.commands.length + 1];
1064
+ System.arraycopy(this.commands, 0, newcommands, 0, i);
1065
+ newcommands[i] = newcommand;
1066
+ System.arraycopy(this.commands, i, newcommands, i + 1, this.commands.length - i);
1067
+ }
1068
+ this.commands = newcommands;
1069
+ }
1070
+
1071
+ private void extract(int i) throws RuntimeException {
1072
+ RCommand[] newcommands;
1073
+ if (commands == null) {
1074
+ throw new RuntimeException("The group is empty. No commands to remove.");
1075
+ } else {
1076
+ if (i < 0) {
1077
+ throw new RuntimeException("Negative values for indexes are not valid.");
1078
+ }
1079
+ if (i > commands.length - 1) {
1080
+ throw new RuntimeException("Index out of the bounds of the group. You are trying to erase an element with an index higher than the number of commands in the group.");
1081
+ }
1082
+ if (commands.length == 1) {
1083
+ newcommands = null;
1084
+ } else if (i == 0) {
1085
+ newcommands = new RCommand[this.commands.length - 1];
1086
+ System.arraycopy(this.commands, 1, newcommands, 0, this.commands.length - 1);
1087
+ } else if (i == commands.length - 1) {
1088
+ newcommands = new RCommand[this.commands.length - 1];
1089
+ System.arraycopy(this.commands, 0, newcommands, 0, this.commands.length - 1);
1090
+ } else {
1091
+ newcommands = new RCommand[this.commands.length - 1];
1092
+ System.arraycopy(this.commands, 0, newcommands, 0, i);
1093
+ System.arraycopy(this.commands, i + 1, newcommands, i, this.commands.length - i - 1);
1094
+ }
1099
1095
  }
1096
+ this.commands = newcommands;
1097
+ }
1100
1098
  }