rubysketch 0.3.6 → 0.3.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a40d65c055cc2baacd0a7489ec511a0db37b8e534f58fc02d5c095f78ecca66
4
- data.tar.gz: 9c8634c610e0df8201655809b82bc8e7dbc2adab8cad405e2033ecc321c09137
3
+ metadata.gz: f9d6862ce564503738c10d66ea1b76000d57ffa7100a0e47bf0b96c8083e02dd
4
+ data.tar.gz: 44825a802755cd03c1efa129ec0a0349872f330795433839f2232ef2b9b83a24
5
5
  SHA512:
6
- metadata.gz: 04d5e9096e7cef9ea5d6c16e3397d5965bc8da07f699fc3b241e91ad982c755fe7b4faf4296b6ce74612da690cc7d7cfd507612387f43276b0e2ab0d05566ddf
7
- data.tar.gz: 224f32277392e5b84c84b6ef13a437813859f960e47dce696f97dd547273d0d86a3e62685a171a7055981989fd99679e60b843e12b839bc2b501c4e9fbb7e622
6
+ metadata.gz: ed6efaf98ea1b9e816d337ebf82d57516f3f2fb30877d693f2a18c42d24d85eaf981fa804c1f1761ec0bd86ec73e8a5f88fcb50103c5bd5979e46bf58a2c0162
7
+ data.tar.gz: 5d8d25591fdbc056dc0f793d5a8c93cae50547731e10128c6ec27e9432491f238d5e547f9cc74701beb85903a39114da045cd320cf1903f235afa7975bef42ca
@@ -1,6 +1,38 @@
1
1
  # RubySketch ChangeLog
2
2
 
3
3
 
4
+ ## [0.3.11] - 2020-12-9
5
+
6
+ - add size(), createCanvas() and pixelDensity()
7
+
8
+
9
+ ## [0.3.10] - 2020-12-1
10
+
11
+ - invert angle parameter value for arc() to fix compatibility to processing API
12
+
13
+
14
+ ## [0.3.9] - 2020-11-30
15
+
16
+ - Graphics#beginDraw() can take block to call endDraw automatically
17
+ - Capture#start() always returns nil
18
+ - add delay_camera.rb
19
+
20
+
21
+ ## [0.3.8] - 2020-11-27
22
+
23
+ - Capture#initialize() can take requestWidth, requestHeight and cameraName
24
+ - add Capture#width and Capture#height
25
+
26
+
27
+ ## [0.3.7] - 2020-11-18
28
+
29
+ - add Capture class
30
+ - add log(), exp(), sqrt() and PI
31
+ - add examples/camera.rb
32
+ - add examples/breakout.rb
33
+ - fix error on calling image()
34
+
35
+
4
36
  ## [0.3.6] - 2020-08-02
5
37
 
6
38
  - random() can take array or nothing
data/README.md CHANGED
@@ -1,3 +1,11 @@
1
- # RubySketch - Processing like Creative Coding Framework
1
+ # RubySketch - Processing compatible Creative Coding Framework
2
2
 
3
3
  by xordog@gmail.com
4
+
5
+
6
+ # How to release
7
+
8
+ ```
9
+ $ rake version:bump:patch message="..."
10
+ $ git push origin --tags
11
+ ```
data/Rakefile CHANGED
@@ -23,3 +23,28 @@ generate_documents
23
23
  build_ruby_gem
24
24
 
25
25
  task :default => :test
26
+
27
+
28
+ namespace :version do
29
+
30
+ namespace :bump do
31
+
32
+ task :major do
33
+ update_and_tag_version 0
34
+ end
35
+
36
+ task :minor do
37
+ update_and_tag_version 1
38
+ end
39
+
40
+ task :patch do
41
+ update_and_tag_version 2
42
+ end
43
+
44
+ task :build do
45
+ update_and_tag_version 3
46
+ end
47
+
48
+ end# bump
49
+
50
+ end# version
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.6
1
+ 0.3.11
@@ -0,0 +1,212 @@
1
+ %w[xot rays reflex rubysketch]
2
+ .map {|s| File.expand_path "../../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'rubysketch-processing'
6
+
7
+
8
+ PADDING = 50
9
+ BRICK_COUNT = 10
10
+
11
+ $objs = []
12
+ $bar = nil
13
+ $gameover = false
14
+
15
+ setup do
16
+ addWalls
17
+ addBricks
18
+
19
+ colorMode HSB, 360, 100, 100
20
+ ellipseMode CORNER
21
+ background 0
22
+ noStroke
23
+ fill 0, 0, 100
24
+ end
25
+
26
+ draw do
27
+ background 0
28
+ $objs.each do |o|
29
+ o.update
30
+ o.draw
31
+ end
32
+ drawTexts
33
+ end
34
+
35
+ mousePressed do
36
+ start unless started?
37
+ end
38
+
39
+ mouseDragged do
40
+ $bar.pos.x = mouseX - $bar.w / 2 if $bar
41
+ end
42
+
43
+ def start()
44
+ $bar = Bar.new
45
+ $objs += [$bar, Ball.new($bar)]
46
+ end
47
+
48
+ def started?()
49
+ $bar
50
+ end
51
+
52
+ def gameover?()
53
+ started? &&
54
+ $objs.count {|o| o.kind_of? Ball} == 0
55
+ end
56
+
57
+ def cleared?()
58
+ started? && !gameover? &&
59
+ $objs.count {|o| o.kind_of? Brick} == 0
60
+ end
61
+
62
+ def addWalls()
63
+ left = Obj.new 0, 0, 10, height
64
+ top = Obj.new 0, 0, width, 10
65
+ right = Obj.new width - 10, 0, 10, height
66
+ bottom = Bottom.new 0, height - 10, width, 10
67
+ $objs += [top, bottom, left, right]
68
+ end
69
+
70
+ def addBricks()
71
+ brickW = (width - PADDING * 2) / BRICK_COUNT
72
+ 5.times do |y|
73
+ BRICK_COUNT.times do |x|
74
+ xx = PADDING + brickW * x
75
+ yy = PADDING + 30 * y
76
+ $objs.push Brick.new(xx, yy, brickW - 5, 20, y * 60)
77
+ end
78
+ end
79
+ end
80
+
81
+ def drawTexts()
82
+ push do
83
+ textAlign CENTER, CENTER
84
+
85
+ if !started?
86
+ fill 50, 100, 100
87
+ textSize 50
88
+ text "BREAKOUT", 0, 0, width, height
89
+ textSize 20
90
+ translate 0, 100
91
+ text "Tap to start!", 0, 0, width, height
92
+ elsif cleared?
93
+ fill 100, 80, 100
94
+ textSize 50
95
+ text "CLEAR!", 0, 0, width, height
96
+ elsif gameover?
97
+ fill 0, 20, 100
98
+ textSize 50
99
+ text "GAMEOVER", 0, 0, width, height
100
+ end
101
+ end
102
+ end
103
+
104
+ class Obj
105
+ attr_reader :pos, :w, :h, :vel
106
+
107
+ def initialize(x, y, w, h, vx = 0, vy = 0)
108
+ @pos = createVector x, y
109
+ @w, @h = w, h
110
+ @vel = createVector vx, vy
111
+ end
112
+
113
+ def update()
114
+ @pos.add @vel
115
+ end
116
+
117
+ def draw()
118
+ rect @pos.x, @pos.y, @w, @h
119
+ end
120
+
121
+ def bounds()
122
+ x, y = @pos.x, @pos.y
123
+ return x, y, x + @w, y + @h
124
+ end
125
+
126
+ def center()
127
+ createVector @pos.x + @w / 2, @pos.y + @h / 2
128
+ end
129
+ end
130
+
131
+ class Ball < Obj
132
+ def initialize(bar)
133
+ super bar.pos.x, bar.pos.y - bar.h, 20, 20
134
+ self.vel = createVector random(-1, 1), -1
135
+ end
136
+
137
+ def vel=(v)
138
+ @vel = v.dup.normalize.mult 8
139
+ end
140
+
141
+ def update()
142
+ b = bounds.dup
143
+ super
144
+ checkHit b
145
+ end
146
+
147
+ def checkHit(prevBounds)
148
+ x1, y1, x2, y2 = prevBounds
149
+ hitH = hitV = false
150
+ hits = []
151
+ $objs.each do |o|
152
+ next if o == self
153
+ next unless intersect? o
154
+ hits.push o
155
+ ox1, oy1, ox2, oy2 = o.bounds
156
+ hitH ||= !overlap?(x1, x2, ox1, ox2)
157
+ hitV ||= !overlap?(y1, y2, oy1, oy2)
158
+ end
159
+ vel.x *= -1 if hitH
160
+ vel.y *= -1 if hitV
161
+
162
+ hits.each {|o| hit o}
163
+ end
164
+
165
+ def intersect?(o)
166
+ x1, y1, x2, y2 = bounds
167
+ ox1, oy1, ox2, oy2 = o.bounds
168
+ overlap?(x1, x2, ox1, ox2) && overlap?(y1, y2, oy1, oy2)
169
+ end
170
+
171
+ def overlap?(a1, a2, b1, b2)
172
+ a1 <= b2 && b1 <= a2
173
+ end
174
+
175
+ def hit(o)
176
+ case o
177
+ when Bar then self.vel = center.sub o.center
178
+ when Brick then $objs.delete o
179
+ when Bottom then $objs.delete self unless cleared?
180
+ end
181
+ end
182
+ end
183
+
184
+ class Bar < Obj
185
+ def initialize()
186
+ w = 100
187
+ super (width - w) / 2, height - 50, w, 20
188
+ end
189
+ end
190
+
191
+ class Brick < Obj
192
+ def initialize(x, y, w, h, hue)
193
+ super x, y, w, h
194
+ @hue = hue
195
+ end
196
+
197
+ def draw()
198
+ push do
199
+ fill @hue, 50, 100
200
+ super
201
+ end
202
+ end
203
+ end
204
+
205
+ class Bottom < Obj
206
+ def draw()
207
+ push do
208
+ fill 0, 0, 50
209
+ super
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,14 @@
1
+ %w[xot rays reflex rubysketch]
2
+ .map {|s| File.expand_path "../../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'rubysketch-processing'
6
+
7
+
8
+ cam = Capture.new 300, 300
9
+ cam.start
10
+
11
+ draw do
12
+ background 0
13
+ image cam, 0, 0
14
+ end
@@ -0,0 +1,33 @@
1
+ %w[xot rays reflex rubysketch]
2
+ .map {|s| File.expand_path "../../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'rubysketch-processing'
6
+
7
+
8
+ w, h = width, height
9
+
10
+ cam = Capture.new w, h, Capture.list.last
11
+ cam.start
12
+
13
+ images = 60.times.map {
14
+ Graphics.new w, h
15
+ }
16
+
17
+ draw do
18
+ if frameCount % 2 == 0
19
+ images.unshift images.pop
20
+ images.first.tap do |image|
21
+ image.beginDraw {
22
+ image.image cam, 0, 0
23
+ }
24
+ end
25
+ end
26
+
27
+ background 0
28
+ segment_h= h / images.size
29
+ images.each.with_index do |image, i|
30
+ y = i * segment_h
31
+ copy image, 0, y, w, segment_h, 0, y, w, segment_h
32
+ end
33
+ end
@@ -2,10 +2,18 @@ require 'rubysketch'
2
2
 
3
3
 
4
4
  begin
5
- include RubySketch::Processing::Context
5
+ window = RubySketch::Window.new {start}
6
+ context = RubySketch::Processing::Context.new window
6
7
 
7
- window = RubySketch::Window.new {start}
8
- setup__ window
8
+ (context.methods - Object.instance_methods).each do |method|
9
+ define_method method do |*args, &block|
10
+ context.__send__ method, *args, &block
11
+ end
12
+ end
13
+
14
+ context.class.constants.each do |const|
15
+ self.class.const_set const, context.class.const_get(const)
16
+ end
9
17
 
10
18
  window.__send__ :begin_draw
11
19
  at_exit do
@@ -141,9 +141,9 @@ module RubySketch
141
141
  #
142
142
  def lerp (*args, amount)
143
143
  v = toVector__ *args
144
- self.x = Context.lerp x, v.x, amount
145
- self.y = Context.lerp y, v.y, amount
146
- self.z = Context.lerp z, v.z, amount
144
+ self.x = x + (v.x - x) * amount
145
+ self.y = y + (v.y - y) * amount
146
+ self.z = z + (v.z - z) * amount
147
147
  self
148
148
  end
149
149
 
@@ -728,27 +728,127 @@ module RubySketch
728
728
  end# Touch
729
729
 
730
730
 
731
+ # Camera object.
732
+ #
733
+ class Capture
734
+
735
+ # Returns a list of available camera device names
736
+ #
737
+ # @return [Array] device name list
738
+ #
739
+ def self.list ()
740
+ Rays::Camera.device_names
741
+ end
742
+
743
+ # Initialize camera object.
744
+ #
745
+ # @overload Capture.new()
746
+ # @overload Capture.new(cameraName)
747
+ # @overload Capture.new(requestWidth, requestHeight)
748
+ # @overload Capture.new(requestWidth, requestHeight, cameraName)
749
+ #
750
+ # @param requestWidth [Integer] captured image width
751
+ # @param requestHeight [Integer] captured image height
752
+ # @param cameraName [String] camera device name
753
+ #
754
+ def initialize (*args)
755
+ width, height, name =
756
+ if args.empty?
757
+ [-1, -1, nil]
758
+ elsif args[0].kind_of?(String)
759
+ [-1, -1, args[0]]
760
+ elsif args[0].kind_of?(Numeric) && args[1].kind_of?(Numeric)
761
+ [args[0], args[1], args[2]]
762
+ else
763
+ raise ArgumentError
764
+ end
765
+ @camera = Rays::Camera.new width, height, device_name: name
766
+ end
767
+
768
+ # Start capturing.
769
+ #
770
+ # @return [nil] nil
771
+ #
772
+ def start ()
773
+ raise "Failed to start capture" unless @camera.start
774
+ nil
775
+ end
776
+
777
+ # Stop capturing.
778
+ #
779
+ # @return [nil] nil
780
+ #
781
+ def stop ()
782
+ @camera.stop
783
+ nil
784
+ end
785
+
786
+ # Returns is the next captured image available?
787
+ #
788
+ # @return [Boolean] true means object has next frame
789
+ #
790
+ def available ()
791
+ @camera.active?
792
+ end
793
+
794
+ # Reads next frame image
795
+ #
796
+ def read ()
797
+ @camera.image
798
+ end
799
+
800
+ # Returns the width of captured image
801
+ #
802
+ # @return [Numeric] the width of captured image
803
+ #
804
+ def width ()
805
+ @camera.image&.width || 0
806
+ end
807
+
808
+ # Returns the height of captured image
809
+ #
810
+ # @return [Numeric] the height of captured image
811
+ #
812
+ def height ()
813
+ @camera.image&.height || 0
814
+ end
815
+
816
+ # @private
817
+ def getInternal__ ()
818
+ @camera.image || dummyImage__
819
+ end
820
+
821
+ # @private
822
+ private def dummyImage__ ()
823
+ @dummy ||= Rays::Image.new 1, 1
824
+ end
825
+
826
+ end# Capture
827
+
828
+
731
829
  # Drawing context
732
830
  #
733
831
  module GraphicsContext
734
832
 
735
- Vector = Processing::Vector
833
+ # PI
834
+ #
835
+ PI = Math::PI
736
836
 
737
837
  # PI / 2
738
838
  #
739
- HALF_PI = Math::PI / 2
839
+ HALF_PI = PI / 2
740
840
 
741
841
  # PI / 4
742
842
  #
743
- QUARTER_PI = Math::PI / 4
843
+ QUARTER_PI = PI / 4
744
844
 
745
845
  # PI * 2
746
846
  #
747
- TWO_PI = Math::PI * 2
847
+ TWO_PI = PI * 2
748
848
 
749
849
  # PI * 2
750
850
  #
751
- TAU = Math::PI * 2
851
+ TAU = PI * 2
752
852
 
753
853
  # RGB mode for colorMode().
754
854
  #
@@ -813,11 +913,8 @@ module RubySketch
813
913
  #
814
914
  SQUARE = :square
815
915
 
816
- def setup__ (painter)
817
- @painter__ = painter
818
- @painter__.miter_limit = 10
819
-
820
- @drawing = false
916
+ def init__ (image, painter)
917
+ @drawing__ = false
821
918
  @hsbColor__ = false
822
919
  @colorMaxes__ = [1.0] * 4
823
920
  @angleScale__ = 1.0
@@ -829,6 +926,8 @@ module RubySketch
829
926
  @matrixStack__ = []
830
927
  @styleStack__ = []
831
928
 
929
+ updateCanvas__ image, painter
930
+
832
931
  colorMode RGB, 255
833
932
  angleMode RADIANS
834
933
  rectMode CORNER
@@ -840,14 +939,20 @@ module RubySketch
840
939
  stroke 0
841
940
  end
842
941
 
843
- def beginDraw ()
942
+ def updateCanvas__ (image, painter)
943
+ @image__, @painter__ = image, painter
944
+ end
945
+
946
+ # @private
947
+ def beginDraw__ ()
844
948
  @matrixStack__.clear
845
949
  @styleStack__.clear
846
- @drawing = true
950
+ @drawing__ = true
847
951
  end
848
952
 
849
- def endDraw ()
850
- @drawing = false
953
+ # @private
954
+ def endDraw__ ()
955
+ @drawing__ = false
851
956
  end
852
957
 
853
958
  def width ()
@@ -1267,8 +1372,8 @@ module RubySketch
1267
1372
  def arc (a, b, c, d, start, stop)
1268
1373
  assertDrawing__
1269
1374
  x, y, w, h = toXYWH__ @ellipseMode__, a, b, c, d
1270
- start = toAngle__ start
1271
- stop = toAngle__ stop
1375
+ start = toAngle__ -start
1376
+ stop = toAngle__ -stop
1272
1377
  @painter__.ellipse x, y, w, h, from: start, to: stop
1273
1378
  nil
1274
1379
  end
@@ -1411,8 +1516,9 @@ module RubySketch
1411
1516
  #
1412
1517
  def image (img, a, b, c = nil, d = nil)
1413
1518
  assertDrawing__
1414
- x, y, w, h = toXYWH__ @imageMode__, a, b, c || img.width, d || img.height
1415
- @painter__.image img.getInternal__, x, y, w, h
1519
+ i = img.getInternal__
1520
+ x, y, w, h = toXYWH__ @imageMode__, a, b, c || i.width, d || i.height
1521
+ @painter__.image i, x, y, w, h
1416
1522
  nil
1417
1523
  end
1418
1524
 
@@ -1588,13 +1694,13 @@ module RubySketch
1588
1694
  end
1589
1695
 
1590
1696
  # @private
1591
- private def getInternal__ ()
1697
+ def getInternal__ ()
1592
1698
  @image__
1593
1699
  end
1594
1700
 
1595
1701
  # @private
1596
1702
  private def assertDrawing__ ()
1597
- raise "call beginDraw() before drawing" unless @drawing
1703
+ raise "call beginDraw() before drawing" unless @drawing__
1598
1704
  end
1599
1705
 
1600
1706
  end# GraphicsContext
@@ -1606,20 +1712,30 @@ module RubySketch
1606
1712
 
1607
1713
  include GraphicsContext
1608
1714
 
1715
+ # Initialize graphics object.
1716
+ #
1609
1717
  def initialize (width, height)
1610
- @image__ = Rays::Image.new width, height
1611
- setup__ @image__.painter
1718
+ image = Rays::Image.new width, height
1719
+ init__ image, image.painter
1612
1720
  end
1613
1721
 
1614
- def beginDraw ()
1722
+ # Start drawing.
1723
+ #
1724
+ def beginDraw (&block)
1615
1725
  @painter__.__send__ :begin_paint
1616
- super
1726
+ beginDraw__
1617
1727
  push
1728
+ if block
1729
+ block.call
1730
+ endDraw
1731
+ end
1618
1732
  end
1619
1733
 
1734
+ # End drawing.
1735
+ #
1620
1736
  def endDraw ()
1621
1737
  pop
1622
- super
1738
+ endDraw__
1623
1739
  @painter__.__send__ :end_paint
1624
1740
  end
1625
1741
 
@@ -1628,38 +1744,42 @@ module RubySketch
1628
1744
 
1629
1745
  # Processing context
1630
1746
  #
1631
- module Context
1747
+ class Context
1748
+
1749
+ include GraphicsContext
1632
1750
 
1633
- include GraphicsContext, Math
1751
+ Vector = Processing::Vector
1752
+ Capture = Processing::Capture
1753
+ Graphics = Processing::Graphics
1634
1754
 
1755
+ # @private
1635
1756
  @@context__ = nil
1636
1757
 
1758
+ # @private
1637
1759
  def self.context__ ()
1638
1760
  @@context__
1639
1761
  end
1640
1762
 
1641
1763
  # @private
1642
- def setup__ (window)
1764
+ def initialize (window)
1643
1765
  @@context__ = self
1644
1766
 
1645
1767
  @window__ = window
1646
- @image__ = @window__.canvas
1647
- super @window__.canvas_painter.paint {background 0.8}
1768
+ init__ @window__.canvas, @window__.canvas_painter.paint {background 0.8}
1648
1769
 
1649
1770
  @loop__ = true
1650
1771
  @redraw__ = false
1651
1772
  @frameCount__ = 0
1652
1773
  @mousePos__ =
1653
- @mousePrevPos__ = Rays::Point.new 0
1774
+ @mousePrevPos__ = [0, 0]
1654
1775
  @mousePressed__ = false
1655
1776
  @touches__ = []
1656
1777
 
1657
- @window__.before_draw = proc {beginDraw}
1658
- @window__.after_draw = proc {endDraw}
1778
+ @window__.before_draw = proc {beginDraw__}
1779
+ @window__.after_draw = proc {endDraw__}
1659
1780
 
1660
1781
  drawFrame = -> {
1661
- @image__ = @window__.canvas
1662
- @painter__ = @window__.canvas_painter
1782
+ updateCanvas__ @window__.canvas, @window__.canvas_painter
1663
1783
  begin
1664
1784
  push
1665
1785
  @drawBlock__.call if @drawBlock__
@@ -1678,9 +1798,11 @@ module RubySketch
1678
1798
  end
1679
1799
 
1680
1800
  updatePointerStates = -> event, pressed = nil {
1681
- @mousePos__ = event.pos
1801
+ @mousePos__ = @window__.to_canvas_coord event.pos.x, event.pos.y
1682
1802
  @mousePressed__ = pressed if pressed != nil
1683
- @touches__ = event.positions.map {|pos| Touch.new pos.x, pos.y}
1803
+ @touches__ = event.positions.map {|pos|
1804
+ Touch.new *@window__.to_canvas_coord(pos.x, pos.y)
1805
+ }
1684
1806
  }
1685
1807
 
1686
1808
  @window__.pointer_down = proc do |e|
@@ -1758,15 +1880,59 @@ module RubySketch
1758
1880
  nil
1759
1881
  end
1760
1882
 
1883
+ # Changes canvas size.
1884
+ #
1885
+ # @param width [Integer] new width
1886
+ # @param height [Integer] new height
1887
+ #
1888
+ # @return [nil] nil
1889
+ #
1890
+ def size (width, height)
1891
+ resizeCanvas__ :size, width, height, pixelDensity
1892
+ nil
1893
+ end
1894
+
1895
+ # Changes canvas size.
1896
+ #
1897
+ # @param width [Integer] new width
1898
+ # @param height [Integer] new height
1899
+ #
1900
+ # @return [nil] nil
1901
+ #
1902
+ def createCanvas (width, height)
1903
+ resizeCanvas__ :createCanvas, width, height, pixelDensity
1904
+ nil
1905
+ end
1906
+
1907
+ # Changes and returns canvas pixel density.
1908
+ #
1909
+ # @param density [Numeric] new pixel density
1910
+ #
1911
+ # @return [Numeric] current pixel density
1912
+ #
1913
+ def pixelDensity (density = nil)
1914
+ resizeCanvas__ :pixelDensity, width, height, density if density
1915
+ @painter__.pixel_density
1916
+ end
1917
+
1761
1918
  # @private
1762
- private def size__ (width, height)
1763
- raise 'size() must be called on startup or setup block' if @started__
1919
+ def resizeCanvas__ (name, width, height, pixelDensity)
1920
+ raise '#{name}() must be called on startup or setup block' if @started__
1764
1921
 
1765
1922
  @painter__.__send__ :end_paint
1766
- @window__.__send__ :reset_canvas, width, height
1923
+ @window__.__send__ :resize_canvas, width, height, pixelDensity
1924
+ updateCanvas__ @window__.canvas, @window__.canvas_painter
1767
1925
  @painter__.__send__ :begin_paint
1768
1926
 
1769
- @auto_resize__ = false
1927
+ @window__.auto_resize = false
1928
+ end
1929
+
1930
+ # Returns pixel density of display.
1931
+ #
1932
+ # @return [Numeric] pixel density
1933
+ #
1934
+ def displayDensity ()
1935
+ @window__.painter.pixel_density
1770
1936
  end
1771
1937
 
1772
1938
  def windowWidth ()
@@ -1793,20 +1959,12 @@ module RubySketch
1793
1959
  @window__.event.fps
1794
1960
  end
1795
1961
 
1796
- # Returns pixel density
1797
- #
1798
- # @return [Numeric] pixel density
1799
- #
1800
- def displayDensity ()
1801
- @painter__.pixel_density
1802
- end
1803
-
1804
1962
  # Returns mouse x position
1805
1963
  #
1806
1964
  # @return [Numeric] horizontal position of mouse
1807
1965
  #
1808
1966
  def mouseX ()
1809
- @mousePos__.x
1967
+ @mousePos__[0]
1810
1968
  end
1811
1969
 
1812
1970
  # Returns mouse y position
@@ -1814,7 +1972,7 @@ module RubySketch
1814
1972
  # @return [Numeric] vertical position of mouse
1815
1973
  #
1816
1974
  def mouseY ()
1817
- @mousePos__.y
1975
+ @mousePos__[1]
1818
1976
  end
1819
1977
 
1820
1978
  # Returns mouse x position in previous frame
@@ -1822,7 +1980,7 @@ module RubySketch
1822
1980
  # @return [Numeric] horizontal position of mouse
1823
1981
  #
1824
1982
  def pmouseX ()
1825
- @mousePrevPos__.x
1983
+ @mousePrevPos__[0]
1826
1984
  end
1827
1985
 
1828
1986
  # Returns mouse y position in previous frame
@@ -1830,7 +1988,7 @@ module RubySketch
1830
1988
  # @return [Numeric] vertical position of mouse
1831
1989
  #
1832
1990
  def pmouseY ()
1833
- @mousePrevPos__.y
1991
+ @mousePrevPos__[1]
1834
1992
  end
1835
1993
 
1836
1994
  # Returns array of touches
@@ -1865,7 +2023,9 @@ module RubySketch
1865
2023
  @redraw__ = true
1866
2024
  end
1867
2025
 
1868
- module_function
2026
+ #
2027
+ # Utilities
2028
+ #
1869
2029
 
1870
2030
  # Returns the absolute number of the value.
1871
2031
  #
@@ -1907,6 +2067,26 @@ module RubySketch
1907
2067
  value.round
1908
2068
  end
1909
2069
 
2070
+ # Returns the natural logarithm (the base-e logarithm) of a number.
2071
+ #
2072
+ # @param value [Numeric] number (> 0.0)
2073
+ #
2074
+ # @return [Numeric] result number
2075
+ #
2076
+ def log (n)
2077
+ Math.log n
2078
+ end
2079
+
2080
+ # Returns Euler's number e raised to the power of value.
2081
+ #
2082
+ # @param value [Numeric] number
2083
+ #
2084
+ # @return [Numeric] result number
2085
+ #
2086
+ def exp (n)
2087
+ Math.exp n
2088
+ end
2089
+
1910
2090
  # Returns value raised to the power of exponent.
1911
2091
  #
1912
2092
  # @param value [Numeric] base number
@@ -1928,6 +2108,16 @@ module RubySketch
1928
2108
  value * value
1929
2109
  end
1930
2110
 
2111
+ # Returns squared value.
2112
+ #
2113
+ # @param value [Numeric] number
2114
+ #
2115
+ # @return [Numeric] squared value
2116
+ #
2117
+ def sqrt (value)
2118
+ Math.sqrt value
2119
+ end
2120
+
1931
2121
  # Returns the magnitude (or length) of a vector.
1932
2122
  #
1933
2123
  # @overload mag(x, y)
@@ -2202,6 +2392,14 @@ module RubySketch
2202
2392
  Vector.new *args
2203
2393
  end
2204
2394
 
2395
+ # Creates a camera object as a video input device.
2396
+ #
2397
+ # @return [Capture] camera object
2398
+ #
2399
+ def createCapture (*args)
2400
+ Capture.new *args
2401
+ end
2402
+
2205
2403
  # Creates a new off-screen graphics context object.
2206
2404
  #
2207
2405
  # @param width [Numeric] width of graphics image
@@ -16,7 +16,8 @@ module RubySketch
16
16
  @auto_resize = true
17
17
  @error = nil
18
18
 
19
- reset_canvas 1, 1
19
+ painter.miter_limit = 10
20
+ resize_canvas 1, 1
20
21
 
21
22
  super *args, size: [width, height], &block
22
23
  end
@@ -43,7 +44,9 @@ module RubySketch
43
44
 
44
45
  def on_draw (e)
45
46
  draw_canvas {call_block @draw, e} if @draw
46
- e.painter.image @canvas
47
+
48
+ x, y, w, h = coord_converter
49
+ e.painter.image @canvas, x, y, @canvas.width * w, @canvas.height * h
47
50
  end
48
51
 
49
52
  def on_key (e)
@@ -64,27 +67,45 @@ module RubySketch
64
67
  end
65
68
 
66
69
  def on_resize (e)
67
- reset_canvas e.width, e.height if @auto_resize
70
+ resize_canvas e.width, e.height if @auto_resize
68
71
  draw_canvas {call_block @resize, e} if @resize
69
72
  end
70
73
 
74
+ def to_canvas_coord (x, y)
75
+ xx, yy, ww, hh = coord_converter
76
+ return (x - xx) / ww, (y - yy) / hh
77
+ end
78
+
71
79
  private
72
80
 
73
- def reset_canvas (width, height)
74
- return if width * height == 0
75
- return if width == @canvas&.width && height == @canvas&.height
81
+ def resize_canvas (width, height, pixel_density = nil)
82
+ return nil if width * height == 0
76
83
 
77
- old_canvas = @canvas
78
- old_painter = @canvas_painter
84
+ unless width == @canvas&.width &&
85
+ height == @canvas&.height &&
86
+ pixel_density == @canvas_painter&.pixel_density
79
87
 
80
- cs = old_canvas&.color_space || Rays::RGBA
81
- @canvas = Rays::Image.new width, height, cs, painter.pixel_density
82
- @canvas_painter = @canvas.painter
88
+ old_canvas = @canvas
89
+ old_painter = @canvas_painter
83
90
 
84
- if old_canvas
85
- @canvas_painter.paint {image old_canvas}
86
- copy_painter_attributes old_painter, @canvas_painter
91
+ cs = old_canvas&.color_space || Rays::RGBA
92
+ pd = pixel_density || painter.pixel_density
93
+ @canvas = Rays::Image.new width, height, cs, pd
94
+ @canvas_painter = @canvas.painter
95
+
96
+ if old_canvas
97
+ @canvas_painter.paint {image old_canvas}
98
+ copy_painter_attributes old_painter, @canvas_painter
99
+ end
100
+
101
+ resize_window width, height
87
102
  end
103
+
104
+ @canvas_painter
105
+ end
106
+
107
+ def resize_window (width, height)
108
+ size width, height
88
109
  end
89
110
 
90
111
  def copy_painter_attributes (from, to)
@@ -97,6 +118,21 @@ module RubySketch
97
118
  to.font = from.font
98
119
  end
99
120
 
121
+ def coord_converter ()
122
+ ww, wh = width.to_f, height.to_f
123
+ cw, ch = @canvas.width.to_f, @canvas.height.to_f
124
+ return [0, 0, 1, 1] if ww == 0 || wh == 0 || cw == 0 || ch == 0
125
+
126
+ wratio, cratio = ww / wh, cw / ch
127
+ if wratio >= cratio
128
+ scaled_w = wh * cratio
129
+ return (ww - scaled_w) / 2, 0, scaled_w / cw, wh / ch
130
+ else
131
+ scaled_h = ww / cratio
132
+ return 0, (wh - scaled_h) / 2, ww / cw, scaled_h / ch
133
+ end
134
+ end
135
+
100
136
  def draw_canvas (&block)
101
137
  begin_draw
102
138
  block.call
@@ -12,11 +12,6 @@ require 'rubysketch'
12
12
  include Xot::Test
13
13
 
14
14
 
15
- unless $RAYS_NOAUTOINIT
16
- #def Rays.fin! () end
17
- end
18
-
19
-
20
15
  def assert_equal_vector (v1, v2, delta = 0.000001)
21
16
  assert_in_delta v1.x, v2.x, delta
22
17
  assert_in_delta v1.y, v2.y, delta
@@ -6,27 +6,31 @@ require_relative '../helper'
6
6
 
7
7
  class TestProcessingUtility < Test::Unit::TestCase
8
8
 
9
- C = RubySketch::Processing::Context
9
+ class Context
10
+ include RubySketch::Processing::Context
11
+ end
10
12
 
11
- def setup ()
12
-
13
+ def context
14
+ Context.new
13
15
  end
14
16
 
15
17
  def test_random ()
16
- assert_equal Float, C.random(1).class
17
- assert_equal Float, C.random(1.0).class
18
- assert_equal Symbol, C.random((:a..:z).to_a).class
18
+ c = context
19
+
20
+ assert_equal Float, c.random(1).class
21
+ assert_equal Float, c.random(1.0).class
22
+ assert_equal Symbol, c.random((:a..:z).to_a).class
19
23
 
20
- assert_not_equal C.random, C.random
24
+ assert_not_equal c.random, c.random
21
25
 
22
26
  10000.times do
23
- n = C.random
27
+ n = c.random
24
28
  assert 0 <= n && n < 1
25
29
 
26
- n = C.random 1
30
+ n = c.random 1
27
31
  assert 0 <= n && n < 1
28
32
 
29
- n = C.random 1, 2
33
+ n = c.random 1, 2
30
34
  assert 1.0 <= n && n < 2.0
31
35
  end
32
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysketch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-05 00:00:00.000000000 Z
11
+ date: 2020-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: reflexion
@@ -40,7 +40,10 @@ files:
40
40
  - README.md
41
41
  - Rakefile
42
42
  - VERSION
43
+ - examples/breakout.rb
44
+ - examples/camera.rb
43
45
  - examples/clock.rb
46
+ - examples/delay_camera.rb
44
47
  - examples/glsl.rb
45
48
  - examples/hello.rb
46
49
  - examples/image.rb