rubysketch 0.3.3 → 0.3.8
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/.github/workflows/release.yml +62 -0
- data/.github/workflows/test.yml +27 -0
- data/ChangeLog.md +34 -0
- data/Gemfile +4 -0
- data/VERSION +1 -1
- data/examples/breakout.rb +212 -0
- data/examples/camera.rb +14 -0
- data/lib/rubysketch-processing.rb +11 -3
- data/lib/rubysketch/processing.rb +558 -286
- data/rubysketch.gemspec +0 -8
- data/test/helper.rb +24 -0
- data/test/processing/test_utility.rb +38 -0
- data/test/processing/test_vector.rb +139 -137
- metadata +15 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5824abb04b555aa085934c3eefb32dc0cf5a79c6bc48945d5706a260c46269d
|
4
|
+
data.tar.gz: 35d88e63413027b4c8c574b860c2dd9e443cb29f140e9820ec73bacaaf800f05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34eaeef4a6992cfa326e16bd58b07e27b4757876129d03d246b717d334620d87d6a412f61757545bd4db561f83f38d8dd9303d255276ae0a544a4731759d853c
|
7
|
+
data.tar.gz: f0f4d8498f19da6a602cb4b120e91cdaebb718e66d4980433cb2386e0ed45e47aeefd25adb2c03974a93fefe2f862783325cd8c1cf923174f8467825172d647b
|
@@ -0,0 +1,62 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags: ['v[0-9]*']
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
release:
|
9
|
+
runs-on: macos-latest
|
10
|
+
|
11
|
+
steps:
|
12
|
+
- name: checkout
|
13
|
+
uses: actions/checkout@v2
|
14
|
+
|
15
|
+
- name: ruby 2.6
|
16
|
+
uses: actions/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
ruby-version: 2.6.x
|
19
|
+
|
20
|
+
- name: install gems
|
21
|
+
run: |
|
22
|
+
gem install bundler
|
23
|
+
bundle install --jobs 4 --retry 3
|
24
|
+
|
25
|
+
- name: version
|
26
|
+
id: version
|
27
|
+
run: |
|
28
|
+
echo ::set-output name=value::$(ruby -e 'print "${{ github.ref }}"[/\/v([\w\.\-]+)/, 1]')
|
29
|
+
|
30
|
+
- name: create gem
|
31
|
+
run: rake clean gem
|
32
|
+
|
33
|
+
- name: create release
|
34
|
+
id: create_release
|
35
|
+
uses: actions/create-release@v1
|
36
|
+
env:
|
37
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
38
|
+
with:
|
39
|
+
tag_name: ${{ github.ref }}
|
40
|
+
release_name: ${{ github.ref }}
|
41
|
+
draft: false
|
42
|
+
prerelease: false
|
43
|
+
|
44
|
+
- name: upload to releases
|
45
|
+
uses: actions/upload-release-asset@v1
|
46
|
+
env:
|
47
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
48
|
+
with:
|
49
|
+
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
50
|
+
asset_path: ./rubysketch-${{ steps.version.outputs.value }}.gem
|
51
|
+
asset_name: rubysketch-${{ steps.version.outputs.value }}.gem
|
52
|
+
asset_content_type: application/zip
|
53
|
+
|
54
|
+
- name: upload to rubygems
|
55
|
+
env:
|
56
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
|
57
|
+
run: |
|
58
|
+
mkdir -p $HOME/.gem
|
59
|
+
touch $HOME/.gem/credentials
|
60
|
+
chmod 0600 $HOME/.gem/credentials
|
61
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
62
|
+
rake upload
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
pull_request:
|
7
|
+
branches: [master]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: macos-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
|
16
|
+
- name: ruby 2.6
|
17
|
+
uses: actions/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 2.6.x
|
20
|
+
|
21
|
+
- name: install gems
|
22
|
+
run: |
|
23
|
+
gem install bundler
|
24
|
+
bundle install --jobs 4 --retry 3
|
25
|
+
|
26
|
+
- name: test
|
27
|
+
run: rake test
|
data/ChangeLog.md
CHANGED
@@ -1,6 +1,40 @@
|
|
1
1
|
# RubySketch ChangeLog
|
2
2
|
|
3
3
|
|
4
|
+
## [0.3.8] - 2020-11-27
|
5
|
+
|
6
|
+
- Capture#initialize() can take requestWidth, requestHeight and cameraName
|
7
|
+
- add Capture#width and Capture#height
|
8
|
+
|
9
|
+
|
10
|
+
## [0.3.7] - 2020-11-18
|
11
|
+
|
12
|
+
- add Capture class
|
13
|
+
- add log(), exp(), sqrt() and PI
|
14
|
+
- add examples/camera.rb
|
15
|
+
- add examples/breakout.rb
|
16
|
+
- fix error on calling image()
|
17
|
+
|
18
|
+
|
19
|
+
## [0.3.6] - 2020-08-02
|
20
|
+
|
21
|
+
- random() can take array or nothing
|
22
|
+
- use github actions to release gem package
|
23
|
+
|
24
|
+
|
25
|
+
## [0.3.5] - 2020-08-02
|
26
|
+
|
27
|
+
- add random()
|
28
|
+
- add sin(), cos(), tan(), asin(), acos(), atan() and atan2()
|
29
|
+
- make Vector class accessible from user script context
|
30
|
+
- fix error on calling rotate()
|
31
|
+
|
32
|
+
|
33
|
+
## [0.3.4] - 2020-08-02
|
34
|
+
|
35
|
+
- delete Utility module
|
36
|
+
|
37
|
+
|
4
38
|
## [0.3.3] - 2020-08-01
|
5
39
|
|
6
40
|
- add Vector class
|
data/Gemfile
ADDED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.8
|
@@ -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
|
data/examples/camera.rb
ADDED
@@ -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, 200, Capture.list.last
|
9
|
+
cam.start
|
10
|
+
|
11
|
+
draw do
|
12
|
+
background 0
|
13
|
+
image cam, 0, 0
|
14
|
+
end
|
@@ -2,10 +2,18 @@ require 'rubysketch'
|
|
2
2
|
|
3
3
|
|
4
4
|
begin
|
5
|
-
|
5
|
+
window = RubySketch::Window.new {start}
|
6
|
+
context = RubySketch::Processing::Context.new window
|
6
7
|
|
7
|
-
|
8
|
-
|
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
|
@@ -6,6 +6,13 @@ module RubySketch
|
|
6
6
|
module Processing
|
7
7
|
|
8
8
|
|
9
|
+
# @private
|
10
|
+
DEG2RAD__ = Math::PI / 180.0
|
11
|
+
|
12
|
+
# @private
|
13
|
+
RAD2DEG__ = 180.0 / Math::PI
|
14
|
+
|
15
|
+
|
9
16
|
# Vector class.
|
10
17
|
#
|
11
18
|
class Vector
|
@@ -27,14 +34,14 @@ module RubySketch
|
|
27
34
|
# @param v [Vector] vector object to copy
|
28
35
|
# @param a [Array] array like [x, y, z]
|
29
36
|
#
|
30
|
-
def initialize (x = 0, y = 0, z = 0, context:
|
37
|
+
def initialize (x = 0, y = 0, z = 0, context: nil)
|
31
38
|
@point = case x
|
32
39
|
when Rays::Point then x.dup
|
33
40
|
when Vector then x.getInternal__.dup
|
34
41
|
when Array then Rays::Point.new x[0] || 0, x[1] || 0, x[2] || 0
|
35
42
|
else Rays::Point.new x || 0, y || 0, z || 0
|
36
43
|
end
|
37
|
-
@context = context
|
44
|
+
@context = context || Context.context__
|
38
45
|
end
|
39
46
|
|
40
47
|
# Initializer for dup or clone
|
@@ -464,7 +471,7 @@ module RubySketch
|
|
464
471
|
# @return [Vector] rotated this object
|
465
472
|
#
|
466
473
|
def rotate (angle)
|
467
|
-
angle = @context ? @context.toAngle__(angle) : angle *
|
474
|
+
angle = @context ? @context.toAngle__(angle) : angle * RAD2DEG__
|
468
475
|
@point.rotate! angle
|
469
476
|
self
|
470
477
|
end
|
@@ -721,25 +728,127 @@ module RubySketch
|
|
721
728
|
end# Touch
|
722
729
|
|
723
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 [Capture] self
|
771
|
+
#
|
772
|
+
def start ()
|
773
|
+
raise "Failed to start capture" unless @camera.start
|
774
|
+
self
|
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
|
+
|
724
829
|
# Drawing context
|
725
830
|
#
|
726
831
|
module GraphicsContext
|
727
832
|
|
833
|
+
# PI
|
834
|
+
#
|
835
|
+
PI = Math::PI
|
836
|
+
|
728
837
|
# PI / 2
|
729
838
|
#
|
730
|
-
HALF_PI =
|
839
|
+
HALF_PI = PI / 2
|
731
840
|
|
732
841
|
# PI / 4
|
733
842
|
#
|
734
|
-
QUARTER_PI =
|
843
|
+
QUARTER_PI = PI / 4
|
735
844
|
|
736
845
|
# PI * 2
|
737
846
|
#
|
738
|
-
TWO_PI =
|
847
|
+
TWO_PI = PI * 2
|
739
848
|
|
740
849
|
# PI * 2
|
741
850
|
#
|
742
|
-
TAU =
|
851
|
+
TAU = PI * 2
|
743
852
|
|
744
853
|
# RGB mode for colorMode().
|
745
854
|
#
|
@@ -808,7 +917,7 @@ module RubySketch
|
|
808
917
|
@painter__ = painter
|
809
918
|
@painter__.miter_limit = 10
|
810
919
|
|
811
|
-
@
|
920
|
+
@drawing__ = false
|
812
921
|
@hsbColor__ = false
|
813
922
|
@colorMaxes__ = [1.0] * 4
|
814
923
|
@angleScale__ = 1.0
|
@@ -834,11 +943,11 @@ module RubySketch
|
|
834
943
|
def beginDraw ()
|
835
944
|
@matrixStack__.clear
|
836
945
|
@styleStack__.clear
|
837
|
-
@
|
946
|
+
@drawing__ = true
|
838
947
|
end
|
839
948
|
|
840
949
|
def endDraw ()
|
841
|
-
@
|
950
|
+
@drawing__ = false
|
842
951
|
end
|
843
952
|
|
844
953
|
def width ()
|
@@ -915,7 +1024,7 @@ module RubySketch
|
|
915
1024
|
#
|
916
1025
|
def angleMode (mode)
|
917
1026
|
@angleScale__ = case mode.upcase.to_sym
|
918
|
-
when RADIANS then
|
1027
|
+
when RADIANS then RAD2DEG__
|
919
1028
|
when DEGREES then 1.0
|
920
1029
|
else raise ArgumentError, "invalid angle mode: #{mode}"
|
921
1030
|
end
|
@@ -923,7 +1032,7 @@ module RubySketch
|
|
923
1032
|
end
|
924
1033
|
|
925
1034
|
# @private
|
926
|
-
|
1035
|
+
def toAngle__ (angle)
|
927
1036
|
angle * @angleScale__
|
928
1037
|
end
|
929
1038
|
|
@@ -1402,8 +1511,9 @@ module RubySketch
|
|
1402
1511
|
#
|
1403
1512
|
def image (img, a, b, c = nil, d = nil)
|
1404
1513
|
assertDrawing__
|
1405
|
-
|
1406
|
-
|
1514
|
+
i = img.getInternal__
|
1515
|
+
x, y, w, h = toXYWH__ @imageMode__, a, b, c || i.width, d || i.height
|
1516
|
+
@painter__.image i, x, y, w, h
|
1407
1517
|
nil
|
1408
1518
|
end
|
1409
1519
|
|
@@ -1579,13 +1689,13 @@ module RubySketch
|
|
1579
1689
|
end
|
1580
1690
|
|
1581
1691
|
# @private
|
1582
|
-
|
1692
|
+
def getInternal__ ()
|
1583
1693
|
@image__
|
1584
1694
|
end
|
1585
1695
|
|
1586
1696
|
# @private
|
1587
1697
|
private def assertDrawing__ ()
|
1588
|
-
raise "call beginDraw() before drawing" unless @
|
1698
|
+
raise "call beginDraw() before drawing" unless @drawing__
|
1589
1699
|
end
|
1590
1700
|
|
1591
1701
|
end# GraphicsContext
|
@@ -1597,17 +1707,23 @@ module RubySketch
|
|
1597
1707
|
|
1598
1708
|
include GraphicsContext
|
1599
1709
|
|
1710
|
+
# Initialize graphics object.
|
1711
|
+
#
|
1600
1712
|
def initialize (width, height)
|
1601
1713
|
@image__ = Rays::Image.new width, height
|
1602
1714
|
setup__ @image__.painter
|
1603
1715
|
end
|
1604
1716
|
|
1717
|
+
# Start drawing.
|
1718
|
+
#
|
1605
1719
|
def beginDraw ()
|
1606
1720
|
@painter__.__send__ :begin_paint
|
1607
1721
|
super
|
1608
1722
|
push
|
1609
1723
|
end
|
1610
1724
|
|
1725
|
+
# End drawing.
|
1726
|
+
#
|
1611
1727
|
def endDraw ()
|
1612
1728
|
pop
|
1613
1729
|
super
|
@@ -1617,77 +1733,316 @@ module RubySketch
|
|
1617
1733
|
end# Graphics
|
1618
1734
|
|
1619
1735
|
|
1620
|
-
|
1736
|
+
# Processing context
|
1737
|
+
#
|
1738
|
+
class Context
|
1739
|
+
|
1740
|
+
include GraphicsContext
|
1621
1741
|
|
1622
|
-
|
1623
|
-
|
1742
|
+
Vector = Processing::Vector
|
1743
|
+
Capture = Processing::Capture
|
1744
|
+
Graphics = Processing::Graphics
|
1745
|
+
|
1746
|
+
@@context__ = nil
|
1747
|
+
|
1748
|
+
def self.context__ ()
|
1749
|
+
@@context__
|
1750
|
+
end
|
1624
1751
|
|
1625
1752
|
# @private
|
1626
|
-
|
1753
|
+
def initialize (window)
|
1754
|
+
@@context__ = self
|
1627
1755
|
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1756
|
+
@window__ = window
|
1757
|
+
@image__ = @window__.canvas
|
1758
|
+
setup__ @window__.canvas_painter.paint {background 0.8}
|
1759
|
+
|
1760
|
+
@loop__ = true
|
1761
|
+
@redraw__ = false
|
1762
|
+
@frameCount__ = 0
|
1763
|
+
@mousePos__ =
|
1764
|
+
@mousePrevPos__ = Rays::Point.new 0
|
1765
|
+
@mousePressed__ = false
|
1766
|
+
@touches__ = []
|
1767
|
+
|
1768
|
+
@window__.before_draw = proc {beginDraw}
|
1769
|
+
@window__.after_draw = proc {endDraw}
|
1770
|
+
|
1771
|
+
drawFrame = -> {
|
1772
|
+
@image__ = @window__.canvas
|
1773
|
+
@painter__ = @window__.canvas_painter
|
1774
|
+
begin
|
1775
|
+
push
|
1776
|
+
@drawBlock__.call if @drawBlock__
|
1777
|
+
ensure
|
1778
|
+
pop
|
1779
|
+
@frameCount__ += 1
|
1780
|
+
end
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
@window__.draw = proc do |e|
|
1784
|
+
if @loop__ || @redraw__
|
1785
|
+
@redraw__ = false
|
1786
|
+
drawFrame.call
|
1787
|
+
end
|
1788
|
+
@mousePrevPos__ = @mousePos__
|
1789
|
+
end
|
1790
|
+
|
1791
|
+
updatePointerStates = -> event, pressed = nil {
|
1792
|
+
@mousePos__ = event.pos
|
1793
|
+
@mousePressed__ = pressed if pressed != nil
|
1794
|
+
@touches__ = event.positions.map {|pos| Touch.new pos.x, pos.y}
|
1795
|
+
}
|
1796
|
+
|
1797
|
+
@window__.pointer_down = proc do |e|
|
1798
|
+
updatePointerStates.call e, true
|
1799
|
+
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
@window__.pointer_up = proc do |e|
|
1803
|
+
updatePointerStates.call e, false
|
1804
|
+
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
@window__.pointer_move = proc do |e|
|
1808
|
+
updatePointerStates.call e
|
1809
|
+
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
1810
|
+
end
|
1811
|
+
|
1812
|
+
@window__.pointer_drag = proc do |e|
|
1813
|
+
updatePointerStates.call e
|
1814
|
+
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
1815
|
+
end
|
1816
|
+
end
|
1817
|
+
|
1818
|
+
# Define setup block.
|
1633
1819
|
#
|
1634
|
-
def
|
1635
|
-
|
1820
|
+
def setup (&block)
|
1821
|
+
@window__.setup = block
|
1822
|
+
nil
|
1636
1823
|
end
|
1637
1824
|
|
1638
|
-
#
|
1825
|
+
# Define draw block.
|
1639
1826
|
#
|
1640
|
-
|
1827
|
+
def draw (&block)
|
1828
|
+
@drawBlock__ = block if block
|
1829
|
+
nil
|
1830
|
+
end
|
1831
|
+
|
1832
|
+
def key (&block)
|
1833
|
+
@window__.key = block
|
1834
|
+
nil
|
1835
|
+
end
|
1836
|
+
|
1837
|
+
def mousePressed (&block)
|
1838
|
+
@mousePressedBlock__ = block if block
|
1839
|
+
@mousePressed__
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
def mouseReleased (&block)
|
1843
|
+
@mouseReleasedBlock__ = block if block
|
1844
|
+
nil
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
def mouseMoved (&block)
|
1848
|
+
@mouseMovedBlock__ = block if block
|
1849
|
+
nil
|
1850
|
+
end
|
1851
|
+
|
1852
|
+
def mouseDragged (&block)
|
1853
|
+
@mouseDraggedBlock__ = block if block
|
1854
|
+
nil
|
1855
|
+
end
|
1856
|
+
|
1857
|
+
def touchStarted (&block)
|
1858
|
+
@touchStartedBlock__ = block if block
|
1859
|
+
nil
|
1860
|
+
end
|
1861
|
+
|
1862
|
+
def touchEnded (&block)
|
1863
|
+
@touchEndedBlock__ = block if block
|
1864
|
+
nil
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
def touchMoved (&block)
|
1868
|
+
@touchMovedBlock__ = block if block
|
1869
|
+
nil
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
# @private
|
1873
|
+
private def size__ (width, height)
|
1874
|
+
raise 'size() must be called on startup or setup block' if @started__
|
1875
|
+
|
1876
|
+
@painter__.__send__ :end_paint
|
1877
|
+
@window__.__send__ :reset_canvas, width, height
|
1878
|
+
@painter__.__send__ :begin_paint
|
1879
|
+
|
1880
|
+
@auto_resize__ = false
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
def windowWidth ()
|
1884
|
+
@window__.width
|
1885
|
+
end
|
1886
|
+
|
1887
|
+
def windowHeight ()
|
1888
|
+
@window__.height
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
# Returns number of frames since program started.
|
1641
1892
|
#
|
1642
|
-
# @return [
|
1893
|
+
# @return [Integer] total number of frames
|
1643
1894
|
#
|
1644
|
-
def
|
1645
|
-
|
1895
|
+
def frameCount ()
|
1896
|
+
@frameCount__
|
1646
1897
|
end
|
1647
1898
|
|
1648
|
-
# Returns
|
1649
|
-
#
|
1650
|
-
# @param value [Numeric] number
|
1899
|
+
# Returns number of frames per second.
|
1651
1900
|
#
|
1652
|
-
# @return [
|
1901
|
+
# @return [Float] frames per second
|
1653
1902
|
#
|
1654
|
-
def
|
1655
|
-
|
1903
|
+
def frameRate ()
|
1904
|
+
@window__.event.fps
|
1656
1905
|
end
|
1657
1906
|
|
1658
|
-
# Returns
|
1659
|
-
#
|
1660
|
-
# @param value [Numeric] number
|
1907
|
+
# Returns pixel density
|
1661
1908
|
#
|
1662
|
-
# @return [Numeric]
|
1909
|
+
# @return [Numeric] pixel density
|
1663
1910
|
#
|
1664
|
-
def
|
1665
|
-
|
1911
|
+
def displayDensity ()
|
1912
|
+
@painter__.pixel_density
|
1666
1913
|
end
|
1667
1914
|
|
1668
|
-
# Returns
|
1669
|
-
#
|
1670
|
-
# @param value [Numeric] number
|
1915
|
+
# Returns mouse x position
|
1671
1916
|
#
|
1672
|
-
# @return [Numeric]
|
1917
|
+
# @return [Numeric] horizontal position of mouse
|
1673
1918
|
#
|
1674
|
-
def
|
1675
|
-
|
1919
|
+
def mouseX ()
|
1920
|
+
@mousePos__.x
|
1676
1921
|
end
|
1677
1922
|
|
1678
|
-
# Returns
|
1679
|
-
#
|
1680
|
-
# @param value [Numeric] number
|
1923
|
+
# Returns mouse y position
|
1681
1924
|
#
|
1682
|
-
# @return [Numeric]
|
1925
|
+
# @return [Numeric] vertical position of mouse
|
1683
1926
|
#
|
1684
|
-
def
|
1685
|
-
|
1927
|
+
def mouseY ()
|
1928
|
+
@mousePos__.y
|
1686
1929
|
end
|
1687
1930
|
|
1688
|
-
# Returns
|
1931
|
+
# Returns mouse x position in previous frame
|
1689
1932
|
#
|
1690
|
-
# @
|
1933
|
+
# @return [Numeric] horizontal position of mouse
|
1934
|
+
#
|
1935
|
+
def pmouseX ()
|
1936
|
+
@mousePrevPos__.x
|
1937
|
+
end
|
1938
|
+
|
1939
|
+
# Returns mouse y position in previous frame
|
1940
|
+
#
|
1941
|
+
# @return [Numeric] vertical position of mouse
|
1942
|
+
#
|
1943
|
+
def pmouseY ()
|
1944
|
+
@mousePrevPos__.y
|
1945
|
+
end
|
1946
|
+
|
1947
|
+
# Returns array of touches
|
1948
|
+
#
|
1949
|
+
# @return [Array] Touch objects
|
1950
|
+
#
|
1951
|
+
def touches ()
|
1952
|
+
@touches__
|
1953
|
+
end
|
1954
|
+
|
1955
|
+
# Enables calling draw block on every frame.
|
1956
|
+
#
|
1957
|
+
# @return [nil] nil
|
1958
|
+
#
|
1959
|
+
def loop ()
|
1960
|
+
@loop__ = true
|
1961
|
+
end
|
1962
|
+
|
1963
|
+
# Disables calling draw block on every frame.
|
1964
|
+
#
|
1965
|
+
# @return [nil] nil
|
1966
|
+
#
|
1967
|
+
def noLoop ()
|
1968
|
+
@loop__ = false
|
1969
|
+
end
|
1970
|
+
|
1971
|
+
# Calls draw block to redraw frame.
|
1972
|
+
#
|
1973
|
+
# @return [nil] nil
|
1974
|
+
#
|
1975
|
+
def redraw ()
|
1976
|
+
@redraw__ = true
|
1977
|
+
end
|
1978
|
+
|
1979
|
+
#
|
1980
|
+
# Utilities
|
1981
|
+
#
|
1982
|
+
|
1983
|
+
# Returns the absolute number of the value.
|
1984
|
+
#
|
1985
|
+
# @param value [Numeric] number
|
1986
|
+
#
|
1987
|
+
# @return [Numeric] absolute number
|
1988
|
+
#
|
1989
|
+
def abs (value)
|
1990
|
+
value.abs
|
1991
|
+
end
|
1992
|
+
|
1993
|
+
# Returns the closest integer number greater than or equal to the value.
|
1994
|
+
#
|
1995
|
+
# @param value [Numeric] number
|
1996
|
+
#
|
1997
|
+
# @return [Numeric] rounded up number
|
1998
|
+
#
|
1999
|
+
def ceil (value)
|
2000
|
+
value.ceil
|
2001
|
+
end
|
2002
|
+
|
2003
|
+
# Returns the closest integer number less than or equal to the value.
|
2004
|
+
#
|
2005
|
+
# @param value [Numeric] number
|
2006
|
+
#
|
2007
|
+
# @return [Numeric] rounded down number
|
2008
|
+
#
|
2009
|
+
def floor (value)
|
2010
|
+
value.floor
|
2011
|
+
end
|
2012
|
+
|
2013
|
+
# Returns the closest integer number.
|
2014
|
+
#
|
2015
|
+
# @param value [Numeric] number
|
2016
|
+
#
|
2017
|
+
# @return [Numeric] rounded number
|
2018
|
+
#
|
2019
|
+
def round (value)
|
2020
|
+
value.round
|
2021
|
+
end
|
2022
|
+
|
2023
|
+
# Returns the natural logarithm (the base-e logarithm) of a number.
|
2024
|
+
#
|
2025
|
+
# @param value [Numeric] number (> 0.0)
|
2026
|
+
#
|
2027
|
+
# @return [Numeric] result number
|
2028
|
+
#
|
2029
|
+
def log (n)
|
2030
|
+
Math.log n
|
2031
|
+
end
|
2032
|
+
|
2033
|
+
# Returns Euler's number e raised to the power of value.
|
2034
|
+
#
|
2035
|
+
# @param value [Numeric] number
|
2036
|
+
#
|
2037
|
+
# @return [Numeric] result number
|
2038
|
+
#
|
2039
|
+
def exp (n)
|
2040
|
+
Math.exp n
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
# Returns value raised to the power of exponent.
|
2044
|
+
#
|
2045
|
+
# @param value [Numeric] base number
|
1691
2046
|
# @param exponent [Numeric] exponent number
|
1692
2047
|
#
|
1693
2048
|
# @return [Numeric] value ** exponent
|
@@ -1706,6 +2061,16 @@ module RubySketch
|
|
1706
2061
|
value * value
|
1707
2062
|
end
|
1708
2063
|
|
2064
|
+
# Returns squared value.
|
2065
|
+
#
|
2066
|
+
# @param value [Numeric] number
|
2067
|
+
#
|
2068
|
+
# @return [Numeric] squared value
|
2069
|
+
#
|
2070
|
+
def sqrt (value)
|
2071
|
+
Math.sqrt value
|
2072
|
+
end
|
2073
|
+
|
1709
2074
|
# Returns the magnitude (or length) of a vector.
|
1710
2075
|
#
|
1711
2076
|
# @overload mag(x, y)
|
@@ -1838,292 +2203,199 @@ module RubySketch
|
|
1838
2203
|
value < min ? min : (value > max ? max : value)
|
1839
2204
|
end
|
1840
2205
|
|
1841
|
-
#
|
1842
|
-
#
|
1843
|
-
# @overload noise(x)
|
1844
|
-
# @overload noise(x, y)
|
1845
|
-
# @overload noise(x, y, z)
|
2206
|
+
# Converts degree to radian.
|
1846
2207
|
#
|
1847
|
-
# @param
|
1848
|
-
# @param y [Numeric] vertical point in noise space
|
1849
|
-
# @param z [Numeric] depth point in noise space
|
2208
|
+
# @param degree [Numeric] degree to convert
|
1850
2209
|
#
|
1851
|
-
# @return [Numeric]
|
2210
|
+
# @return [Numeric] radian
|
1852
2211
|
#
|
1853
|
-
def
|
1854
|
-
|
2212
|
+
def radians (degree)
|
2213
|
+
degree * DEG2RAD__
|
1855
2214
|
end
|
1856
2215
|
|
1857
|
-
#
|
2216
|
+
# Converts radian to degree.
|
1858
2217
|
#
|
1859
|
-
# @param
|
1860
|
-
# @param extension [String] type of image to load (ex. 'png')
|
2218
|
+
# @param radian [Numeric] radian to convert
|
1861
2219
|
#
|
1862
|
-
# @return [
|
2220
|
+
# @return [Numeric] degree
|
1863
2221
|
#
|
1864
|
-
def
|
1865
|
-
|
1866
|
-
Image.new Rays::Image.load filename
|
1867
|
-
end
|
1868
|
-
|
1869
|
-
# @private
|
1870
|
-
private def getImage__ (uri, ext)
|
1871
|
-
ext ||= File.extname uri
|
1872
|
-
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png)$/i
|
1873
|
-
|
1874
|
-
tmpdir = Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name)
|
1875
|
-
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
1876
|
-
path = path.sub_ext ext
|
1877
|
-
|
1878
|
-
unless path.file?
|
1879
|
-
URI.open uri do |input|
|
1880
|
-
tmpdir.mkdir unless tmpdir.directory?
|
1881
|
-
path.open('w') do |output|
|
1882
|
-
while buf = input.read(2 ** 16)
|
1883
|
-
output.write buf
|
1884
|
-
end
|
1885
|
-
end
|
1886
|
-
end
|
1887
|
-
end
|
1888
|
-
path.to_s
|
1889
|
-
end
|
1890
|
-
|
1891
|
-
def createGraphics (width, height)
|
1892
|
-
Graphics.new width, height
|
1893
|
-
end
|
1894
|
-
|
1895
|
-
end# Utility
|
1896
|
-
|
1897
|
-
|
1898
|
-
# Processing context
|
1899
|
-
#
|
1900
|
-
module Context
|
1901
|
-
|
1902
|
-
include GraphicsContext, Utility, Math
|
1903
|
-
|
1904
|
-
# @private
|
1905
|
-
def setup__ (window)
|
1906
|
-
@window__ = window
|
1907
|
-
@image__ = @window__.canvas
|
1908
|
-
super @window__.canvas_painter.paint {background 0.8}
|
1909
|
-
|
1910
|
-
@loop__ = true
|
1911
|
-
@redraw__ = false
|
1912
|
-
@frameCount__ = 0
|
1913
|
-
@mousePos__ =
|
1914
|
-
@mousePrevPos__ = Rays::Point.new 0
|
1915
|
-
@mousePressed__ = false
|
1916
|
-
@touches__ = []
|
1917
|
-
|
1918
|
-
@window__.before_draw = proc {beginDraw}
|
1919
|
-
@window__.after_draw = proc {endDraw}
|
1920
|
-
|
1921
|
-
drawFrame = -> {
|
1922
|
-
@image__ = @window__.canvas
|
1923
|
-
@painter__ = @window__.canvas_painter
|
1924
|
-
begin
|
1925
|
-
push
|
1926
|
-
@drawBlock__.call if @drawBlock__
|
1927
|
-
ensure
|
1928
|
-
pop
|
1929
|
-
@frameCount__ += 1
|
1930
|
-
end
|
1931
|
-
}
|
1932
|
-
|
1933
|
-
@window__.draw = proc do |e|
|
1934
|
-
if @loop__ || @redraw__
|
1935
|
-
@redraw__ = false
|
1936
|
-
drawFrame.call
|
1937
|
-
end
|
1938
|
-
@mousePrevPos__ = @mousePos__
|
1939
|
-
end
|
1940
|
-
|
1941
|
-
updatePointerStates = -> event, pressed = nil {
|
1942
|
-
@mousePos__ = event.pos
|
1943
|
-
@mousePressed__ = pressed if pressed != nil
|
1944
|
-
@touches__ = event.positions.map {|pos| Touch.new pos.x, pos.y}
|
1945
|
-
}
|
1946
|
-
|
1947
|
-
@window__.pointer_down = proc do |e|
|
1948
|
-
updatePointerStates.call e, true
|
1949
|
-
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
1950
|
-
end
|
1951
|
-
|
1952
|
-
@window__.pointer_up = proc do |e|
|
1953
|
-
updatePointerStates.call e, false
|
1954
|
-
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
1955
|
-
end
|
1956
|
-
|
1957
|
-
@window__.pointer_move = proc do |e|
|
1958
|
-
updatePointerStates.call e
|
1959
|
-
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
1960
|
-
end
|
1961
|
-
|
1962
|
-
@window__.pointer_drag = proc do |e|
|
1963
|
-
updatePointerStates.call e
|
1964
|
-
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
1965
|
-
end
|
2222
|
+
def degrees (radian)
|
2223
|
+
radian * RAD2DEG__
|
1966
2224
|
end
|
1967
2225
|
|
1968
|
-
#
|
2226
|
+
# Returns the sine of an angle.
|
1969
2227
|
#
|
1970
|
-
|
1971
|
-
@window__.setup = block
|
1972
|
-
nil
|
1973
|
-
end
|
1974
|
-
|
1975
|
-
# Define draw block.
|
2228
|
+
# @param angle [Numeric] angle in radians
|
1976
2229
|
#
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
def key (&block)
|
1983
|
-
@window__.key = block
|
1984
|
-
nil
|
1985
|
-
end
|
1986
|
-
|
1987
|
-
def mousePressed (&block)
|
1988
|
-
@mousePressedBlock__ = block if block
|
1989
|
-
@mousePressed__
|
1990
|
-
end
|
1991
|
-
|
1992
|
-
def mouseReleased (&block)
|
1993
|
-
@mouseReleasedBlock__ = block if block
|
1994
|
-
nil
|
1995
|
-
end
|
1996
|
-
|
1997
|
-
def mouseMoved (&block)
|
1998
|
-
@mouseMovedBlock__ = block if block
|
1999
|
-
nil
|
2000
|
-
end
|
2001
|
-
|
2002
|
-
def mouseDragged (&block)
|
2003
|
-
@mouseDraggedBlock__ = block if block
|
2004
|
-
nil
|
2005
|
-
end
|
2006
|
-
|
2007
|
-
def touchStarted (&block)
|
2008
|
-
@touchStartedBlock__ = block if block
|
2009
|
-
nil
|
2010
|
-
end
|
2011
|
-
|
2012
|
-
def touchEnded (&block)
|
2013
|
-
@touchEndedBlock__ = block if block
|
2014
|
-
nil
|
2015
|
-
end
|
2016
|
-
|
2017
|
-
def touchMoved (&block)
|
2018
|
-
@touchMovedBlock__ = block if block
|
2019
|
-
nil
|
2020
|
-
end
|
2021
|
-
|
2022
|
-
# @private
|
2023
|
-
private def size__ (width, height)
|
2024
|
-
raise 'size() must be called on startup or setup block' if @started__
|
2025
|
-
|
2026
|
-
@painter__.__send__ :end_paint
|
2027
|
-
@window__.__send__ :reset_canvas, width, height
|
2028
|
-
@painter__.__send__ :begin_paint
|
2029
|
-
|
2030
|
-
@auto_resize__ = false
|
2031
|
-
end
|
2032
|
-
|
2033
|
-
def windowWidth ()
|
2034
|
-
@window__.width
|
2230
|
+
# @return [Numeric] the sine
|
2231
|
+
#
|
2232
|
+
def sin (angle)
|
2233
|
+
Math.sin angle
|
2035
2234
|
end
|
2036
2235
|
|
2037
|
-
|
2038
|
-
|
2236
|
+
# Returns the cosine of an angle.
|
2237
|
+
#
|
2238
|
+
# @param angle [Numeric] angle in radians
|
2239
|
+
#
|
2240
|
+
# @return [Numeric] the cosine
|
2241
|
+
#
|
2242
|
+
def cos (angle)
|
2243
|
+
Math.cos angle
|
2039
2244
|
end
|
2040
2245
|
|
2041
|
-
# Returns
|
2246
|
+
# Returns the ratio of the sine and cosine of an angle.
|
2042
2247
|
#
|
2043
|
-
# @
|
2248
|
+
# @param angle [Numeric] angle in radians
|
2044
2249
|
#
|
2045
|
-
|
2046
|
-
|
2250
|
+
# @return [Numeric] the tangent
|
2251
|
+
#
|
2252
|
+
def tan (angle)
|
2253
|
+
Math.tan angle
|
2047
2254
|
end
|
2048
2255
|
|
2049
|
-
# Returns
|
2256
|
+
# Returns the inverse of sin().
|
2050
2257
|
#
|
2051
|
-
# @
|
2258
|
+
# @param value [Numeric] value for calculation
|
2052
2259
|
#
|
2053
|
-
|
2054
|
-
|
2260
|
+
# @return [Numeric] the arc sine
|
2261
|
+
#
|
2262
|
+
def asin (value)
|
2263
|
+
Math.asin value
|
2055
2264
|
end
|
2056
2265
|
|
2057
|
-
# Returns
|
2266
|
+
# Returns the inverse of cos().
|
2058
2267
|
#
|
2059
|
-
# @
|
2268
|
+
# @param value [Numeric] value for calculation
|
2060
2269
|
#
|
2061
|
-
|
2062
|
-
|
2270
|
+
# @return [Numeric] the arc cosine
|
2271
|
+
#
|
2272
|
+
def acos (value)
|
2273
|
+
Math.acos value
|
2063
2274
|
end
|
2064
2275
|
|
2065
|
-
# Returns
|
2276
|
+
# Returns the inverse of tan().
|
2066
2277
|
#
|
2067
|
-
# @
|
2278
|
+
# @param value [Numeric] value for valculation
|
2068
2279
|
#
|
2069
|
-
|
2070
|
-
|
2280
|
+
# @return [Numeric] the arc tangent
|
2281
|
+
#
|
2282
|
+
def atan (value)
|
2283
|
+
Math.atan value
|
2071
2284
|
end
|
2072
2285
|
|
2073
|
-
# Returns
|
2286
|
+
# Returns the angle from a specified point.
|
2074
2287
|
#
|
2075
|
-
# @
|
2288
|
+
# @param y [Numeric] y of the point
|
2289
|
+
# @param x [Numeric] x of the point
|
2076
2290
|
#
|
2077
|
-
|
2078
|
-
|
2291
|
+
# @return [Numeric] the angle in radians
|
2292
|
+
#
|
2293
|
+
def atan2 (y, x)
|
2294
|
+
Math.atan2 y, x
|
2079
2295
|
end
|
2080
2296
|
|
2081
|
-
# Returns
|
2297
|
+
# Returns the perlin noise value.
|
2082
2298
|
#
|
2083
|
-
# @
|
2299
|
+
# @overload noise(x)
|
2300
|
+
# @overload noise(x, y)
|
2301
|
+
# @overload noise(x, y, z)
|
2084
2302
|
#
|
2085
|
-
|
2086
|
-
|
2303
|
+
# @param x [Numeric] horizontal point in noise space
|
2304
|
+
# @param y [Numeric] vertical point in noise space
|
2305
|
+
# @param z [Numeric] depth point in noise space
|
2306
|
+
#
|
2307
|
+
# @return [Numeric] noise value (0.0..1.0)
|
2308
|
+
#
|
2309
|
+
def noise (x, y = 0, z = 0)
|
2310
|
+
Rays.perlin(x, y, z) / 2.0 + 0.5
|
2087
2311
|
end
|
2088
2312
|
|
2089
|
-
# Returns
|
2313
|
+
# Returns a random number in range low...high
|
2090
2314
|
#
|
2091
|
-
# @
|
2315
|
+
# @overload random()
|
2316
|
+
# @overload random(high)
|
2317
|
+
# @overload random(low, high)
|
2318
|
+
# @overload random(choices)
|
2092
2319
|
#
|
2093
|
-
|
2094
|
-
|
2320
|
+
# @param low [Numeric] lower limit
|
2321
|
+
# @param high [Numeric] upper limit
|
2322
|
+
# @param choices [Array] array to choose from
|
2323
|
+
#
|
2324
|
+
# @return [Float] random number
|
2325
|
+
#
|
2326
|
+
def random (*args)
|
2327
|
+
return args.first.sample if args.first.kind_of? Array
|
2328
|
+
high, low = args.reverse
|
2329
|
+
rand (low || 0).to_f...(high || 1).to_f
|
2095
2330
|
end
|
2096
2331
|
|
2097
|
-
#
|
2332
|
+
# Creates a new vector.
|
2098
2333
|
#
|
2099
|
-
# @
|
2334
|
+
# @overload createVector()
|
2335
|
+
# @overload createVector(x, y)
|
2336
|
+
# @overload createVector(x, y, z)
|
2100
2337
|
#
|
2101
|
-
|
2102
|
-
|
2338
|
+
# @param x [Numeric] x of new vector
|
2339
|
+
# @param y [Numeric] y of new vector
|
2340
|
+
# @param z [Numeric] z of new vector
|
2341
|
+
#
|
2342
|
+
# @return [Vector] new vector
|
2343
|
+
#
|
2344
|
+
def createVector (*args)
|
2345
|
+
Vector.new *args
|
2103
2346
|
end
|
2104
2347
|
|
2105
|
-
#
|
2348
|
+
# Creates a camera object as a video input device.
|
2106
2349
|
#
|
2107
|
-
# @return [
|
2350
|
+
# @return [Capture] camera object
|
2108
2351
|
#
|
2109
|
-
def
|
2110
|
-
|
2352
|
+
def createCapture (*args)
|
2353
|
+
Capture.new *args
|
2111
2354
|
end
|
2112
2355
|
|
2113
|
-
#
|
2356
|
+
# Creates a new off-screen graphics context object.
|
2114
2357
|
#
|
2115
|
-
# @
|
2358
|
+
# @param width [Numeric] width of graphics image
|
2359
|
+
# @param height [Numeric] height of graphics image
|
2116
2360
|
#
|
2117
|
-
|
2118
|
-
|
2361
|
+
# @return [Graphics] graphics object
|
2362
|
+
#
|
2363
|
+
def createGraphics (width, height)
|
2364
|
+
Graphics.new width, height
|
2119
2365
|
end
|
2120
2366
|
|
2121
|
-
#
|
2367
|
+
# Loads image.
|
2122
2368
|
#
|
2123
|
-
# @
|
2369
|
+
# @param filename [String] file name to load image
|
2370
|
+
# @param extension [String] type of image to load (ex. 'png')
|
2124
2371
|
#
|
2125
|
-
|
2126
|
-
|
2372
|
+
# @return [Image] loaded image object
|
2373
|
+
#
|
2374
|
+
def loadImage (filename, extension = nil)
|
2375
|
+
filename = getImage__ filename, extension if filename =~ %r|^https?://|
|
2376
|
+
Image.new Rays::Image.load filename
|
2377
|
+
end
|
2378
|
+
|
2379
|
+
# @private
|
2380
|
+
private def getImage__ (uri, ext)
|
2381
|
+
ext ||= File.extname uri
|
2382
|
+
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png)$/i
|
2383
|
+
|
2384
|
+
tmpdir = Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name)
|
2385
|
+
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
2386
|
+
path = path.sub_ext ext
|
2387
|
+
|
2388
|
+
unless path.file?
|
2389
|
+
URI.open uri do |input|
|
2390
|
+
tmpdir.mkdir unless tmpdir.directory?
|
2391
|
+
path.open('w') do |output|
|
2392
|
+
while buf = input.read(2 ** 16)
|
2393
|
+
output.write buf
|
2394
|
+
end
|
2395
|
+
end
|
2396
|
+
end
|
2397
|
+
end
|
2398
|
+
path.to_s
|
2127
2399
|
end
|
2128
2400
|
|
2129
2401
|
end# Context
|