geomerative 0.2.0-java → 0.3.2-java

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