processing 0.5.31 → 0.5.33

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.
@@ -8,7 +8,7 @@ class TestGraphicsContext < Test::Unit::TestCase
8
8
 
9
9
  THRESHOLD_TO_BE_FIXED = 0.0
10
10
 
11
- def test_color()
11
+ def test_rgb_color()
12
12
  g = graphics
13
13
 
14
14
  g.colorMode G::RGB, 255
@@ -23,6 +23,32 @@ class TestGraphicsContext < Test::Unit::TestCase
23
23
  assert_in_delta 0.2, g.green(c), 1 / 256.0
24
24
  assert_in_delta 0.3, g.blue(c), 1 / 256.0
25
25
  assert_in_delta 0.4, g.alpha(c), 1 / 256.0
26
+
27
+ g.colorMode G::RGB, 0.5
28
+ c = g.color 0.1, 0.2, 0.3, 0.4
29
+ assert_equal 0xcc336699, c
30
+ assert_in_delta 0.1, g.red(c), 1 / 256.0
31
+ assert_in_delta 0.2, g.green(c), 1 / 256.0
32
+ assert_in_delta 0.3, g.blue(c), 1 / 256.0
33
+ assert_in_delta 0.4, g.alpha(c), 1 / 256.0
34
+ end
35
+
36
+ def test_hsb_color()
37
+ g = graphics
38
+
39
+ g.colorMode G::HSB, 1.0
40
+ c = g.color 0.1, 0.2, 0.3, 0.4
41
+ assert_in_delta 0.1, g.hue(c), 1 / 256.0
42
+ assert_in_delta 0.2, g.saturation(c), 1 / 256.0
43
+ assert_in_delta 0.3, g.brightness(c), 1 / 256.0
44
+ assert_in_delta 0.4, g.alpha(c), 1 / 256.0
45
+
46
+ g.colorMode G::HSB, 0.5
47
+ c = g.color 0.1, 0.2, 0.3, 0.4
48
+ assert_in_delta 0.1, g.hue(c), 1 / 256.0
49
+ assert_in_delta 0.2, g.saturation(c), 1 / 256.0
50
+ assert_in_delta 0.3, g.brightness(c), 1 / 256.0
51
+ assert_in_delta 0.4, g.alpha(c), 1 / 256.0
26
52
  end
27
53
 
28
54
  def test_colorMode()
@@ -76,6 +102,85 @@ class TestGraphicsContext < Test::Unit::TestCase
76
102
  END
77
103
  end
78
104
 
105
+ def test_textFont()
106
+ graphics do |g|
107
+ arial10 = g.createFont 'Arial', 10
108
+ helvetica11 = g.createFont 'Helvetica', 11
109
+
110
+ font = -> {g.instance_variable_get(:@textFont__).getInternal__}
111
+ painterFont = -> {g.instance_variable_get(:@painter__).font}
112
+
113
+ assert_not_nil font[] .name
114
+ assert_not_equal 'Arial', font[] .name
115
+ assert_equal 12, font[] .size
116
+ assert_equal 12, painterFont[].size
117
+
118
+ g.textFont arial10
119
+ assert_equal 'Arial', font[] .name
120
+ assert_equal 10, font[] .size
121
+ assert_equal 10, painterFont[].size
122
+
123
+ g.push do
124
+ g.textFont helvetica11
125
+ assert_equal 'Helvetica', font[] .name
126
+ assert_equal 11, font[] .size
127
+ assert_equal 11, painterFont[].size
128
+ end
129
+
130
+ assert_equal 'Arial', font[] .name
131
+ assert_equal 10, font[] .size
132
+ assert_equal 10, painterFont[].size
133
+
134
+ g.push do
135
+ g.textFont arial10, 13
136
+ assert_equal 'Arial', font[] .name
137
+ assert_equal 13, font[] .size
138
+ assert_equal 13, painterFont[].size
139
+ end
140
+
141
+ assert_equal 'Arial', font[] .name
142
+ assert_equal 10, font[] .size
143
+ assert_equal 10, painterFont[].size
144
+ end
145
+ end
146
+
147
+ def test_textSize()
148
+ graphics do |g|
149
+ font = -> {g.instance_variable_get(:@textFont__).getInternal__}
150
+ painterFont = -> {g.instance_variable_get(:@painter__).font}
151
+
152
+ assert_equal 12, font[] .size
153
+ assert_equal 12, painterFont[].size
154
+
155
+ g.push do
156
+ g.textSize 10
157
+ assert_equal 10, font[] .size
158
+ assert_equal 10, painterFont[].size
159
+ end
160
+
161
+ assert_equal 12, font[] .size
162
+ assert_equal 12, painterFont[].size
163
+ end
164
+ end
165
+
166
+ def test_textLeading()
167
+ assert_p5_draw <<~END, threshold: 0.97
168
+ noStroke
169
+ textSize 200
170
+ push
171
+ text "X\nX", 100, 200
172
+ textLeading 300
173
+ text "X\nX", 250, 200
174
+ textLeading 400
175
+ text "X\nX", 400, 200
176
+ textLeading 100
177
+ text "X\nX", 550, 200
178
+ textLeading 0
179
+ text "X\nX", 700, 200
180
+ pop
181
+ END
182
+ end
183
+
79
184
  def test_clear()
80
185
  colors = -> g {get_pixels(g).uniq}
81
186
 
@@ -186,16 +291,42 @@ class TestGraphicsContext < Test::Unit::TestCase
186
291
 
187
292
  def test_curve()
188
293
  src = 'curve 100,100, 100,500, 500,500, 600,100'
189
- assert_p5_fill src, threshold: 0
190
- assert_p5_stroke src, threshold: 0
191
- assert_p5_fill_stroke src, threshold: 0
294
+ assert_p5_fill src, threshold: THRESHOLD_TO_BE_FIXED
295
+ assert_p5_stroke src
296
+ assert_p5_fill_stroke src
192
297
  end
193
298
 
194
299
  def test_bezier()
195
- src = 'curve 100,100, 100,500, 500,500, 600,100'
196
- assert_p5_fill src, threshold: 0
197
- assert_p5_stroke src, threshold: 0
198
- assert_p5_fill_stroke src, threshold: 0
300
+ src = 'bezier 100,100, 100,500, 500,500, 600,100'
301
+ assert_p5_fill src
302
+ assert_p5_stroke src
303
+ assert_p5_fill_stroke src
304
+ end
305
+
306
+ def test_curveDetail()
307
+ opts = {
308
+ webgl: true,
309
+ # tests in headless mode will time out...
310
+ headless: false,
311
+ # Something is wrong with the behavior of `p5.js + WEBGL + curve()`
312
+ threshold: THRESHOLD_TO_BE_FIXED
313
+ }
314
+ [1, 2, 3, 5, 10, 100].each do |detail|
315
+ assert_p5_stroke <<~END, label: test_label(2, suffix: detail), **opts
316
+ curveDetail #{detail}
317
+ curve 100,100, 100,500, 500,500, 600,100
318
+ END
319
+ end
320
+ end
321
+
322
+ def test_bezierDetail()
323
+ opts = {webgl: true, headless: false} # tests in headless mode will time out...
324
+ [1, 2, 3, 5, 10, 100].each do |detail|
325
+ assert_p5_stroke <<~END, label: test_label(2, suffix: detail), **opts
326
+ bezierDetail #{detail}
327
+ bezier 100,100, 100,500, 500,500, 600,100
328
+ END
329
+ end
199
330
  end
200
331
 
201
332
  def test_shape_with_shapeMode_corner()
@@ -468,6 +599,330 @@ class TestGraphicsContext < Test::Unit::TestCase
468
599
  assert_p5_fill_stroke src, 'endShape CLOSE'
469
600
  end
470
601
 
602
+ def test_beginShape_with_fill()
603
+ assert_equal_draw <<~HEADER, <<~EXPECTED, <<~ACTUAL
604
+ noStroke
605
+ HEADER
606
+ fill 0, 255, 0
607
+ rect 100, 100, 500, 400
608
+ EXPECTED
609
+ beginShape
610
+ fill 0, 255, 0
611
+ vertex 100, 100
612
+ vertex 600, 100
613
+ vertex 600, 500
614
+ vertex 100, 500
615
+ endShape
616
+ ACTUAL
617
+ end
618
+
619
+ def test_curveVertex()
620
+ src = <<~END
621
+ beginShape
622
+ curveVertex 100, 100
623
+ curveVertex 800, 100
624
+ curveVertex 800, 800
625
+ curveVertex 100, 800
626
+ END
627
+ assert_p5_fill src, 'endShape'
628
+ assert_p5_stroke src, 'endShape'
629
+ assert_p5_fill_stroke src, 'endShape'
630
+ assert_p5_fill src, 'endShape CLOSE'
631
+ assert_p5_stroke src, 'endShape CLOSE'
632
+ assert_p5_fill_stroke src, 'endShape CLOSE'
633
+
634
+ src = <<~END
635
+ beginShape
636
+ curveVertex 200, 200
637
+ curveVertex 200, 200
638
+ curveVertex 800, 200
639
+ curveVertex 800, 400
640
+ curveVertex 200, 400
641
+ curveVertex 200, 800
642
+ curveVertex 800, 800
643
+ curveVertex 800, 700
644
+ curveVertex 800, 700
645
+ END
646
+ assert_p5_fill src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
647
+ assert_p5_stroke src, 'endShape'
648
+ assert_p5_fill_stroke src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
649
+ assert_p5_fill src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
650
+ assert_p5_stroke src, 'endShape CLOSE'
651
+ assert_p5_fill_stroke src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
652
+ end
653
+
654
+ def test_bezierVertex()
655
+ src = <<~END
656
+ beginShape
657
+ vertex 100, 100
658
+ bezierVertex 900, 100, 900, 900, 200, 500
659
+ END
660
+ assert_p5_fill src, 'endShape'
661
+ assert_p5_stroke src, 'endShape'
662
+ assert_p5_fill_stroke src, 'endShape'
663
+ assert_p5_fill src, 'endShape CLOSE'
664
+ assert_p5_stroke src, 'endShape CLOSE'
665
+ assert_p5_fill_stroke src, 'endShape CLOSE'
666
+
667
+ src = <<~END
668
+ beginShape
669
+ vertex 100, 100
670
+ bezierVertex 900, 100, 900, 500, 300, 500
671
+ bezierVertex 100, 900, 900, 900, 900, 600
672
+ END
673
+ assert_p5_fill src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
674
+ assert_p5_stroke src, 'endShape'
675
+ assert_p5_fill_stroke src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
676
+ assert_p5_fill src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
677
+ assert_p5_stroke src, 'endShape CLOSE'
678
+ assert_p5_fill_stroke src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
679
+ end
680
+
681
+ def test_quadraticVertex()
682
+ src = <<~END
683
+ beginShape
684
+ vertex 100, 100
685
+ quadraticVertex 800, 500, 200, 800
686
+ END
687
+ assert_p5_fill src, 'endShape'
688
+ assert_p5_stroke src, 'endShape'
689
+ assert_p5_fill_stroke src, 'endShape'
690
+ assert_p5_fill src, 'endShape CLOSE'
691
+ assert_p5_stroke src, 'endShape CLOSE'
692
+ assert_p5_fill_stroke src, 'endShape CLOSE'
693
+
694
+ src = <<~END
695
+ beginShape
696
+ vertex 100, 100
697
+ quadraticVertex 800, 100, 500, 500
698
+ quadraticVertex 100, 800, 800, 800
699
+ END
700
+ assert_p5_fill src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
701
+ assert_p5_stroke src, 'endShape'
702
+ assert_p5_fill_stroke src, 'endShape', threshold: THRESHOLD_TO_BE_FIXED
703
+ assert_p5_fill src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
704
+ assert_p5_stroke src, 'endShape CLOSE'
705
+ assert_p5_fill_stroke src, 'endShape CLOSE', threshold: THRESHOLD_TO_BE_FIXED
706
+ end
707
+
708
+ def test_contour()
709
+ src = <<~END
710
+ beginShape
711
+ vertex 100, 100
712
+ vertex 100, 900
713
+ vertex 900, 900
714
+ vertex 900, 100
715
+ beginContour
716
+ vertex 200, 200
717
+ vertex 800, 200
718
+ vertex 700, 700
719
+ vertex 200, 800
720
+ endContour
721
+ END
722
+ assert_p5_fill src, 'endShape'
723
+ assert_p5_stroke src, 'endShape'
724
+ assert_p5_fill_stroke src, 'endShape'
725
+ assert_p5_fill src, 'endShape CLOSE'
726
+ assert_p5_stroke src, 'endShape CLOSE'
727
+ assert_p5_fill_stroke src, 'endShape CLOSE'
728
+ end
729
+
730
+ def test_pixels()
731
+ g = graphics 2, 2
732
+
733
+ g.loadPixels
734
+ assert_equal [0] * 4, g.pixels
735
+ assert_equal [0] * 4, g.getInternal__.pixels
736
+
737
+ g.pixels.replace [0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000]
738
+ assert_equal [0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000], g.pixels
739
+ assert_equal [0] * 4, g.getInternal__.pixels
740
+
741
+ g.updatePixels
742
+ assert_nil g.pixels
743
+ assert_equal [0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000], g.getInternal__.pixels
744
+ assert_nothing_raised {g.updatePixels}
745
+
746
+ g.loadPixels
747
+ g.pixels.replace [0xff000000]
748
+ assert_raise(ArgumentError) {g.updatePixels}
749
+ end
750
+
751
+ def test_pixels_and_modified_flags()
752
+ drawRect = -> g, x, *rgb do
753
+ g.beginDraw do
754
+ g.fill(*rgb)
755
+ g.rect x, 0, 2, 2
756
+ end
757
+ end
758
+ updatePixels = -> g, i, *rgb do
759
+ g.loadPixels
760
+ g.pixels[i] = g.color(*rgb)
761
+ g.updatePixels
762
+ end
763
+ getPixels = -> g do
764
+ g.getInternal__.pixels
765
+ .select.with_index {|_, i| i.even?}
766
+ .map {|n| n.to_s 16}
767
+ end
768
+
769
+ g = graphics 6, 1
770
+ drawRect .call g, 0, 255,0,0
771
+ assert_equal %w[ffff0000 0 0], getPixels.call(g)
772
+
773
+ g = graphics 6, 1
774
+ drawRect .call g, 0, 255,0,0
775
+ updatePixels.call g, 2, 0,255,0
776
+ assert_equal %w[ffff0000 ff00ff00 0], getPixels.call(g)
777
+
778
+ g = graphics 6, 1
779
+ drawRect .call g, 0, 255,0,0
780
+ updatePixels.call g, 2, 0,255,0
781
+ drawRect .call g, 4, 0,0,255
782
+ assert_equal %w[ffff0000 ff00ff00 ff0000ff], getPixels.call(g)
783
+ end
784
+
785
+ def test_rotateX()
786
+ assert_p5_draw <<~END, webgl: true, headless: false
787
+ noStroke
788
+ translate 100, 100
789
+ rotateX PI * 0.1
790
+ rect 0, 0, 500, 500
791
+ END
792
+ end
793
+
794
+ def test_rotateY()
795
+ assert_p5_draw <<~END, webgl: true, headless: false
796
+ noStroke
797
+ translate 100, 100
798
+ rotateY PI * 0.1
799
+ rect 0, 0, 500, 500
800
+ END
801
+ end
802
+
803
+ def test_rotateZ()
804
+ assert_p5_draw <<~END, webgl: true, headless: false
805
+ noStroke
806
+ translate 100, 100
807
+ rotateZ PI * 0.1
808
+ rect 0, 0, 500, 500
809
+ END
810
+ end
811
+
812
+ def test_shearX()
813
+ assert_p5_draw <<~END
814
+ translate 100, 100
815
+ shearX PI * 0.2
816
+ rect 0, 0, 500, 500
817
+ END
818
+ end
819
+
820
+ def test_shearY()
821
+ assert_p5_draw <<~END
822
+ translate 100, 100
823
+ shearY PI * 0.2
824
+ rect 0, 0, 500, 500
825
+ END
826
+ end
827
+
828
+ def test_applyMatrix()
829
+ g = graphics
830
+
831
+ painterMatrix = -> {g.instance_variable_get(:@painter__).matrix.to_a}
832
+
833
+ g.beginDraw do
834
+ g.resetMatrix
835
+ g.applyMatrix 1,2, 3,4, 5,6
836
+ assert_equal [1,2,0,0, 3,4,0,0, 0,0,1,0, 5,6,0,1], painterMatrix.call
837
+
838
+ g.resetMatrix
839
+ g.applyMatrix [1,2, 3,4, 5,6]
840
+ assert_equal [1,2,0,0, 3,4,0,0, 0,0,1,0, 5,6,0,1], painterMatrix.call
841
+
842
+ g.resetMatrix
843
+ g.applyMatrix 1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16
844
+ assert_equal [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16], painterMatrix.call
845
+
846
+ g.resetMatrix
847
+ g.applyMatrix [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]
848
+ assert_equal [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16], painterMatrix.call
849
+
850
+ ((0..17).to_a - [6, 16]).each do |n|
851
+ assert_raise(ArgumentError) {g.applyMatrix [0] * n}
852
+ assert_raise(ArgumentError) {g.applyMatrix(*([0] * n))}
853
+ end
854
+ end
855
+ end
856
+
857
+ def test_applyMatrix_translate()
858
+ assert_p5_draw <<~END
859
+ applyMatrix 1, 0, 0, 1, 100, 200
860
+ rect 100, 100, 500, 600
861
+ END
862
+ assert_p5_draw <<~END
863
+ applyMatrix [1, 0, 0, 1, 100, 200]
864
+ rect 100, 100, 500, 600
865
+ END
866
+ assert_p5_draw <<~END, webgl: true, headless: false
867
+ applyMatrix 1,0,0,0, 0,1,0,0, 0,0,1,0, 100,200,0,1
868
+ rect 100, 100, 500, 600
869
+ END
870
+ assert_p5_draw <<~END, webgl: true, headless: false
871
+ applyMatrix [1,0,0,0, 0,1,0,0, 0,0,1,0, 100,200,0,1]
872
+ rect 100, 100, 500, 600
873
+ END
874
+ end
875
+
876
+ def test_applyMatrix_scale()
877
+ assert_p5_draw <<~END
878
+ applyMatrix 2, 0, 0, 3, 0, 0
879
+ rect 100, 100, 200, 200
880
+ END
881
+ assert_p5_draw <<~END
882
+ applyMatrix [2, 0, 0, 3, 0, 0]
883
+ rect 100, 100, 200, 200
884
+ END
885
+ assert_p5_draw <<~END, webgl: true, headless: false, threshold: THRESHOLD_TO_BE_FIXED
886
+ applyMatrix 2,0,0,0, 0,3,0,0, 0,0,1,0, 0,0,0,1
887
+ rect 100, 100, 200, 200
888
+ END
889
+ assert_p5_draw <<~END, webgl: true, headless: false, threshold: THRESHOLD_TO_BE_FIXED
890
+ applyMatrix [2,0,0,0, 0,3,0,0, 0,0,1,0, 0,0,0,1]
891
+ rect 100, 100, 200, 200
892
+ END
893
+ end
894
+
895
+ def test_applyMatrix_rotate()
896
+ header = 's, c = Math.sin(Math::PI / 10), Math.cos(Math::PI / 10)'
897
+ assert_p5_draw header, <<~END
898
+ applyMatrix c, s, -s, c, 0, 0
899
+ rect 100, 100, 500, 600
900
+ END
901
+ assert_p5_draw header, <<~END
902
+ applyMatrix [c, s, -s, c, 0, 0]
903
+ rect 100, 100, 500, 600
904
+ END
905
+ assert_p5_draw header, <<~END, webgl: true, headless: false
906
+ applyMatrix c,s,0,0, -s,c,0,0, 0,0,1,0, 0,0,0,1
907
+ rect 100, 100, 500, 600
908
+ END
909
+ assert_p5_draw header, <<~END, webgl: true, headless: false
910
+ applyMatrix [c,s,0,0, -s,c,0,0, 0,0,1,0, 0,0,0,1]
911
+ rect 100, 100, 500, 600
912
+ END
913
+ end
914
+
915
+ def test_applyMatrix_multiple_times()
916
+ assert_p5_draw <<~END
917
+ applyMatrix 1, 0, 0, 1, 100, 200
918
+ s = Math.sin(Math::PI / 10)
919
+ c = Math.cos(Math::PI / 10)
920
+ applyMatrix c, s, -s, c, 0, 0
921
+ applyMatrix 2, 0, 0, 3, 0, 0
922
+ rect 100, 100, 100, 100
923
+ END
924
+ end
925
+
471
926
  def test_lerp()
472
927
  g = graphics
473
928
 
@@ -491,6 +946,16 @@ class TestGraphicsContext < Test::Unit::TestCase
491
946
  assert_equal c[ 70, 80, 90], g.lerpColor(c[10, 20, 30], c[50, 60, 70], 1.5)
492
947
  end
493
948
 
949
+ def test_createFont()
950
+ g = graphics
951
+
952
+ assert_not_nil g.createFont(nil, nil).getInternal__.name
953
+ assert_equal 'Arial', g.createFont('Arial', nil).getInternal__.name
954
+
955
+ assert_equal 12, g.createFont(nil, nil).getInternal__.size
956
+ assert_equal 10, g.createFont(nil, 10) .getInternal__.size
957
+ end
958
+
494
959
  def test_createShape_line()
495
960
  assert_equal_draw <<~EXPECTED, <<~ACTUAL
496
961
  line 100, 200, 800, 900
@@ -539,4 +1004,193 @@ class TestGraphicsContext < Test::Unit::TestCase
539
1004
  ACTUAL
540
1005
  end
541
1006
 
1007
+ def test_curvePoint()
1008
+ assert_p5_draw <<~END
1009
+ steps = 8
1010
+ (0..steps).each do |i|
1011
+ t = i.to_f / steps.to_f;
1012
+ x = curvePoint(*[20, 20, 292, 292].map {|n| n * 3}, t)
1013
+ y = curvePoint(*[104, 104, 96, 244].map {|n| n * 3}, t)
1014
+ point x, y
1015
+ x = curvePoint(*[20, 292, 292, 60] .map {|n| n * 3}, t)
1016
+ y = curvePoint(*[104, 96, 244, 260].map {|n| n * 3}, t)
1017
+ point x, y
1018
+ end
1019
+ END
1020
+ end
1021
+
1022
+ def test_bezierPoint()
1023
+ assert_p5_draw <<~END
1024
+ steps = 10
1025
+ (0..steps).each do |i|
1026
+ t = i.to_f / steps.to_f
1027
+ x = bezierPoint(*[85, 10, 90, 15].map {|n| n * 10}, t)
1028
+ y = bezierPoint(*[20, 10, 90, 80].map {|n| n * 10}, t)
1029
+ point x, y
1030
+ end
1031
+ END
1032
+ end
1033
+
1034
+ def test_curveTangent()
1035
+ assert_p5_draw <<~END
1036
+ drawTangent = -> x, y, tx, ty do
1037
+ tv = createVector tx, ty
1038
+ tv.normalize
1039
+ tv.rotate radians(-90)
1040
+ point x, y
1041
+ push
1042
+ stroke 0, 0, 255
1043
+ strokeWeight 20
1044
+ line x, y, x + tv.x * 100, y + tv.y * 100
1045
+ pop
1046
+ end
1047
+ steps = 8
1048
+ (0..steps).each do |i|
1049
+ t = i.to_f / steps.to_f;
1050
+
1051
+ xx = [20, 20, 292, 292].map {|n| n * 2}
1052
+ yy = [104, 104, 96, 244].map {|n| n * 3}
1053
+ x = curvePoint( *xx, t)
1054
+ y = curvePoint( *yy, t)
1055
+ tx = curveTangent(*xx, t)
1056
+ ty = curveTangent(*yy, t)
1057
+ drawTangent.call x, y, tx, ty
1058
+
1059
+ xx = [20, 292, 292, 60] .map {|n| n * 2}
1060
+ yy = [104, 96, 244, 260].map {|n| n * 3}
1061
+ x = curvePoint( *xx, t)
1062
+ y = curvePoint( *yy, t)
1063
+ tx = curveTangent(*xx, t)
1064
+ ty = curveTangent(*yy, t)
1065
+ drawTangent.call x, y, tx, ty
1066
+ end
1067
+ END
1068
+ end
1069
+
1070
+ def test_bezierTangent()
1071
+ assert_p5_draw <<~END
1072
+ drawTangent = -> x, y, tx, ty do
1073
+ tv = createVector tx, ty
1074
+ tv.normalize
1075
+ tv.rotate radians(-90)
1076
+ point x, y
1077
+ push
1078
+ stroke 0, 0, 255
1079
+ strokeWeight 20
1080
+ line x, y, x + tv.x * 100, y + tv.y * 100
1081
+ pop
1082
+ end
1083
+ steps = 10
1084
+ (0..steps).each do |i|
1085
+ t = i.to_f / steps.to_f
1086
+
1087
+ xx = *[85, 10, 90, 15].map {|n| n * 10}
1088
+ yy = *[20, 10, 90, 80].map {|n| n * 10}
1089
+ x = bezierPoint( *xx, t)
1090
+ y = bezierPoint( *yy, t)
1091
+ tx = bezierTangent(*xx, t)
1092
+ ty = bezierTangent(*yy, t)
1093
+ drawTangent.call x, y, tx, ty
1094
+ end
1095
+ END
1096
+ end
1097
+
1098
+ def test_random()
1099
+ g = graphics
1100
+
1101
+ assert_equal Float, g.random() .class
1102
+ assert_equal Float, g.random(1) .class
1103
+ assert_equal Float, g.random(1.0) .class
1104
+ assert_equal Float, g.random(1, 2) .class
1105
+ assert_equal Float, g.random(1.0, 2.0).class
1106
+
1107
+ assert_not_equal g.random(1.0), g.random(1.0)
1108
+
1109
+ assert_raise(ArgumentError) {g.random 0}
1110
+ assert_raise(ArgumentError) {g.random 1, 1}
1111
+
1112
+ array = 10000.times.map {g.random 1, 2}
1113
+ assert array.all? {|n| (1.0...2.0).include? n}
1114
+ assert_in_delta 1.5, array.sum.to_f / array.size, 0.01
1115
+ end
1116
+
1117
+ def test_random_choice()
1118
+ g = graphics
1119
+
1120
+ assert_equal :a, g.random([:a])
1121
+ assert_equal :a, g.random([:a, :a])
1122
+ assert_equal nil, g.random([])
1123
+ assert_equal nil, g.random([nil])
1124
+
1125
+ array = 10000.times.map {g.random([1, 2])}
1126
+ assert array.all? {|n| (1..10).include? n}
1127
+ assert_in_delta 1.5, array.sum.to_f / array.size, 0.02
1128
+ end
1129
+
1130
+ def test_randomSeed()
1131
+ g = graphics
1132
+ r0 = g.random 1
1133
+ g.randomSeed 1; r1 = g.random 1
1134
+ g.randomSeed 2; r2 = g.random 1
1135
+
1136
+ assert_equal 3, [r0, r1, r2].uniq.size
1137
+
1138
+ g.randomSeed 1
1139
+ assert_equal r1, g.random(1)
1140
+ end
1141
+
1142
+ def test_randomSeed_choice()
1143
+ g = graphics
1144
+ r0 = g.random((0...10000).to_a)
1145
+ g.randomSeed 1; r1 = g.random((0...10000).to_a)
1146
+ g.randomSeed 2; r2 = g.random((0...10000).to_a)
1147
+
1148
+ assert_equal 3, [r0, r1, r2].uniq.size
1149
+
1150
+ g.randomSeed 1
1151
+ assert_equal r1, g.random((0...10000).to_a)
1152
+ end
1153
+
1154
+ def test_randomGaussian()
1155
+ g = graphics
1156
+
1157
+ assert_equal Float, g.randomGaussian.class
1158
+
1159
+ array = 10000.times.map {g.randomGaussian}
1160
+ assert array.select {|n| (0...3).include? n.abs}.size > 9800
1161
+ assert_in_delta 0, array.sum.to_f / array.size, 0.05
1162
+ end
1163
+
1164
+ def test_noise()
1165
+ g = graphics
1166
+ assert_equal g.noise(0.1, 0.2, 0.3), g.noise(0.1, 0.2, 0.3)
1167
+ assert_not_equal g.noise(0.1, 0.2, 0.3), g.noise(0.2, 0.2, 0.3)
1168
+ assert_not_equal g.noise(0.1, 0.2, 0.3), g.noise(0.1, 0.3, 0.3)
1169
+ assert_not_equal g.noise(0.1, 0.2, 0.3), g.noise(0.1, 0.2, 0.4)
1170
+ end
1171
+
1172
+ def test_noiseSeed()
1173
+ g = graphics
1174
+ n0 = g.noise 0.1, 0.2, 0.3
1175
+ g.noiseSeed 1; n1 = g.noise 0.1, 0.2, 0.3
1176
+ g.noiseSeed 2; n2 = g.noise 0.1, 0.2, 0.3
1177
+
1178
+ assert_equal 3, [n0, n1, n2].uniq.size
1179
+
1180
+ g.noiseSeed 1
1181
+ assert_equal n1, g.noise(0.1, 0.2, 0.3)
1182
+ end
1183
+
1184
+ def test_noiseDetail()
1185
+ g = graphics
1186
+ n0 = g.noise 0.1, 0.2, 0.3
1187
+ g.noiseDetail 1; n1 = g.noise 0.1, 0.2, 0.3
1188
+ g.noiseDetail 2; n2 = g.noise 0.1, 0.2, 0.3
1189
+ g.noiseDetail 3; n3 = g.noise 0.1, 0.2, 0.3
1190
+ g.noiseDetail 4; n4 = g.noise 0.1, 0.2, 0.3
1191
+
1192
+ assert_equal 4, [n1, n2, n3, n4].uniq.size
1193
+ assert_equal n4, n0
1194
+ end
1195
+
542
1196
  end# TestGraphicsContext