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.
- 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
|