processing 0.5.31 → 0.5.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +57 -0
- data/VERSION +1 -1
- data/lib/processing/all.rb +3 -1
- data/lib/processing/context.rb +103 -16
- data/lib/processing/events.rb +22 -0
- data/lib/processing/font.rb +30 -3
- data/lib/processing/graphics.rb +2 -13
- data/lib/processing/graphics_context.rb +820 -107
- data/lib/processing/image.rb +38 -10
- data/lib/processing/shape.rb +152 -33
- data/lib/processing/window.rb +96 -58
- data/processing.gemspec +4 -4
- data/test/helper.rb +7 -5
- data/test/p5.rb +6 -5
- data/test/test_font.rb +33 -2
- data/test/test_graphics_context.rb +662 -8
- data/test/test_image.rb +21 -0
- data/test/test_shape.rb +125 -0
- data/test/test_utility.rb +0 -19
- metadata +12 -11
@@ -25,6 +25,14 @@ module Processing
|
|
25
25
|
#
|
26
26
|
TAU = PI * 2
|
27
27
|
|
28
|
+
# Processing mode for renderMode().
|
29
|
+
#
|
30
|
+
PROCESSING = :processing
|
31
|
+
|
32
|
+
# p5.js mode for renderMode().
|
33
|
+
#
|
34
|
+
P5JS = :p5js
|
35
|
+
|
28
36
|
# RGBA format for createImage().
|
29
37
|
#
|
30
38
|
RGBA = :rgba
|
@@ -129,6 +137,18 @@ module Processing
|
|
129
137
|
# Mode for textAlign().
|
130
138
|
BASELINE = :baseline
|
131
139
|
|
140
|
+
# Mode for textureMode().
|
141
|
+
IMAGE = :image
|
142
|
+
|
143
|
+
# Mode for textureMode().
|
144
|
+
NORMAL = :normal
|
145
|
+
|
146
|
+
# Mode for textureWrap().
|
147
|
+
CLAMP = :clamp
|
148
|
+
|
149
|
+
# Mode for textureWrap().
|
150
|
+
REPEAT = :repeat
|
151
|
+
|
132
152
|
# Filter type for filter()
|
133
153
|
THRESHOLD = :threshold
|
134
154
|
|
@@ -247,29 +267,50 @@ module Processing
|
|
247
267
|
# @private
|
248
268
|
RAD2DEG__ = 180.0 / Math::PI
|
249
269
|
|
270
|
+
# @private
|
271
|
+
FONT_SIZE_DEFAULT__ = 12
|
272
|
+
|
273
|
+
# @private
|
274
|
+
FONT_SIZE_MAX__ = 256
|
275
|
+
|
250
276
|
# @private
|
251
277
|
def init__(image, painter)
|
252
|
-
@drawing__
|
253
|
-
@
|
254
|
-
@
|
255
|
-
@
|
256
|
-
@
|
257
|
-
@
|
258
|
-
@
|
259
|
-
@
|
260
|
-
@
|
261
|
-
@
|
262
|
-
@
|
263
|
-
@
|
264
|
-
@
|
265
|
-
@
|
266
|
-
@
|
267
|
-
@
|
268
|
-
@
|
269
|
-
@
|
278
|
+
@drawing__ = false
|
279
|
+
@renderMode__ = nil
|
280
|
+
@p5jsMode__ = false
|
281
|
+
@colorMode__ = nil
|
282
|
+
@hsbColor__ = false
|
283
|
+
@colorMaxes__ = [1.0] * 4
|
284
|
+
@angleMode__ = nil
|
285
|
+
@toRad__ = 1.0
|
286
|
+
@toDeg__ = 1.0
|
287
|
+
@fromRad__ = 1.0
|
288
|
+
@fromDeg__ = 1.0
|
289
|
+
@rectMode__ = nil
|
290
|
+
@ellipseMode__ = nil
|
291
|
+
@imageMode__ = nil
|
292
|
+
@shapeMode__ = nil
|
293
|
+
@blendMode__ = nil
|
294
|
+
@curveDetail__ = nil
|
295
|
+
@curveTightness__ = nil
|
296
|
+
@bezierDetail__ = nil
|
297
|
+
@textAlignH__ = nil
|
298
|
+
@textAlignV__ = nil
|
299
|
+
@textFont__ = nil
|
300
|
+
@tint__ = nil
|
301
|
+
@filter__ = nil
|
302
|
+
@pixels__ = nil
|
303
|
+
@random__ = nil
|
304
|
+
@nextGaussian__ = nil
|
305
|
+
@noiseSeed__ = nil
|
306
|
+
@noiseOctaves__ = nil
|
307
|
+
@noiseFallOff__ = nil
|
308
|
+
@matrixStack__ = []
|
309
|
+
@styleStack__ = []
|
270
310
|
|
271
311
|
updateCanvas__ image, painter
|
272
312
|
|
313
|
+
renderMode PROCESSING
|
273
314
|
colorMode RGB, 255
|
274
315
|
angleMode RADIANS
|
275
316
|
rectMode CORNER
|
@@ -280,11 +321,20 @@ module Processing
|
|
280
321
|
strokeCap ROUND
|
281
322
|
strokeJoin MITER
|
282
323
|
textAlign LEFT
|
324
|
+
textFont createFont(nil, nil)
|
325
|
+
textureMode IMAGE
|
326
|
+
textureWrap CLAMP
|
283
327
|
|
284
|
-
fill
|
285
|
-
stroke
|
286
|
-
strokeWeight
|
328
|
+
fill 255
|
329
|
+
stroke 0
|
330
|
+
strokeWeight 1
|
287
331
|
noTint
|
332
|
+
curveDetail 20
|
333
|
+
curveTightness 0
|
334
|
+
bezierDetail 20
|
335
|
+
randomSeed Random.new_seed
|
336
|
+
noiseSeed Random.new_seed
|
337
|
+
noiseDetail 4, 0.5
|
288
338
|
end
|
289
339
|
|
290
340
|
# @private
|
@@ -300,6 +350,26 @@ module Processing
|
|
300
350
|
@matrixStack__.clear
|
301
351
|
@styleStack__.clear
|
302
352
|
@drawing__ = true
|
353
|
+
setupMatrix__
|
354
|
+
end
|
355
|
+
|
356
|
+
# @private
|
357
|
+
def setupMatrix__()
|
358
|
+
w, h = width.to_f, height.to_f
|
359
|
+
x, y = w / 2.0, h / 2.0
|
360
|
+
|
361
|
+
fov, z = nil
|
362
|
+
if @p5jsMode__
|
363
|
+
z = 800
|
364
|
+
fov = degrees Math.atan(y / z) * 2.0
|
365
|
+
else
|
366
|
+
fov = 60
|
367
|
+
z = y / Math.tan(radians(fov) / 2.0)
|
368
|
+
end
|
369
|
+
|
370
|
+
@painter__.matrix =
|
371
|
+
Rays::Matrix.perspective(fov, w / h, z / 10.0, z * 10.0) *
|
372
|
+
Rays::Matrix.look_at(x, y, z, x, y, 0)
|
303
373
|
end
|
304
374
|
|
305
375
|
# @private
|
@@ -313,7 +383,7 @@ module Processing
|
|
313
383
|
# @return [Numeric] width
|
314
384
|
#
|
315
385
|
def width()
|
316
|
-
|
386
|
+
getInternal__.width
|
317
387
|
end
|
318
388
|
|
319
389
|
# Returns the height of the graphics object.
|
@@ -321,7 +391,7 @@ module Processing
|
|
321
391
|
# @return [Numeric] height
|
322
392
|
#
|
323
393
|
def height()
|
324
|
-
|
394
|
+
getInternal__.height
|
325
395
|
end
|
326
396
|
|
327
397
|
# Returns the width of the graphics object in pixels.
|
@@ -348,6 +418,20 @@ module Processing
|
|
348
418
|
@painter__.pixel_density
|
349
419
|
end
|
350
420
|
|
421
|
+
# Sets render mode.
|
422
|
+
#
|
423
|
+
# @param mode [PROCESSING, P5JS] compatible to Processing or p5.js
|
424
|
+
#
|
425
|
+
# @return [PROCESSING, P5JS] current mode
|
426
|
+
#
|
427
|
+
def renderMode(mode = nil)
|
428
|
+
if mode
|
429
|
+
@renderMode__ = mode
|
430
|
+
@p5jsMode__ = mode == P5JS
|
431
|
+
end
|
432
|
+
@renderMode__
|
433
|
+
end
|
434
|
+
|
351
435
|
# Sets color mode and max color values.
|
352
436
|
#
|
353
437
|
# @overload colorMode(mode)
|
@@ -441,19 +525,56 @@ module Processing
|
|
441
525
|
((color >> 24) & 0xff) / 255.0 * @colorMaxes__[3]
|
442
526
|
end
|
443
527
|
|
528
|
+
# Returns the hue value of the color.
|
529
|
+
#
|
530
|
+
# @param color [Numeric] color value
|
531
|
+
#
|
532
|
+
# @return [Numeric] the hue value
|
533
|
+
#
|
534
|
+
def hue(color)
|
535
|
+
h, = toRawColor__(color).to_hsv
|
536
|
+
h * (@hsbColor__ ? @colorMaxes__[0] : 1)
|
537
|
+
end
|
538
|
+
|
539
|
+
# Returns the saturation value of the color.
|
540
|
+
#
|
541
|
+
# @param color [Numeric] color value
|
542
|
+
#
|
543
|
+
# @return [Numeric] the saturation value
|
544
|
+
#
|
545
|
+
def saturation(color)
|
546
|
+
_, s, = toRawColor__(color).to_hsv
|
547
|
+
s * (@hsbColor__ ? @colorMaxes__[1] : 1)
|
548
|
+
end
|
549
|
+
|
550
|
+
# Returns the brightness value of the color.
|
551
|
+
#
|
552
|
+
# @param color [Numeric] color value
|
553
|
+
#
|
554
|
+
# @return [Numeric] the brightness value
|
555
|
+
#
|
556
|
+
def brightness(color)
|
557
|
+
_, _, b = toRawColor__(color).to_hsv
|
558
|
+
b * (@hsbColor__ ? @colorMaxes__[2] : 1)
|
559
|
+
end
|
560
|
+
|
444
561
|
# @private
|
445
562
|
private def toRGBA__(*args)
|
446
|
-
a, b
|
563
|
+
a, b = args
|
447
564
|
return parseColor__(a, b || alphaMax__) if a.kind_of?(String)
|
565
|
+
rawColor__(*args).to_a
|
566
|
+
end
|
448
567
|
|
568
|
+
# @private
|
569
|
+
def rawColor__(*args)
|
570
|
+
a, b, c, d = args
|
449
571
|
rgba = case args.size
|
450
572
|
when 1, 2 then [a, a, a, b || alphaMax__]
|
451
573
|
when 3, 4 then [a, b, c, d || alphaMax__]
|
452
574
|
else raise ArgumentError
|
453
575
|
end
|
454
|
-
rgba
|
455
|
-
|
456
|
-
color.to_a
|
576
|
+
rgba = rgba.map.with_index {|value, i| value / @colorMaxes__[i]}
|
577
|
+
@hsbColor__ ? Rays::Color.hsv(*rgba) : Rays::Color.new(*rgba)
|
457
578
|
end
|
458
579
|
|
459
580
|
# @private
|
@@ -470,6 +591,15 @@ module Processing
|
|
470
591
|
@colorMaxes__[3]
|
471
592
|
end
|
472
593
|
|
594
|
+
# @private
|
595
|
+
private def toRawColor__(color)
|
596
|
+
Rays::Color.new(
|
597
|
+
((color >> 16) & 0xff) / 255.0,
|
598
|
+
((color >> 8) & 0xff) / 255.0,
|
599
|
+
( color & 0xff) / 255.0,
|
600
|
+
((color >> 24) & 0xff) / 255.0)
|
601
|
+
end
|
602
|
+
|
473
603
|
# Sets angle mode.
|
474
604
|
#
|
475
605
|
# @param mode [RADIANS, DEGREES] RADIANS or DEGREES
|
@@ -479,37 +609,34 @@ module Processing
|
|
479
609
|
def angleMode(mode = nil)
|
480
610
|
if mode != nil
|
481
611
|
@angleMode__ = mode
|
482
|
-
@
|
612
|
+
@toRad__, @toDeg__, @fromRad__, @fromDeg__ =
|
483
613
|
case mode.downcase.to_sym
|
484
|
-
when RADIANS then RAD2DEG__
|
485
|
-
when DEGREES then 1.0
|
614
|
+
when RADIANS then [1.0, RAD2DEG__, 1.0, DEG2RAD__]
|
615
|
+
when DEGREES then [DEG2RAD__, 1.0, RAD2DEG__, 1.0]
|
486
616
|
else raise ArgumentError, "invalid angle mode: #{mode}"
|
487
617
|
end
|
488
618
|
end
|
489
619
|
@angleMode__
|
490
620
|
end
|
491
621
|
|
622
|
+
# @private
|
623
|
+
def toRadians__(angle)
|
624
|
+
angle * @toRad__
|
625
|
+
end
|
626
|
+
|
492
627
|
# @private
|
493
628
|
def toDegrees__(angle)
|
494
|
-
angle * @
|
629
|
+
angle * @toDeg__
|
495
630
|
end
|
496
631
|
|
497
632
|
# @private
|
498
633
|
def fromRadians__(radians)
|
499
|
-
|
500
|
-
when RADIANS then radians
|
501
|
-
when DEGREES then radians * RAD2DEG__
|
502
|
-
else raise "invalid angle mode: #{mode}"
|
503
|
-
end
|
634
|
+
radians * @fromRad__
|
504
635
|
end
|
505
636
|
|
506
637
|
# @private
|
507
638
|
def fromDegrees__(degrees)
|
508
|
-
|
509
|
-
when RADIANS then degrees * DEG2RAD__
|
510
|
-
when DEGREES then degrees
|
511
|
-
else raise "invalid angle mode: #{mode}"
|
512
|
-
end
|
639
|
+
degrees * @fromDeg__
|
513
640
|
end
|
514
641
|
|
515
642
|
# Sets rect mode. Default is CORNER.
|
@@ -618,6 +745,11 @@ module Processing
|
|
618
745
|
nil
|
619
746
|
end
|
620
747
|
|
748
|
+
# @private
|
749
|
+
def getFill__()
|
750
|
+
@painter__.fill
|
751
|
+
end
|
752
|
+
|
621
753
|
# Disables filling.
|
622
754
|
#
|
623
755
|
# @return [nil] nil
|
@@ -692,6 +824,52 @@ module Processing
|
|
692
824
|
nil
|
693
825
|
end
|
694
826
|
|
827
|
+
# Sets the resolution at which curves display.
|
828
|
+
# The default value is 20 while the minimum value is 3.
|
829
|
+
#
|
830
|
+
# @param detail [Numeric] resolution of the curves
|
831
|
+
#
|
832
|
+
# @return [nil] nil
|
833
|
+
#
|
834
|
+
# @see https://processing.org/reference/curveDetail_.html
|
835
|
+
# @see https://p5js.org/reference/#/p5/curveDetail
|
836
|
+
#
|
837
|
+
def curveDetail(detail)
|
838
|
+
detail = 3 if detail < 3
|
839
|
+
@curveDetail__ = detail
|
840
|
+
nil
|
841
|
+
end
|
842
|
+
|
843
|
+
# Sets the quality of curve forms.
|
844
|
+
#
|
845
|
+
# @param tightness [Numeric] determines how the curve fits to the vertex points
|
846
|
+
#
|
847
|
+
# @return [nil] nil
|
848
|
+
#
|
849
|
+
# @see https://processing.org/reference/curveTightness_.html
|
850
|
+
# @see https://p5js.org/reference/#/p5/curveTightness
|
851
|
+
#
|
852
|
+
def curveTightness(tightness)
|
853
|
+
@curveTightness__ = tightness
|
854
|
+
nil
|
855
|
+
end
|
856
|
+
|
857
|
+
# Sets the resolution at which Bezier's curve is displayed.
|
858
|
+
# The default value is 20.
|
859
|
+
#
|
860
|
+
# @param detail [Numeric] resolution of the curves
|
861
|
+
#
|
862
|
+
# @return [nil] nil
|
863
|
+
#
|
864
|
+
# @see https://processing.org/reference/bezierDetail_.html
|
865
|
+
# @see https://p5js.org/reference/#/p5/bezierDetail
|
866
|
+
#
|
867
|
+
def bezierDetail(detail)
|
868
|
+
detail = 1 if detail < 1
|
869
|
+
@bezierDetail__ = detail
|
870
|
+
nil
|
871
|
+
end
|
872
|
+
|
695
873
|
# Sets fill color for drawing images.
|
696
874
|
#
|
697
875
|
# @overload tint(rgb)
|
@@ -723,6 +901,11 @@ module Processing
|
|
723
901
|
@tint__ = nil
|
724
902
|
end
|
725
903
|
|
904
|
+
# @private
|
905
|
+
def getTint__()
|
906
|
+
@tint__ ? toRGBA__(*@tint__) : 1
|
907
|
+
end
|
908
|
+
|
726
909
|
# Limits the drawable rectangle.
|
727
910
|
#
|
728
911
|
# The parameters a, b, c, and d are determined by rectMode().
|
@@ -749,12 +932,14 @@ module Processing
|
|
749
932
|
nil
|
750
933
|
end
|
751
934
|
|
752
|
-
# Sets font.
|
935
|
+
# Sets text font.
|
936
|
+
# (Passing a font name as the first parameter is deprecated)
|
753
937
|
#
|
938
|
+
# @overload textFont()
|
754
939
|
# @overload textFont(font)
|
755
|
-
# @overload textFont(name)
|
940
|
+
# @overload textFont(name) [DEPRECATED]
|
756
941
|
# @overload textFont(font, size)
|
757
|
-
# @overload textFont(name, size)
|
942
|
+
# @overload textFont(name, size) [DEPRECATED]
|
758
943
|
#
|
759
944
|
# @param font [Font] font
|
760
945
|
# @param name [String] font name
|
@@ -763,8 +948,17 @@ module Processing
|
|
763
948
|
# @return [Font] current font
|
764
949
|
#
|
765
950
|
def textFont(font = nil, size = nil)
|
766
|
-
|
767
|
-
|
951
|
+
if font != nil || size != nil
|
952
|
+
size = FONT_SIZE_MAX__ if size && size > FONT_SIZE_MAX__
|
953
|
+
if font.nil? || font.kind_of?(String)
|
954
|
+
font = createFont font, size
|
955
|
+
elsif size
|
956
|
+
font.setSize__ size
|
957
|
+
end
|
958
|
+
@painter__.font = font.getInternal__
|
959
|
+
@textFont__ = font
|
960
|
+
end
|
961
|
+
@textFont__
|
768
962
|
end
|
769
963
|
|
770
964
|
# Sets text size.
|
@@ -774,8 +968,7 @@ module Processing
|
|
774
968
|
# @return [nil] nil
|
775
969
|
#
|
776
970
|
def textSize(size)
|
777
|
-
|
778
|
-
nil
|
971
|
+
textFont @textFont__, size
|
779
972
|
end
|
780
973
|
|
781
974
|
def textWidth(str)
|
@@ -795,16 +988,60 @@ module Processing
|
|
795
988
|
@textAlignV__ = vertical
|
796
989
|
end
|
797
990
|
|
991
|
+
# Sets the spacing between lines of text in units of pixels.
|
992
|
+
#
|
993
|
+
# @overload textLeading()
|
994
|
+
# @overload textLeading(leading)
|
995
|
+
#
|
996
|
+
# @param leading [Numeric] the size in pixels for spacing between lines
|
997
|
+
#
|
998
|
+
# @return [Numeric] current spacing
|
999
|
+
#
|
1000
|
+
def textLeading(leading = nil)
|
1001
|
+
@painter__.line_height = leading if leading
|
1002
|
+
@painter__.line_height
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def texture(image)
|
1006
|
+
@painter__.texture image&.getInternal__
|
1007
|
+
nil
|
1008
|
+
end
|
1009
|
+
|
798
1010
|
# @private
|
799
|
-
def
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
1011
|
+
def drawWithTexture__(&block)
|
1012
|
+
if @painter__.texture
|
1013
|
+
@painter__.push fill: getTint__, &block
|
1014
|
+
else
|
1015
|
+
block.call
|
1016
|
+
end
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
# Sets the coordinate space for texture mapping.
|
1020
|
+
#
|
1021
|
+
# @param mode [IMAGE, NORMAL] image coordinate, or normalized coordinate
|
1022
|
+
#
|
1023
|
+
# @return [nil] nil
|
1024
|
+
#
|
1025
|
+
# @see https://processing.org/reference/textureMode_.html
|
1026
|
+
# @see https://p5js.org/reference/#/p5/textureMode
|
1027
|
+
#
|
1028
|
+
def textureMode(mode)
|
1029
|
+
@painter__.texcoord_mode = mode
|
1030
|
+
nil
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
# Sets the texture wrapping mode.
|
1034
|
+
#
|
1035
|
+
# @param wrap [CLAMP, REPEAT] how texutres behave when go outside of the range
|
1036
|
+
#
|
1037
|
+
# @return [nil] nil
|
1038
|
+
#
|
1039
|
+
# @see https://processing.org/reference/textureWrap_.html
|
1040
|
+
# @see https://p5js.org/reference/#/p5/textureWrap
|
1041
|
+
#
|
1042
|
+
def textureWrap(wrap)
|
1043
|
+
@painter__.texcoord_wrap = wrap
|
1044
|
+
nil
|
808
1045
|
end
|
809
1046
|
|
810
1047
|
# Sets shader.
|
@@ -887,7 +1124,7 @@ module Processing
|
|
887
1124
|
#
|
888
1125
|
def point(x, y)
|
889
1126
|
assertDrawing__
|
890
|
-
@painter__.
|
1127
|
+
@painter__.point x, y
|
891
1128
|
nil
|
892
1129
|
end
|
893
1130
|
|
@@ -1070,7 +1307,9 @@ module Processing
|
|
1070
1307
|
#
|
1071
1308
|
def curve(cx1, cy1, x1, y1, x2, y2, cx2, cy2)
|
1072
1309
|
assertDrawing__
|
1310
|
+
@painter__.nsegment = @curveDetail__
|
1073
1311
|
@painter__.curve cx1, cy1, x1, y1, x2, y2, cx2, cy2
|
1312
|
+
@painter__.nsegment = 0
|
1074
1313
|
nil
|
1075
1314
|
end
|
1076
1315
|
|
@@ -1091,7 +1330,9 @@ module Processing
|
|
1091
1330
|
#
|
1092
1331
|
def bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2)
|
1093
1332
|
assertDrawing__
|
1333
|
+
@painter__.nsegment = @bezierDetail__
|
1094
1334
|
@painter__.bezier x1, y1, cx1, cy1, cx2, cy2, x2, y2
|
1335
|
+
@painter__.nsegment = 0
|
1095
1336
|
nil
|
1096
1337
|
end
|
1097
1338
|
|
@@ -1156,8 +1397,7 @@ module Processing
|
|
1156
1397
|
def image(img, a, b, c = nil, d = nil)
|
1157
1398
|
assertDrawing__
|
1158
1399
|
x, y, w, h = toXYWH__ @imageMode__, a, b, c || img.width, d || img.height
|
1159
|
-
|
1160
|
-
img.drawImage__ @painter__, x, y, w, h, fill: tint, stroke: :none
|
1400
|
+
img.drawImage__ @painter__, x, y, w, h, fill: getTint__, stroke: :none
|
1161
1401
|
nil
|
1162
1402
|
end
|
1163
1403
|
|
@@ -1182,11 +1422,13 @@ module Processing
|
|
1182
1422
|
assertDrawing__
|
1183
1423
|
return nil unless shp.isVisible
|
1184
1424
|
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1425
|
+
drawWithTexture__ do |_|
|
1426
|
+
if c || d || @shapeMode__ != CORNER
|
1427
|
+
x, y, w, h = toXYWH__ @shapeMode__, a, b, c || shp.width, d || shp.height
|
1428
|
+
shp.draw__ @painter__, x, y, w, h
|
1429
|
+
else
|
1430
|
+
shp.draw__ @painter__, a, b
|
1431
|
+
end
|
1190
1432
|
end
|
1191
1433
|
nil
|
1192
1434
|
end
|
@@ -1195,7 +1437,7 @@ module Processing
|
|
1195
1437
|
|
1196
1438
|
# Begins drawing complex shapes.
|
1197
1439
|
#
|
1198
|
-
# @param
|
1440
|
+
# @param type [POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP, TESS]
|
1199
1441
|
#
|
1200
1442
|
# @return [nil] nil
|
1201
1443
|
#
|
@@ -1217,9 +1459,10 @@ module Processing
|
|
1217
1459
|
#
|
1218
1460
|
# @see https://processing.org/reference/beginShape_.html
|
1219
1461
|
#
|
1220
|
-
def beginShape(
|
1221
|
-
|
1222
|
-
|
1462
|
+
def beginShape(type = nil)
|
1463
|
+
raise "beginShape() cannot be called twice" if @drawingShape__
|
1464
|
+
@drawingShape__ = createShape
|
1465
|
+
@drawingShape__.beginShape type
|
1223
1466
|
end
|
1224
1467
|
|
1225
1468
|
# Ends drawing complex shapes.
|
@@ -1234,25 +1477,114 @@ module Processing
|
|
1234
1477
|
# @see https://processing.org/reference/endShape_.html
|
1235
1478
|
#
|
1236
1479
|
def endShape(mode = nil)
|
1237
|
-
raise "endShape() must be called after beginShape()"
|
1238
|
-
|
1239
|
-
|
1240
|
-
@
|
1480
|
+
s = @drawingShape__ or raise "endShape() must be called after beginShape()"
|
1481
|
+
s.endShape mode
|
1482
|
+
shape s
|
1483
|
+
@drawingShape__ = nil
|
1241
1484
|
nil
|
1242
1485
|
end
|
1243
1486
|
|
1487
|
+
# Begins drawing a hole inside shape.
|
1488
|
+
#
|
1489
|
+
# @return [nil] nil
|
1490
|
+
#
|
1491
|
+
# @example
|
1492
|
+
# beginShape
|
1493
|
+
# vertex 10, 10
|
1494
|
+
# vertex 10, 50
|
1495
|
+
# vertex 50, 50
|
1496
|
+
# vertex 90, 10
|
1497
|
+
# beginContour
|
1498
|
+
# vertex 20, 20
|
1499
|
+
# vertex 30, 20
|
1500
|
+
# vertex 30, 30
|
1501
|
+
# vertex 20, 30
|
1502
|
+
# endContour
|
1503
|
+
# endShape CLOSE
|
1504
|
+
#
|
1505
|
+
# @see https://processing.org/reference/beginContour_.html
|
1506
|
+
# @see https://p5js.org/reference/#/p5/beginContour
|
1507
|
+
#
|
1508
|
+
def beginContour()
|
1509
|
+
(@drawingShape__ or raise "beginContour() must be called after beginShape()")
|
1510
|
+
.beginContour
|
1511
|
+
end
|
1512
|
+
|
1513
|
+
# Ends drawing a hole.
|
1514
|
+
#
|
1515
|
+
# @return [nil] nil
|
1516
|
+
#
|
1517
|
+
# @see https://processing.org/reference/endContour_.html
|
1518
|
+
# @see https://p5js.org/reference/#/p5/endContour
|
1519
|
+
#
|
1520
|
+
def endContour()
|
1521
|
+
(@drawingShape__ or raise "endContour() must be called after beginShape()")
|
1522
|
+
.endContour
|
1523
|
+
end
|
1524
|
+
|
1244
1525
|
# Append vertex for shape polygon.
|
1245
1526
|
#
|
1527
|
+
# @overload vertex(x, y)
|
1528
|
+
# @overload vertex(x, y, u, v)
|
1529
|
+
#
|
1246
1530
|
# @param x [Numeric] x position of vertex
|
1247
1531
|
# @param y [Numeric] y position of vertex
|
1532
|
+
# @param u [Numeric] u texture coordinate of vertex
|
1533
|
+
# @param v [Numeric] v texture coordinate of vertex
|
1248
1534
|
#
|
1249
1535
|
# @return [nil] nil
|
1250
1536
|
#
|
1251
1537
|
# @see https://processing.org/reference/vertex_.html
|
1538
|
+
# @see https://p5js.org/reference/#/p5/vertex
|
1539
|
+
#
|
1540
|
+
def vertex(x, y, u = nil, v = nil)
|
1541
|
+
(@drawingShape__ or raise "vertex() must be called after beginShape()")
|
1542
|
+
.vertex x, y, u, v
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
# Append curve vertex for shape polygon.
|
1546
|
+
#
|
1547
|
+
# @param x [Numeric] x position of vertex
|
1548
|
+
# @param y [Numeric] y position of vertex
|
1549
|
+
#
|
1550
|
+
# @return [nil] nil
|
1551
|
+
#
|
1552
|
+
# @see https://processing.org/reference/curveVertex_.html
|
1553
|
+
# @see https://p5js.org/reference/#/p5/curveVertex
|
1252
1554
|
#
|
1253
|
-
def
|
1254
|
-
raise "
|
1255
|
-
|
1555
|
+
def curveVertex(x, y)
|
1556
|
+
(@drawingShape__ or raise "curveVertex() must be called after beginShape()")
|
1557
|
+
.curveVertex x, y
|
1558
|
+
end
|
1559
|
+
|
1560
|
+
# Append bezier vertex for shape polygon.
|
1561
|
+
#
|
1562
|
+
# @param x [Numeric] x position of vertex
|
1563
|
+
# @param y [Numeric] y position of vertex
|
1564
|
+
#
|
1565
|
+
# @return [nil] nil
|
1566
|
+
#
|
1567
|
+
# @see https://processing.org/reference/bezierVertex_.html
|
1568
|
+
# @see https://p5js.org/reference/#/p5/bezierVertex
|
1569
|
+
#
|
1570
|
+
def bezierVertex(x2, y2, x3, y3, x4, y4)
|
1571
|
+
(@drawingShape__ or raise "bezierVertex() must be called after beginShape()")
|
1572
|
+
.bezierVertex x2, y2, x3, y3, x4, y4
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
# Append quadratic vertex for shape polygon.
|
1576
|
+
#
|
1577
|
+
# @param x [Numeric] x position of vertex
|
1578
|
+
# @param y [Numeric] y position of vertex
|
1579
|
+
#
|
1580
|
+
# @return [nil] nil
|
1581
|
+
#
|
1582
|
+
# @see https://processing.org/reference/quadraticVertex_.html
|
1583
|
+
# @see https://p5js.org/reference/#/p5/quadraticVertex
|
1584
|
+
#
|
1585
|
+
def quadraticVertex(cx, cy, x3, y3)
|
1586
|
+
(@drawingShape__ or raise "quadraticVertex() must be called after beginShape()")
|
1587
|
+
.quadraticVertex cx, cy, x3, y3
|
1256
1588
|
end
|
1257
1589
|
|
1258
1590
|
# Copies image.
|
@@ -1296,11 +1628,41 @@ module Processing
|
|
1296
1628
|
#
|
1297
1629
|
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
1298
1630
|
assertDrawing__
|
1299
|
-
|
1300
|
-
img ||= self
|
1301
|
-
img.drawImage__(
|
1631
|
+
(img || self).drawImage__(
|
1302
1632
|
@painter__, sx, sy, sw, sh, dx, dy, dw, dh,
|
1303
|
-
fill:
|
1633
|
+
fill: getTint__, stroke: :none, blend_mode: mode)
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
# Loads all pixels to the 'pixels' array.
|
1637
|
+
#
|
1638
|
+
# @return [nil] nil
|
1639
|
+
#
|
1640
|
+
def loadPixels()
|
1641
|
+
@pixels__ = getInternal__.pixels
|
1642
|
+
end
|
1643
|
+
|
1644
|
+
# Update the image pixels with the 'pixels' array.
|
1645
|
+
#
|
1646
|
+
# @return [nil] nil
|
1647
|
+
#
|
1648
|
+
def updatePixels(&block)
|
1649
|
+
return if !block && !@pixels__
|
1650
|
+
if block
|
1651
|
+
loadPixels
|
1652
|
+
block.call pixels
|
1653
|
+
end
|
1654
|
+
getInternal__.tap do |img|
|
1655
|
+
img.pixels = @pixels__
|
1656
|
+
img.paint {} # update texture and set modifiied
|
1657
|
+
end
|
1658
|
+
@pixels__ = nil
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
# An array of all pixels.
|
1662
|
+
# Call loadPixels() before accessing the array.
|
1663
|
+
#
|
1664
|
+
def pixels()
|
1665
|
+
@pixels__
|
1304
1666
|
end
|
1305
1667
|
|
1306
1668
|
# Saves screen image to file.
|
@@ -1310,7 +1672,7 @@ module Processing
|
|
1310
1672
|
# @return [nil] nil
|
1311
1673
|
#
|
1312
1674
|
def save(filename)
|
1313
|
-
|
1675
|
+
getInternal__.save filename
|
1314
1676
|
nil
|
1315
1677
|
end
|
1316
1678
|
|
@@ -1360,6 +1722,42 @@ module Processing
|
|
1360
1722
|
nil
|
1361
1723
|
end
|
1362
1724
|
|
1725
|
+
def rotateX(angle)
|
1726
|
+
assertDrawing__
|
1727
|
+
@painter__.rotate toDegrees__(angle), 1, 0, 0
|
1728
|
+
nil
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
def rotateY(angle)
|
1732
|
+
assertDrawing__
|
1733
|
+
@painter__.rotate toDegrees__(angle), 0, 1, 0
|
1734
|
+
nil
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
def rotateZ(angle)
|
1738
|
+
assertDrawing__
|
1739
|
+
@painter__.rotate toDegrees__(angle), 0, 0, 1
|
1740
|
+
nil
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
def shearX(angle)
|
1744
|
+
t = Math.tan toRadians__(angle)
|
1745
|
+
@painter__.matrix *= Rays::Matrix.new(
|
1746
|
+
1, t, 0, 0,
|
1747
|
+
0, 1, 0, 0,
|
1748
|
+
0, 0, 1, 0,
|
1749
|
+
0, 0, 0, 1)
|
1750
|
+
end
|
1751
|
+
|
1752
|
+
def shearY(angle)
|
1753
|
+
t = Math.tan toRadians__(angle)
|
1754
|
+
@painter__.matrix *= Rays::Matrix.new(
|
1755
|
+
1, 0, 0, 0,
|
1756
|
+
t, 1, 0, 0,
|
1757
|
+
0, 0, 1, 0,
|
1758
|
+
0, 0, 0, 1)
|
1759
|
+
end
|
1760
|
+
|
1363
1761
|
# Pushes the current transformation matrix to stack.
|
1364
1762
|
#
|
1365
1763
|
# @return [Object] result of the expression at the end of the block
|
@@ -1383,6 +1781,51 @@ module Processing
|
|
1383
1781
|
nil
|
1384
1782
|
end
|
1385
1783
|
|
1784
|
+
# Reset current transformation matrix with 2x3, or 4x4 matrix.
|
1785
|
+
#
|
1786
|
+
# @overload applyMatrix(array)
|
1787
|
+
# @overload applyMatrix(a, b, c, d, e, f)
|
1788
|
+
# @overload applyMatrix(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
|
1789
|
+
#
|
1790
|
+
# @param array [Array] 6 or 16 numbers which define the matrix
|
1791
|
+
# @param a [Numeric] number which defines the matrix
|
1792
|
+
# @param b [Numeric] number which defines the matrix
|
1793
|
+
# @param c [Numeric] number which defines the matrix
|
1794
|
+
# @param d [Numeric] number which defines the matrix
|
1795
|
+
# @param e [Numeric] number which defines the matrix
|
1796
|
+
# @param f [Numeric] number which defines the matrix
|
1797
|
+
# @param g [Numeric] number which defines the matrix
|
1798
|
+
# @param h [Numeric] number which defines the matrix
|
1799
|
+
# @param i [Numeric] number which defines the matrix
|
1800
|
+
# @param j [Numeric] number which defines the matrix
|
1801
|
+
# @param k [Numeric] number which defines the matrix
|
1802
|
+
# @param l [Numeric] number which defines the matrix
|
1803
|
+
# @param m [Numeric] number which defines the matrix
|
1804
|
+
# @param n [Numeric] number which defines the matrix
|
1805
|
+
# @param o [Numeric] number which defines the matrix
|
1806
|
+
# @param p [Numeric] number which defines the matrix
|
1807
|
+
#
|
1808
|
+
# @return [nil] nil
|
1809
|
+
#
|
1810
|
+
def applyMatrix(*args)
|
1811
|
+
assertDrawing__
|
1812
|
+
args = args.first if args.first.kind_of?(Array)
|
1813
|
+
if args.size == 6
|
1814
|
+
a, b, c, d, e, f = args
|
1815
|
+
args = [
|
1816
|
+
a, b, 0, 0,
|
1817
|
+
c, d, 0, 0,
|
1818
|
+
0, 0, 1, 0,
|
1819
|
+
e, f, 0, 1
|
1820
|
+
]
|
1821
|
+
end
|
1822
|
+
raise ArgumentError unless args.size == 16
|
1823
|
+
m = Rays::Matrix.new(*args)
|
1824
|
+
m.transpose! if @p5jsMode__
|
1825
|
+
@painter__.matrix *= m
|
1826
|
+
nil
|
1827
|
+
end
|
1828
|
+
|
1386
1829
|
# Reset current transformation matrix with identity matrix.
|
1387
1830
|
#
|
1388
1831
|
# @return [nil] nil
|
@@ -1393,6 +1836,17 @@ module Processing
|
|
1393
1836
|
nil
|
1394
1837
|
end
|
1395
1838
|
|
1839
|
+
# Prints matrix elements to console.
|
1840
|
+
#
|
1841
|
+
# @return [nil] nil
|
1842
|
+
#
|
1843
|
+
def printMatrix()
|
1844
|
+
m = @painter__.matrix
|
1845
|
+
m.transpose! if @p5jsMode__
|
1846
|
+
print "%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" % m.to_a
|
1847
|
+
nil
|
1848
|
+
end
|
1849
|
+
|
1396
1850
|
# Save current style values to the style stack.
|
1397
1851
|
#
|
1398
1852
|
# @return [Object] result of the expression at the end of the block
|
@@ -1405,19 +1859,34 @@ module Processing
|
|
1405
1859
|
@painter__.stroke_width,
|
1406
1860
|
@painter__.stroke_cap,
|
1407
1861
|
@painter__.stroke_join,
|
1862
|
+
@painter__.miter_limit,
|
1863
|
+
@painter__.line_height!,
|
1408
1864
|
@painter__.clip,
|
1409
1865
|
@painter__.blend_mode,
|
1410
1866
|
@painter__.font,
|
1867
|
+
@painter__.texture,
|
1868
|
+
@painter__.texcoord_mode,
|
1869
|
+
@painter__.texcoord_wrap,
|
1411
1870
|
@painter__.shader,
|
1871
|
+
@colorMode__,
|
1412
1872
|
@hsbColor__,
|
1413
1873
|
@colorMaxes__,
|
1414
|
-
@
|
1874
|
+
@angleMode__,
|
1875
|
+
@toRad__,
|
1876
|
+
@toDeg__,
|
1877
|
+
@fromRad__,
|
1878
|
+
@fromDeg__,
|
1415
1879
|
@rectMode__,
|
1416
1880
|
@ellipseMode__,
|
1417
1881
|
@imageMode__,
|
1418
1882
|
@shapeMode__,
|
1883
|
+
@blendMode__,
|
1884
|
+
@curveDetail__,
|
1885
|
+
@curveTightness__,
|
1886
|
+
@bezierDetail__,
|
1419
1887
|
@textAlignH__,
|
1420
1888
|
@textAlignV__,
|
1889
|
+
@textFont__,
|
1421
1890
|
@tint__,
|
1422
1891
|
]
|
1423
1892
|
block.call if block
|
@@ -1437,20 +1906,36 @@ module Processing
|
|
1437
1906
|
@painter__.stroke_width,
|
1438
1907
|
@painter__.stroke_cap,
|
1439
1908
|
@painter__.stroke_join,
|
1909
|
+
@painter__.miter_limit,
|
1910
|
+
@painter__.line_height,
|
1440
1911
|
@painter__.clip,
|
1441
1912
|
@painter__.blend_mode,
|
1442
1913
|
@painter__.font,
|
1914
|
+
@painter__.texture,
|
1915
|
+
@painter__.texcoord_mode,
|
1916
|
+
@painter__.texcoord_wrap,
|
1443
1917
|
@painter__.shader,
|
1918
|
+
@colorMode__,
|
1444
1919
|
@hsbColor__,
|
1445
1920
|
@colorMaxes__,
|
1446
|
-
@
|
1921
|
+
@angleMode__,
|
1922
|
+
@toRad__,
|
1923
|
+
@toDeg__,
|
1924
|
+
@fromRad__,
|
1925
|
+
@fromDeg__,
|
1447
1926
|
@rectMode__,
|
1448
1927
|
@ellipseMode__,
|
1449
1928
|
@imageMode__,
|
1450
1929
|
@shapeMode__,
|
1930
|
+
@blendMode__,
|
1931
|
+
@curveDetail__,
|
1932
|
+
@curveTightness__,
|
1933
|
+
@bezierDetail__,
|
1451
1934
|
@textAlignH__,
|
1452
1935
|
@textAlignV__,
|
1936
|
+
@textFont__,
|
1453
1937
|
@tint__ = @styleStack__.pop
|
1938
|
+
@textFont__.setSize__ @painter__.font.size
|
1454
1939
|
nil
|
1455
1940
|
end
|
1456
1941
|
|
@@ -1481,10 +1966,10 @@ module Processing
|
|
1481
1966
|
end
|
1482
1967
|
|
1483
1968
|
# @private
|
1484
|
-
def drawImage__(painter, *args, **states)
|
1969
|
+
def drawImage__(painter, *args, image__: getInternal__, **states)
|
1485
1970
|
shader = painter.shader || @filter__&.getInternal__
|
1486
1971
|
painter.push shader: shader, **states do |_|
|
1487
|
-
painter.image
|
1972
|
+
painter.image image__, *args
|
1488
1973
|
end
|
1489
1974
|
end
|
1490
1975
|
|
@@ -1827,6 +2312,98 @@ module Processing
|
|
1827
2312
|
Math.atan2 y, x
|
1828
2313
|
end
|
1829
2314
|
|
2315
|
+
# Evaluates the curve at point t for points a, b, c, d.
|
2316
|
+
#
|
2317
|
+
# @param a [Numeric] coordinate of first control point
|
2318
|
+
# @param b [Numeric] coordinate of first point on the curve
|
2319
|
+
# @param c [Numeric] coordinate of second point on the curve
|
2320
|
+
# @param d [Numeric] coordinate of second control point
|
2321
|
+
# @param t [Numeric] value between 0.0 and 1.0
|
2322
|
+
#
|
2323
|
+
# @return [Numeric] interpolated value
|
2324
|
+
#
|
2325
|
+
# @see https://processing.org/reference/curvePoint_.html
|
2326
|
+
# @see https://p5js.org/reference/#/p5/curvePoint
|
2327
|
+
#
|
2328
|
+
def curvePoint(a, b, c, d, t)
|
2329
|
+
s = @curveTightness__
|
2330
|
+
t3 = t * t * t
|
2331
|
+
t2 = t * t
|
2332
|
+
f1 = ( s - 1.0) / 2.0 * t3 + ( 1.0 - s) * t2 + (s - 1.0) / 2.0 * t
|
2333
|
+
f2 = ( s + 3.0) / 2.0 * t3 + (-5.0 - s) / 2.0 * t2 + 1.0
|
2334
|
+
f3 = (-3.0 - s) / 2.0 * t3 + ( s + 2.0) * t2 + (1.0 - s) / 2.0 * t
|
2335
|
+
f4 = ( 1.0 - s) / 2.0 * t3 + ( s - 1.0) / 2.0 * t2
|
2336
|
+
a * f1 + b * f2 + c * f3 + d * f4
|
2337
|
+
end
|
2338
|
+
|
2339
|
+
# Calculates the tangent of a point on a curve.
|
2340
|
+
#
|
2341
|
+
# @param a [Numeric] coordinate of first control point
|
2342
|
+
# @param b [Numeric] coordinate of first point on the curve
|
2343
|
+
# @param c [Numeric] coordinate of second point on the curve
|
2344
|
+
# @param d [Numeric] coordinate of second control point
|
2345
|
+
# @param t [Numeric] value between 0.0 and 1.0
|
2346
|
+
#
|
2347
|
+
# @return [Numeric] tangent value
|
2348
|
+
#
|
2349
|
+
# @see https://processing.org/reference/curveTangent_.html
|
2350
|
+
# @see https://p5js.org/reference/#/p5/curveTangent
|
2351
|
+
#
|
2352
|
+
def curveTangent(a, b, c, d, t)
|
2353
|
+
s = @curveTightness__
|
2354
|
+
tt3 = t * t * 3.0
|
2355
|
+
t2 = t * 2.0
|
2356
|
+
f1 = ( s - 1.0) / 2.0 * tt3 + ( 1.0 - s) * t2 + (s - 1.0) / 2.0
|
2357
|
+
f2 = ( s + 3.0) / 2.0 * tt3 + (-5.0 - s) / 2.0 * t2
|
2358
|
+
f3 = (-3.0 - s) / 2.0 * tt3 + ( s + 2.0) * t2 + (1.0 - s) / 2.0
|
2359
|
+
f4 = ( 1.0 - s) / 2.0 * tt3 + ( s - 1.0) / 2.0 * t2
|
2360
|
+
a * f1 + b * f2 + c * f3 + d * f4
|
2361
|
+
end
|
2362
|
+
|
2363
|
+
# Evaluates the Bezier at point t for points a, b, c, d.
|
2364
|
+
#
|
2365
|
+
# @param a [Numeric] coordinate of first point on the curve
|
2366
|
+
# @param b [Numeric] coordinate of first control point
|
2367
|
+
# @param c [Numeric] coordinate of second control point
|
2368
|
+
# @param d [Numeric] coordinate of second point on the curve
|
2369
|
+
# @param t [Numeric] value between 0.0 and 1.0
|
2370
|
+
#
|
2371
|
+
# @return [Numeric] interpolated value
|
2372
|
+
#
|
2373
|
+
# @see https://processing.org/reference/bezierPoint_.html
|
2374
|
+
# @see https://p5js.org/reference/#/p5/bezierPoint
|
2375
|
+
#
|
2376
|
+
def bezierPoint(a, b, c, d, t)
|
2377
|
+
tt = 1.0 - t
|
2378
|
+
tt ** 3.0 * a +
|
2379
|
+
tt ** 2.0 * b * 3.0 * t +
|
2380
|
+
t ** 2.0 * c * 3.0 * tt +
|
2381
|
+
t ** 3.0 * d
|
2382
|
+
end
|
2383
|
+
|
2384
|
+
# Calculates the tangent of a point on a Bezier curve.
|
2385
|
+
#
|
2386
|
+
# @param a [Numeric] coordinate of first point on the curve
|
2387
|
+
# @param b [Numeric] coordinate of first control point
|
2388
|
+
# @param c [Numeric] coordinate of second control point
|
2389
|
+
# @param d [Numeric] coordinate of second point on the curve
|
2390
|
+
# @param t [Numeric] value between 0.0 and 1.0
|
2391
|
+
#
|
2392
|
+
# @return [Numeric] tangent value
|
2393
|
+
#
|
2394
|
+
# @see https://processing.org/reference/bezierTangent_.html
|
2395
|
+
# @see https://p5js.org/reference/#/p5/bezierTangent
|
2396
|
+
#
|
2397
|
+
def bezierTangent(a, b, c, d, t)
|
2398
|
+
tt = 1.0 - t
|
2399
|
+
3.0 * d * t ** 2.0 -
|
2400
|
+
3.0 * c * t ** 2.0 +
|
2401
|
+
6.0 * c * tt * t -
|
2402
|
+
6.0 * b * tt * t +
|
2403
|
+
3.0 * b * tt ** 2.0 -
|
2404
|
+
3.0 * a * tt ** 2.0
|
2405
|
+
end
|
2406
|
+
|
1830
2407
|
# Returns the perlin noise value.
|
1831
2408
|
#
|
1832
2409
|
# @overload noise(x)
|
@@ -1839,13 +2416,52 @@ module Processing
|
|
1839
2416
|
#
|
1840
2417
|
# @return [Numeric] noise value (0.0..1.0)
|
1841
2418
|
#
|
2419
|
+
# @see https://processing.org/reference/noise_.html
|
2420
|
+
# @see https://p5js.org/reference/#/p5/noise
|
2421
|
+
#
|
1842
2422
|
def noise(x, y = 0, z = 0)
|
1843
|
-
|
2423
|
+
seed, falloff = @noiseSeed__, @noiseFallOff__
|
2424
|
+
amp = 0.5
|
2425
|
+
@noiseOctaves__.times.reduce(0) do |sum|
|
2426
|
+
value = (Rays.perlin(x, y, z, seed) / 2.0 + 0.5) * amp
|
2427
|
+
x *= 2
|
2428
|
+
y *= 2
|
2429
|
+
z *= 2
|
2430
|
+
amp *= falloff
|
2431
|
+
sum + value
|
2432
|
+
end
|
2433
|
+
end
|
2434
|
+
|
2435
|
+
# Sets the seed value for noise()
|
2436
|
+
#
|
2437
|
+
# @param seed [Numeric] seed value
|
2438
|
+
#
|
2439
|
+
# @return [nil] nil
|
2440
|
+
#
|
2441
|
+
# @see https://processing.org/reference/noiseSeed_.html
|
2442
|
+
# @see https://p5js.org/reference/#/p5/noiseSeed
|
2443
|
+
#
|
2444
|
+
def noiseSeed(seed)
|
2445
|
+
@noiseSeed__ = Random.new(seed).rand 0.0..1.0
|
2446
|
+
end
|
2447
|
+
|
2448
|
+
# Adjusts the character and level of detail produced by the Perlin noise function.
|
2449
|
+
#
|
2450
|
+
# @param lod [Numeric] number of octaves to be used by the noise
|
2451
|
+
# @param falloff [Numeric] falloff factor for each octave
|
2452
|
+
#
|
2453
|
+
# @return [nil] nil
|
2454
|
+
#
|
2455
|
+
# @see https://processing.org/reference/noiseDetail_.html
|
2456
|
+
# @see https://p5js.org/reference/#/p5/noiseDetail
|
2457
|
+
#
|
2458
|
+
def noiseDetail(lod, falloff = nil)
|
2459
|
+
@noiseOctaves__ = lod if lod && lod > 0
|
2460
|
+
@noiseFallOff__ = falloff if falloff && falloff > 0
|
1844
2461
|
end
|
1845
2462
|
|
1846
2463
|
# Returns a random number in range low...high
|
1847
2464
|
#
|
1848
|
-
# @overload random()
|
1849
2465
|
# @overload random(high)
|
1850
2466
|
# @overload random(low, high)
|
1851
2467
|
# @overload random(choices)
|
@@ -1856,13 +2472,63 @@ module Processing
|
|
1856
2472
|
#
|
1857
2473
|
# @return [Float] random number
|
1858
2474
|
#
|
2475
|
+
# @see https://processing.org/reference/random_.html
|
2476
|
+
# @see https://p5js.org/reference/#/p5/random
|
2477
|
+
#
|
1859
2478
|
def random(*args)
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
2479
|
+
if args.first.kind_of? Array
|
2480
|
+
a = args.first
|
2481
|
+
a.empty? ? nil : a[@random__.rand a.size]
|
2482
|
+
else
|
2483
|
+
high, low = args.reverse
|
2484
|
+
@random__.rand (low || 0).to_f...(high || 1).to_f
|
2485
|
+
end
|
2486
|
+
end
|
2487
|
+
|
2488
|
+
# Sets the seed value for random()
|
2489
|
+
#
|
2490
|
+
# @param seed [Numeric] seed value
|
2491
|
+
#
|
2492
|
+
# @return [nil] nil
|
2493
|
+
#
|
2494
|
+
# @see https://processing.org/reference/randomSeed_.html
|
2495
|
+
# @see https://p5js.org/reference/#/p5/randomSeed
|
2496
|
+
#
|
2497
|
+
def randomSeed(seed)
|
2498
|
+
@random__ = Random.new seed
|
2499
|
+
@nextGaussian__ = nil
|
1863
2500
|
end
|
1864
2501
|
|
1865
|
-
#
|
2502
|
+
# Returns a random number fitting a Gaussian, or normal, distribution.
|
2503
|
+
#
|
2504
|
+
# @param mean [Numeric] mean
|
2505
|
+
# @param sd [Numeric] standard deviation
|
2506
|
+
#
|
2507
|
+
# @return [Float] random number
|
2508
|
+
#
|
2509
|
+
# @see https://processing.org/reference/randomGaussian_.html
|
2510
|
+
# @see https://p5js.org/reference/#/p5/randomGaussian
|
2511
|
+
#
|
2512
|
+
def randomGaussian(mean = 0, sd = 1)
|
2513
|
+
value =
|
2514
|
+
if @nextGaussian__
|
2515
|
+
x, @nextGaussian__ = @nextGaussian__, nil
|
2516
|
+
x
|
2517
|
+
else
|
2518
|
+
a, b, w = 0, 0, 1
|
2519
|
+
until w < 1
|
2520
|
+
a = random(2) - 1
|
2521
|
+
b = random(2) - 1
|
2522
|
+
w = a ** 2 + b ** 2
|
2523
|
+
end
|
2524
|
+
w = Math.sqrt(-2 * Math.log(w) / w)
|
2525
|
+
@randomGaussian__ = a * w
|
2526
|
+
b * w
|
2527
|
+
end
|
2528
|
+
value * sd + mean
|
2529
|
+
end
|
2530
|
+
|
2531
|
+
# Creates a new vector object.
|
1866
2532
|
#
|
1867
2533
|
# @overload createVector()
|
1868
2534
|
# @overload createVector(x, y)
|
@@ -1878,7 +2544,17 @@ module Processing
|
|
1878
2544
|
Vector.new(*args, context: self)
|
1879
2545
|
end
|
1880
2546
|
|
1881
|
-
# Creates a new
|
2547
|
+
# Creates a new font object.
|
2548
|
+
#
|
2549
|
+
# @param name [String] font name
|
2550
|
+
# @param size [Numeric] font size (max 256)
|
2551
|
+
#
|
2552
|
+
def createFont(name, size)
|
2553
|
+
size = FONT_SIZE_MAX__ if size && size > FONT_SIZE_MAX__
|
2554
|
+
Font.new Rays::Font.new(name, size || FONT_SIZE_DEFAULT__)
|
2555
|
+
end
|
2556
|
+
|
2557
|
+
# Creates a new image object.
|
1882
2558
|
#
|
1883
2559
|
# @overload createImage(w, h)
|
1884
2560
|
# @overload createImage(w, h, format)
|
@@ -1895,7 +2571,7 @@ module Processing
|
|
1895
2571
|
Image.new Rays::Image.new(w, h, colorspace).paint {background 0, 0}
|
1896
2572
|
end
|
1897
2573
|
|
1898
|
-
# Creates a new shape.
|
2574
|
+
# Creates a new shape object.
|
1899
2575
|
#
|
1900
2576
|
# @overload createShape()
|
1901
2577
|
# @overload createShape(LINE, x1, y1, x2, y2)
|
@@ -1924,7 +2600,7 @@ module Processing
|
|
1924
2600
|
|
1925
2601
|
# @private
|
1926
2602
|
private def createLineShape__(x1, y1, x2, y2)
|
1927
|
-
Shape.new Rays::Polygon.
|
2603
|
+
Shape.new Rays::Polygon.line(x1, y1, x2, y2), context: self
|
1928
2604
|
end
|
1929
2605
|
|
1930
2606
|
# @private
|
@@ -2014,6 +2690,23 @@ module Processing
|
|
2014
2690
|
Capture.new(*args)
|
2015
2691
|
end
|
2016
2692
|
|
2693
|
+
# Loads font from file.
|
2694
|
+
#
|
2695
|
+
# @param filename [String] file name to load font file
|
2696
|
+
#
|
2697
|
+
# @return [Font] loaded font object
|
2698
|
+
#
|
2699
|
+
# @see https://processing.org/reference/loadFont_.html
|
2700
|
+
# @see https://p5js.org/reference/#/p5/loadFont
|
2701
|
+
#
|
2702
|
+
def loadFont(filename)
|
2703
|
+
ext = File.extname filename
|
2704
|
+
raise "unsupported font type -- '#{ext}'" unless ext =~ /^\.?(ttf|otf)$/i
|
2705
|
+
|
2706
|
+
filename = httpGet__ filename, ext if filename =~ %r|^https?://|
|
2707
|
+
Font.new Rays::Font.load filename
|
2708
|
+
end
|
2709
|
+
|
2017
2710
|
# Loads image.
|
2018
2711
|
#
|
2019
2712
|
# @param filename [String] file name to load image
|
@@ -2021,11 +2714,39 @@ module Processing
|
|
2021
2714
|
#
|
2022
2715
|
# @return [Image] loaded image object
|
2023
2716
|
#
|
2717
|
+
# @see https://processing.org/reference/loadImage_.html
|
2718
|
+
# @see https://p5js.org/reference/#/p5/loadImage
|
2719
|
+
#
|
2024
2720
|
def loadImage(filename, extension = nil)
|
2025
|
-
|
2721
|
+
ext = extension || File.extname(filename)
|
2722
|
+
raise "unsupported image type -- '#{ext}'" unless ext =~ /^\.?(png|jpg|gif)$/i
|
2723
|
+
|
2724
|
+
filename = httpGet__ filename, ext if filename =~ %r|^https?://|
|
2026
2725
|
Image.new Rays::Image.load filename
|
2027
2726
|
end
|
2028
2727
|
|
2728
|
+
# Loads image on a new thread.
|
2729
|
+
# When the image is loading, its width and height will be 0.
|
2730
|
+
# If an error occurs while loading the image, its width and height wil be -1.
|
2731
|
+
#
|
2732
|
+
# @param filename [String] file name to load image
|
2733
|
+
# @param extension [String] type of image to load (ex. 'png')
|
2734
|
+
#
|
2735
|
+
# @return [Image] loading image object
|
2736
|
+
#
|
2737
|
+
# @see https://processing.org/reference/requestImage_.html
|
2738
|
+
#
|
2739
|
+
def requestImage(filename, extension = nil)
|
2740
|
+
img = Image.new nil
|
2741
|
+
Thread.new filename, extension do |fn, ext|
|
2742
|
+
loaded = loadImage(fn, ext) or raise
|
2743
|
+
img.setInternal__ loaded.getInternal__
|
2744
|
+
rescue
|
2745
|
+
img.setInternal__ nil, true
|
2746
|
+
end
|
2747
|
+
img
|
2748
|
+
end
|
2749
|
+
|
2029
2750
|
# Loads shader file.
|
2030
2751
|
#
|
2031
2752
|
# @overload loadShader(fragPath)
|
@@ -2041,24 +2762,16 @@ module Processing
|
|
2041
2762
|
end
|
2042
2763
|
|
2043
2764
|
# @private
|
2044
|
-
private def
|
2045
|
-
ext ||= File.extname uri
|
2046
|
-
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png|jpg|gif)$/i
|
2047
|
-
|
2765
|
+
private def httpGet__(uri, ext)
|
2048
2766
|
tmpdir = tmpdir__
|
2049
2767
|
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
2050
2768
|
path = path.sub_ext ext
|
2051
2769
|
|
2052
2770
|
unless path.file?
|
2053
|
-
URI.
|
2054
|
-
|
2771
|
+
Net::HTTP.get_response URI.parse(uri) do |res|
|
2772
|
+
res.value # raise an error unless successful
|
2055
2773
|
tmpdir.mkdir unless tmpdir.directory?
|
2056
|
-
path.open('
|
2057
|
-
output.set_encoding Encoding::ASCII_8BIT
|
2058
|
-
while buf = input.read(2 ** 16)
|
2059
|
-
output.write buf
|
2060
|
-
end
|
2061
|
-
end
|
2774
|
+
path.open('wb') {|file| res.read_body {|body| file.write body}}
|
2062
2775
|
end
|
2063
2776
|
end
|
2064
2777
|
path.to_s
|