geomerative 0.4.3-java → 2.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
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
  }