geomerative 0.2.0-java → 0.3.2-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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +8 -0
  3. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  4. data/.travis.yml +14 -0
  5. data/CHANGELOG.md +4 -0
  6. data/COPYING.md +17 -0
  7. data/Gemfile +8 -1
  8. data/README.md +5 -1
  9. data/examples/README.md +1 -7
  10. data/examples/Rakefile +30 -0
  11. data/examples/data/ruby.svg +16 -0
  12. data/examples/f_agent.rb +30 -0
  13. data/examples/font_agent.rb +24 -0
  14. data/examples/hello_polygonize.rb +1 -1
  15. data/examples/hello_svg_to_pdf.rb +2 -2
  16. data/examples/hello_world.rb +1 -1
  17. data/examples/jruby_merge.rb +94 -0
  18. data/examples/physics_type.rb +1 -1
  19. data/examples/rotate_first_letter.rb +3 -4
  20. data/examples/typo_deform.rb +68 -0
  21. data/examples/typo_extra_bright.rb +62 -0
  22. data/examples/typo_merge.rb +94 -0
  23. data/geomerative.gemspec +2 -3
  24. data/lib/geomerative/version.rb +1 -1
  25. data/pom.rb +47 -0
  26. data/pom.xml +35 -65
  27. data/src/geomerative/FastRClip.java +1 -1
  28. data/src/geomerative/RCommand.java +1877 -1741
  29. data/src/geomerative/RContour.java +8 -1
  30. data/src/geomerative/RFont.java +8 -5
  31. data/src/geomerative/RG.java +8 -3
  32. data/src/geomerative/RGeomElem.java +8 -9
  33. data/src/geomerative/RGroup.java +50 -28
  34. data/src/geomerative/RMatrix.java +53 -57
  35. data/src/geomerative/RMesh.java +8 -3
  36. data/src/geomerative/RPath.java +34 -29
  37. data/src/geomerative/RPoint.java +408 -408
  38. data/src/geomerative/RPolygon.java +7 -3
  39. data/src/geomerative/RSVG.java +13 -10
  40. data/src/geomerative/RShape.java +18 -11
  41. data/src/geomerative/RStrip.java +5 -1
  42. data/src/geomerative/RStyle.java +15 -11
  43. metadata +17 -18
@@ -18,9 +18,12 @@
18
18
  */
19
19
  package geomerative;
20
20
 
21
- import processing.core.*;
21
+
22
22
 
23
23
  import java.util.List;
24
+ import processing.core.PApplet;
25
+ import processing.core.PConstants;
26
+ import processing.core.PGraphics;
24
27
 
25
28
  /**
26
29
  * RContour is a reduced interface for creating, holding and drawing contours.
@@ -111,6 +114,10 @@ public class RContour extends RGeomElem {
111
114
  }
112
115
  }
113
116
 
117
+ /**
118
+ *
119
+ * @param g
120
+ */
114
121
  @Override
115
122
  public void draw(PApplet g) {
116
123
  int numPoints = countPoints();
@@ -18,10 +18,13 @@
18
18
  */
19
19
 
20
20
  package geomerative;
21
- import processing.core.*;
21
+
22
22
 
23
23
  import org.apache.batik.svggen.font.*;
24
24
  import org.apache.batik.svggen.font.table.*;
25
+ import processing.core.PApplet;
26
+ import processing.core.PConstants;
27
+ import processing.core.PGraphics;
25
28
 
26
29
  /**
27
30
  * RShape is a reduced interface for creating, holding and drawing text from TrueType Font files. It's a basic interpreter of TrueType fonts enabling to access any String in the form of a group of shapes. Enabling us in this way to access their geometry.
@@ -98,7 +101,7 @@ public class RFont implements PConstants{
98
101
  * @related size
99
102
  * @related RFont
100
103
  */
101
- public void setSize(int size){
104
+ public final void setSize(int size){
102
105
  short unitsPerEm = f.getHeadTable().getUnitsPerEm();
103
106
  int resolution = RG.dpi();
104
107
  this.scaleFactor = ((float)size * (float)resolution) / (72F * (float)unitsPerEm);
@@ -140,7 +143,7 @@ public class RFont implements PConstants{
140
143
  * @related align
141
144
  * @related RFont
142
145
  */
143
- public void setAlign(int align) throws RuntimeException{
146
+ public final void setAlign(int align) throws RuntimeException{
144
147
  if(align!=LEFT && align!=CENTER && align!=RIGHT){
145
148
  throw new RuntimeException("Alignment unknown. The only accepted values are: RFont.LEFT, RFont.CENTER and RFont.RIGHT");
146
149
  }
@@ -148,6 +151,7 @@ public class RFont implements PConstants{
148
151
  }
149
152
 
150
153
  /**
154
+ * @return
151
155
  * @invisible
152
156
  **/
153
157
  public String getFamily(){
@@ -437,8 +441,7 @@ public class RFont implements PConstants{
437
441
 
438
442
  public void draw(char character) throws RuntimeException{
439
443
  this.toShape(character).draw();
440
- }
441
-
444
+ }
442
445
 
443
446
 
444
447
  private static float midValue(float a, float b) {
@@ -18,14 +18,19 @@
18
18
  */
19
19
  package geomerative;
20
20
 
21
- import processing.core.*;
21
+
22
+
23
+ import processing.core.PApplet;
24
+ import processing.core.PConstants;
25
+ import processing.core.PGraphics;
26
+
22
27
 
23
28
  /**
24
29
  * RG is a static class containing all the states, modes, etc.. Geomerative is
25
30
  * mostly used by calling RG methods. e.g. RShape s = RG.getEllipse(30, 40, 80,
26
31
  * 80)
27
32
  */
28
- public class RG implements PConstants {
33
+ public class RG {
29
34
 
30
35
  /**
31
36
  * @invisible
@@ -304,7 +309,7 @@ public class RG implements PConstants {
304
309
  * @eexample createShape
305
310
  */
306
311
  public static void breakShape(int endMode) {
307
- if (endMode == CLOSE) {
312
+ if (endMode == PConstants.CLOSE) {
308
313
  shape.addClose();
309
314
  }
310
315
 
@@ -17,8 +17,8 @@
17
17
  * Geomerative. If not, see <http://www.gnu.org/licenses/>.
18
18
  */
19
19
  package geomerative;
20
-
21
- import processing.core.*;
20
+ import processing.core.PApplet;
21
+ import processing.core.PGraphics;
22
22
 
23
23
  /**
24
24
  * RGeomElem is an interface to any geometric element that can be drawn and
@@ -86,6 +86,10 @@ public abstract class RGeomElem {
86
86
  // They must be overrided
87
87
  public abstract void draw(PGraphics g);
88
88
 
89
+ /**
90
+ *
91
+ * @param g
92
+ */
89
93
  public abstract void draw(PApplet g);
90
94
 
91
95
  public void draw() {
@@ -142,15 +146,10 @@ public abstract class RGeomElem {
142
146
  RPoint bl = shp.getBottomRight();
143
147
  RPoint br = shp.getBottomLeft();
144
148
 
145
- if (this.contains(tl)
149
+ return this.contains(tl)
146
150
  && this.contains(tr)
147
151
  && this.contains(bl)
148
- && this.contains(br)) {
149
-
150
- return true;
151
- }
152
-
153
- return false;
152
+ && this.contains(br);
154
153
  }
155
154
 
156
155
  /**
@@ -55,6 +55,7 @@ public class RGroup extends RGeomElem
55
55
 
56
56
  /**
57
57
  * Use this method to create a copy of a group.
58
+ * @param grp
58
59
  * @eexample RGroup
59
60
  */
60
61
  public RGroup(RGroup grp){
@@ -91,6 +92,7 @@ public class RGroup extends RGeomElem
91
92
  * @related getBounds ( )
92
93
  * @related getCenter ( )
93
94
  */
95
+ @Override
94
96
  public RPoint getCentroid(){
95
97
  RPoint bestCentroid = new RPoint();
96
98
  float bestArea = Float.NEGATIVE_INFINITY;
@@ -120,6 +122,7 @@ public class RGroup extends RGeomElem
120
122
  return elements.length;
121
123
  }
122
124
 
125
+ @Override
123
126
  public void print(){
124
127
  System.out.println("group: ");
125
128
  for(int i=0;i<countElements();i++)
@@ -135,6 +138,7 @@ public class RGroup extends RGeomElem
135
138
  * @eexample RGroup_draw
136
139
  * @param g PGraphics, the graphics object on which to draw the group
137
140
  */
141
+ @Override
138
142
  public void draw(PGraphics g){
139
143
  if(!RG.ignoreStyles){
140
144
  saveContext(g);
@@ -150,6 +154,7 @@ public class RGroup extends RGeomElem
150
154
  }
151
155
  }
152
156
 
157
+ @Override
153
158
  public void draw(PApplet a){
154
159
  if(!RG.ignoreStyles){
155
160
  saveContext(a);
@@ -171,7 +176,7 @@ public class RGroup extends RGeomElem
171
176
  * @param elem RGeomElem, any kind of RGeomElem to add. It accepts the classes RShape, RPolygon and RMesh.
172
177
  * @related removeElement ( )
173
178
  */
174
- public void addElement(RGeomElem elem){
179
+ public final void addElement(RGeomElem elem){
175
180
  this.append(elem);
176
181
  }
177
182
 
@@ -257,8 +262,10 @@ public class RGroup extends RGeomElem
257
262
  }
258
263
 
259
264
  /**
265
+ * @return
260
266
  * @invisible
261
267
  */
268
+ @Override
262
269
  public RMesh toMesh() throws RuntimeException{
263
270
  //throw new RuntimeException("Transforming a Group to a Mesh is not yet implemented.");
264
271
  RGroup meshGroup = toMeshGroup();
@@ -274,8 +281,10 @@ public class RGroup extends RGeomElem
274
281
  }
275
282
 
276
283
  /**
284
+ * @return
277
285
  * @invisible
278
286
  */
287
+ @Override
279
288
  public RPolygon toPolygon() throws RuntimeException{
280
289
  //throw new RuntimeException("Transforming a Group to a Polygon is not yet implemented.");
281
290
  //RGroup polygonGroup = toPolygonGroup();
@@ -291,8 +300,10 @@ public class RGroup extends RGeomElem
291
300
  }
292
301
 
293
302
  /**
303
+ * @return
294
304
  * @invisible
295
305
  */
306
+ @Override
296
307
  public RShape toShape() throws RuntimeException{
297
308
  //throw new RuntimeException("Transforming a Group to a Shape is not yet implemented.");
298
309
  RShape result = new RShape();
@@ -311,6 +322,7 @@ public class RGroup extends RGeomElem
311
322
  * @eexample RGroup_getHandles
312
323
  * @return RPoint[], the points returned in an array.
313
324
  * */
325
+ @Override
314
326
  public RPoint[] getHandles(){
315
327
  int numElements = countElements();
316
328
  if(numElements == 0){
@@ -318,7 +330,7 @@ public class RGroup extends RGeomElem
318
330
  }
319
331
 
320
332
  RPoint[] result=null;
321
- RPoint[] newresult=null;
333
+ RPoint[] newresult;
322
334
  for(int i=0;i<numElements;i++){
323
335
  RPoint[] newPoints = elements[i].getHandles();
324
336
  if(newPoints!=null){
@@ -336,6 +348,12 @@ public class RGroup extends RGeomElem
336
348
  return result;
337
349
  }
338
350
 
351
+ /**
352
+ *
353
+ * @param t
354
+ * @return
355
+ */
356
+ @Override
339
357
  public RPoint getPoint(float t){
340
358
  float[] indAndAdv = indAndAdvAt(t);
341
359
  int indOfElement = (int)(indAndAdv[0]);
@@ -349,6 +367,7 @@ public class RGroup extends RGeomElem
349
367
  * @eexample RGroup_getPoints
350
368
  * @return RPoint[], the points returned in an array.
351
369
  * */
370
+ @Override
352
371
  public RPoint[] getPoints(){
353
372
  int numElements = countElements();
354
373
  if(numElements == 0){
@@ -357,7 +376,7 @@ public class RGroup extends RGeomElem
357
376
 
358
377
  RCommand.segmentAccOffset = RCommand.segmentOffset;
359
378
  RPoint[] result=null;
360
- RPoint[] newresult=null;
379
+ RPoint[] newresult;
361
380
  for(int i=0;i<numElements;i++){
362
381
  RPoint[] newPoints = elements[i].getPoints();
363
382
  if(newPoints!=null){
@@ -376,6 +395,7 @@ public class RGroup extends RGeomElem
376
395
  return result;
377
396
  }
378
397
 
398
+ @Override
379
399
  public RPoint getTangent(float t){
380
400
  float[] indAndAdv = indAndAdvAt(t);
381
401
  int indOfElement = (int)(indAndAdv[0]);
@@ -389,6 +409,7 @@ public class RGroup extends RGeomElem
389
409
  * @eexample RGroup_getPoints
390
410
  * @return RPoint[], the points returned in an array.
391
411
  * */
412
+ @Override
392
413
  public RPoint[] getTangents(){
393
414
  int numElements = countElements();
394
415
  if(numElements == 0){
@@ -396,7 +417,7 @@ public class RGroup extends RGeomElem
396
417
  }
397
418
 
398
419
  RPoint[] result=null;
399
- RPoint[] newresult=null;
420
+ RPoint[] newresult;
400
421
  for(int i=0;i<numElements;i++){
401
422
  RPoint[] newPoints = elements[i].getTangents();
402
423
  if(newPoints!=null){
@@ -419,6 +440,7 @@ public class RGroup extends RGeomElem
419
440
  * @eexample RGroup_getPoints
420
441
  * @return RPoint[], the points returned in an array.
421
442
  * */
443
+ @Override
422
444
  public RPoint[][] getPointsInPaths(){
423
445
  int numElements = countElements();
424
446
  if(numElements == 0){
@@ -426,7 +448,7 @@ public class RGroup extends RGeomElem
426
448
  }
427
449
 
428
450
  RPoint[][] result=null;
429
- RPoint[][] newresult=null;
451
+ RPoint[][] newresult;
430
452
  for(int i=0;i<numElements;i++){
431
453
  RPoint[][] newPointPaths = elements[i].getPointsInPaths();
432
454
  if(newPointPaths != null){
@@ -444,14 +466,14 @@ public class RGroup extends RGeomElem
444
466
  return result;
445
467
  }
446
468
 
469
+ @Override
447
470
  public RPoint[][] getHandlesInPaths(){
448
471
  int numElements = countElements();
449
472
  if(numElements == 0){
450
473
  return null;
451
- }
452
-
474
+ }
453
475
  RPoint[][] result=null;
454
- RPoint[][] newresult=null;
476
+ RPoint[][] newresult;
455
477
  for(int i=0;i<numElements;i++){
456
478
  RPoint[][] newHandlePaths = elements[i].getHandlesInPaths();
457
479
  if(newHandlePaths != null){
@@ -469,14 +491,14 @@ public class RGroup extends RGeomElem
469
491
  return result;
470
492
  }
471
493
 
494
+ @Override
472
495
  public RPoint[][] getTangentsInPaths(){
473
496
  int numElements = countElements();
474
497
  if(numElements == 0){
475
498
  return null;
476
- }
477
-
499
+ }
478
500
  RPoint[][] result=null;
479
- RPoint[][] newresult=null;
501
+ RPoint[][] newresult;
480
502
  for(int i=0;i<numElements;i++){
481
503
  RPoint[][] newTangentPaths = elements[i].getTangentsInPaths();
482
504
  if(newTangentPaths != null){
@@ -499,6 +521,7 @@ public class RGroup extends RGeomElem
499
521
  * @param p the point for which to test containment..
500
522
  * @return boolean, true if the point is in the path.
501
523
  * */
524
+ @Override
502
525
  public boolean contains(RPoint p){
503
526
  float testx = p.x;
504
527
  float testy = p.y;
@@ -529,6 +552,7 @@ public class RGroup extends RGeomElem
529
552
  * @eexample RPolygon_getType
530
553
  * @return int, will allways return RGeomElem.POLYGON
531
554
  */
555
+ @Override
532
556
  public int getType(){
533
557
  return type;
534
558
  }
@@ -714,12 +738,11 @@ public class RGroup extends RGeomElem
714
738
  ((RShape)element).insertHandleInPaths(t);
715
739
  break;
716
740
  }
717
- }
718
-
719
- return;
741
+ }
720
742
  }
721
743
 
722
744
 
745
+ @Override
723
746
  protected void calculateCurveLengths(){
724
747
  lenCurves = new float[countElements()];
725
748
  lenCurve = 0F;
@@ -732,6 +755,8 @@ public class RGroup extends RGeomElem
732
755
 
733
756
  /**
734
757
  * Use this method to adapt a group of of figures to a group.
758
+ * @param wght
759
+ * @param lngthOffset
735
760
  * @eexample RGroup_adapt
736
761
  * @param grp the path to which to adapt
737
762
  */
@@ -749,20 +774,17 @@ public class RGroup extends RGeomElem
749
774
  RGeomElem elem = this.elements[i];
750
775
  RPoint[] ps = elem.getHandles();
751
776
  if(ps != null){
752
- for(int k=0;k<ps.length;k++){
753
- float px = ps[k].x;
754
- float py = ps[k].y;
755
-
756
- float t = ((px-xmin)/(xmax-xmin) + lngthOffset ) % 1.001F;
757
- float amp = (ymax-py);
758
-
759
- RPoint tg = grp.getTangent(t);
760
- RPoint p = grp.getPoint(t);
761
- float angle = (float)Math.atan2(tg.y, tg.x) - (float)Math.PI/2F;
762
-
763
- ps[k].x = p.x + wght*amp*(float)Math.cos(angle);
764
- ps[k].y = p.y + wght*amp*(float)Math.sin(angle);
765
- }
777
+ for (RPoint p1 : ps) {
778
+ float px = p1.x;
779
+ float py = p1.y;
780
+ float t = ((px-xmin)/(xmax-xmin) + lngthOffset ) % 1.001F;
781
+ float amp = (ymax-py);
782
+ RPoint tg = grp.getTangent(t);
783
+ RPoint p = grp.getPoint(t);
784
+ float angle = (float)Math.atan2(tg.y, tg.x) - (float)Math.PI/2F;
785
+ p1.x = p.x + wght*amp*(float)Math.cos(angle);
786
+ p1.y = p.y + wght*amp*(float)Math.sin(angle);
787
+ }
766
788
  }
767
789
  }
768
790
  break;
@@ -106,56 +106,52 @@ public class RMatrix
106
106
  public RMatrix(String transformationString){
107
107
  String[] transfTokens = PApplet.splitTokens(transformationString, ")");
108
108
 
109
- // Loop through all transformations
110
- for(int i=0; i<transfTokens.length; i++){
111
- // Check the transformation and the parameters
112
- String[] transf = PApplet.splitTokens(transfTokens[i], "(");
113
- String[] params = PApplet.splitTokens(transf[1], ", ");
114
- float[] fparams = new float[params.length];
115
- for(int j=0; j<params.length; j++){
116
- fparams[j] = PApplet.parseFloat(params[j]);
117
- }
118
-
119
- transf[0] = PApplet.trim(transf[0]);
120
-
121
- if(transf[0].equals("translate")){
122
- if(params.length == 1){
123
- this.translate(fparams[0]);
124
-
125
- }else if(params.length == 2){
126
- this.translate(fparams[0], fparams[1]);
127
-
128
- }
129
- }else if(transf[0].equals("rotate")){
130
- if(params.length == 1){
131
- this.rotate(PApplet.radians(fparams[0]));
132
-
133
- }else if(params.length == 3){
134
- this.rotate(PApplet.radians(fparams[0]), fparams[1], fparams[2]);
135
-
136
- }
137
-
138
- }else if(transf[0].equals("scale")){
139
- if(params.length == 1){
140
- this.scale(fparams[0]);
141
-
142
- }else if(params.length == 2){
143
- this.scale(fparams[0], fparams[1]);
109
+ // Loop through all transformations
110
+ for (String transfToken : transfTokens) {
111
+ // Check the transformation and the parameters
112
+ String[] transf = PApplet.splitTokens(transfToken, "(");
113
+ String[] params = PApplet.splitTokens(transf[1], ", ");
114
+ float[] fparams = new float[params.length];
115
+ for(int j=0; j<params.length; j++){
116
+ fparams[j] = PApplet.parseFloat(params[j]);
117
+ } transf[0] = PApplet.trim(transf[0]);
118
+ switch (transf[0]) {
119
+ case "translate":
120
+ if(params.length == 1){
121
+ this.translate(fparams[0]);
122
+
123
+ }else if(params.length == 2){
124
+ this.translate(fparams[0], fparams[1]);
125
+
126
+ } break;
127
+ case "rotate":
128
+ if(params.length == 1){
129
+ this.rotate(PApplet.radians(fparams[0]));
130
+
131
+ }else if(params.length == 3){
132
+ this.rotate(PApplet.radians(fparams[0]), fparams[1], fparams[2]);
133
+
134
+ } break;
135
+ case "scale":
136
+ if(params.length == 1){
137
+ this.scale(fparams[0]);
138
+
139
+ }else if(params.length == 2){
140
+ this.scale(fparams[0], fparams[1]);
141
+ } break;
142
+ case "skewX":
143
+ this.skewX(PApplet.radians(fparams[0]));
144
+ break;
145
+ case "skewY":
146
+ this.skewY(PApplet.radians(fparams[0]));
147
+ break;
148
+ case "matrix":
149
+ this.apply(fparams[0], fparams[2], fparams[4], fparams[1], fparams[3], fparams[5]);
150
+ break;
151
+ default:
152
+ throw new RuntimeException("Transformation unknown. '"+ transf[0] +"'");
144
153
  }
145
-
146
- }else if(transf[0].equals("skewX")){
147
- this.skewX(PApplet.radians(fparams[0]));
148
-
149
- }else if(transf[0].equals("skewY")){
150
- this.skewY(PApplet.radians(fparams[0]));
151
-
152
- }else if(transf[0].equals("matrix")){
153
- this.apply(fparams[0], fparams[2], fparams[4], fparams[1], fparams[3], fparams[5]);
154
-
155
- }else{
156
- throw new RuntimeException("Transformation unknown. '"+ transf[0] +"'");
157
154
  }
158
- }
159
155
  }
160
156
 
161
157
  private void set(float m00, float m01, float m02,
@@ -185,7 +181,7 @@ public class RMatrix
185
181
  * @related scale ( )
186
182
  * @related shear ( )
187
183
  */
188
- public void apply(float n00, float n01, float n02,
184
+ public final void apply(float n00, float n01, float n02,
189
185
  float n10, float n11, float n12) {
190
186
 
191
187
  float r00 = m00*n00 + m01*n10;
@@ -225,12 +221,12 @@ public class RMatrix
225
221
  * @related scale ( )
226
222
  * @related shear ( )
227
223
  */
228
- public void translate(float tx, float ty)
224
+ public final void translate(float tx, float ty)
229
225
  {
230
226
  apply(1, 0, tx, 0, 1, ty);
231
227
  }
232
228
 
233
- public void translate(float tx)
229
+ public final void translate(float tx)
234
230
  {
235
231
  translate(tx, 0);
236
232
  }
@@ -260,14 +256,14 @@ public class RMatrix
260
256
  * @related translate ( )
261
257
  * @related scale ( )
262
258
  */
263
- public void rotate(float angle, float vx, float vy)
259
+ public final void rotate(float angle, float vx, float vy)
264
260
  {
265
261
  translate(vx,vy);
266
262
  rotate(angle);
267
263
  translate(-vx,-vy);
268
264
  }
269
265
 
270
- public void rotate(float angle)
266
+ public final void rotate(float angle)
271
267
  {
272
268
  float c = (float)Math.cos(angle);
273
269
  float s = (float)Math.sin(angle);
@@ -308,7 +304,7 @@ public class RMatrix
308
304
  translate(-x,-y);
309
305
  }
310
306
 
311
- public void scale(float sx, float sy)
307
+ public final void scale(float sx, float sy)
312
308
  {
313
309
  apply(sx, 0, 0, 0, sy, 0);
314
310
  }
@@ -360,7 +356,7 @@ public class RMatrix
360
356
  scale(s, s, p.x, p.y);
361
357
  }
362
358
 
363
- public void scale(float s)
359
+ public final void scale(float s)
364
360
  {
365
361
  scale(s, s);
366
362
  }
@@ -374,12 +370,12 @@ public class RMatrix
374
370
  * @related scale ( )
375
371
  * @related translate ( )
376
372
  */
377
- public void skewX(float angle)
373
+ public final void skewX(float angle)
378
374
  {
379
375
  apply(1, (float)Math.tan(angle), 0, 0, 1, 0);
380
376
  }
381
377
 
382
- public void skewY(float angle)
378
+ public final void skewY(float angle)
383
379
  {
384
380
  apply(1, 0, 0, (float)Math.tan(angle), 1, 0);
385
381
  }