rubysketch 0.3.2 → 0.3.7
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 +33 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -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 +1109 -318
- 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 +397 -0
- metadata +18 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41b3a75aeb6c8bdc443d2d87e44c60361a527e4d6b8b3918e8b1eaa2503f92e4
|
4
|
+
data.tar.gz: 7f373d0f3fdb31d38bb76d8e8ed88ce2f3cedca0c696d8a5f571ded1e78fb15d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffcba1a2e5ae98525c4c1512230d249995071e6be9183918b6f62ed5293d9ac8f530d38aa5f544d2d4fc431ca17f38c7746955df313e9609e0ee528551045a51
|
7
|
+
data.tar.gz: cb49daa453cdf6dd9027a59c508363a63fed2e210b0acbcfa311e66334b107a88471e5b8b59dac7f77b5aa04423aaa2d0cd2b2fa0c4b1221b76997a93ce89e79
|
@@ -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,39 @@
|
|
1
1
|
# RubySketch ChangeLog
|
2
2
|
|
3
3
|
|
4
|
+
## [0.3.7] - 2020-11-18
|
5
|
+
|
6
|
+
- add Capture class
|
7
|
+
- add log(), exp(), sqrt() and PI
|
8
|
+
- add examples/camera.rb
|
9
|
+
- add examples/breakout.rb
|
10
|
+
- fix error on calling image()
|
11
|
+
|
12
|
+
|
13
|
+
## [0.3.6] - 2020-08-02
|
14
|
+
|
15
|
+
- random() can take array or nothing
|
16
|
+
- use github actions to release gem package
|
17
|
+
|
18
|
+
|
19
|
+
## [0.3.5] - 2020-08-02
|
20
|
+
|
21
|
+
- add random()
|
22
|
+
- add sin(), cos(), tan(), asin(), acos(), atan() and atan2()
|
23
|
+
- make Vector class accessible from user script context
|
24
|
+
- fix error on calling rotate()
|
25
|
+
|
26
|
+
|
27
|
+
## [0.3.4] - 2020-08-02
|
28
|
+
|
29
|
+
- delete Utility module
|
30
|
+
|
31
|
+
|
32
|
+
## [0.3.3] - 2020-08-01
|
33
|
+
|
34
|
+
- add Vector class
|
35
|
+
|
36
|
+
|
4
37
|
## [0.3.2] - 2020-07-22
|
5
38
|
|
6
39
|
- text() draws to the baseline by default
|
data/Gemfile
ADDED
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.7
|
@@ -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
|
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,13 +6,574 @@ 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
|
+
|
16
|
+
# Vector class.
|
17
|
+
#
|
18
|
+
class Vector
|
19
|
+
|
20
|
+
include Comparable
|
21
|
+
|
22
|
+
# Initialize vector object.
|
23
|
+
#
|
24
|
+
# @overload new()
|
25
|
+
# @overload new(x)
|
26
|
+
# @overload new(x, y)
|
27
|
+
# @overload new(x, y, z)
|
28
|
+
# @overload new(v)
|
29
|
+
# @overload new(a)
|
30
|
+
#
|
31
|
+
# @param x [Numeric] x of vector
|
32
|
+
# @param y [Numeric] y of vector
|
33
|
+
# @param z [Numeric] z of vector
|
34
|
+
# @param v [Vector] vector object to copy
|
35
|
+
# @param a [Array] array like [x, y, z]
|
36
|
+
#
|
37
|
+
def initialize (x = 0, y = 0, z = 0, context: nil)
|
38
|
+
@point = case x
|
39
|
+
when Rays::Point then x.dup
|
40
|
+
when Vector then x.getInternal__.dup
|
41
|
+
when Array then Rays::Point.new x[0] || 0, x[1] || 0, x[2] || 0
|
42
|
+
else Rays::Point.new x || 0, y || 0, z || 0
|
43
|
+
end
|
44
|
+
@context = context || Context.context__
|
45
|
+
end
|
46
|
+
|
47
|
+
# Initializer for dup or clone
|
48
|
+
#
|
49
|
+
def initialize_copy (o)
|
50
|
+
@point = o.getInternal__.dup
|
51
|
+
end
|
52
|
+
|
53
|
+
# Copy vector object
|
54
|
+
#
|
55
|
+
# @return [Vector] duplicated vector object
|
56
|
+
#
|
57
|
+
alias copy dup
|
58
|
+
|
59
|
+
# Sets x, y and z.
|
60
|
+
#
|
61
|
+
# @overload set(x)
|
62
|
+
# @overload set(x, y)
|
63
|
+
# @overload set(x, y, z)
|
64
|
+
# @overload set(v)
|
65
|
+
# @overload set(a)
|
66
|
+
#
|
67
|
+
# @param x [Numeric] x of vector
|
68
|
+
# @param y [Numeric] y of vector
|
69
|
+
# @param z [Numeric] z of vector
|
70
|
+
# @param v [Vector] vector object to copy
|
71
|
+
# @param a [Array] array with x, y, z
|
72
|
+
#
|
73
|
+
# @return [nil] nil
|
74
|
+
#
|
75
|
+
def set (*args)
|
76
|
+
initialize *args
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
# Gets x value.
|
81
|
+
#
|
82
|
+
# @return [Numeric] x value of vector
|
83
|
+
#
|
84
|
+
def x ()
|
85
|
+
@point.x
|
86
|
+
end
|
87
|
+
|
88
|
+
# Gets y value.
|
89
|
+
#
|
90
|
+
# @return [Numeric] y value of vector
|
91
|
+
#
|
92
|
+
def y ()
|
93
|
+
@point.y
|
94
|
+
end
|
95
|
+
|
96
|
+
# Gets z value.
|
97
|
+
#
|
98
|
+
# @return [Numeric] z value of vector
|
99
|
+
#
|
100
|
+
def z ()
|
101
|
+
@point.z
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sets x value.
|
105
|
+
#
|
106
|
+
# @return [Numeric] x value of vector
|
107
|
+
#
|
108
|
+
def x= (x)
|
109
|
+
@point.x = x
|
110
|
+
end
|
111
|
+
|
112
|
+
# Sets y value.
|
113
|
+
#
|
114
|
+
# @return [Numeric] y value of vector
|
115
|
+
#
|
116
|
+
def y= (y)
|
117
|
+
@point.y = y
|
118
|
+
end
|
119
|
+
|
120
|
+
# Sets z value.
|
121
|
+
#
|
122
|
+
# @return [Numeric] z value of vector
|
123
|
+
#
|
124
|
+
def z= (z)
|
125
|
+
@point.z = z
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns the interpolated vector between 2 vectors.
|
129
|
+
#
|
130
|
+
# @overload lerp(v, amount)
|
131
|
+
# @overload lerp(x, y, amount)
|
132
|
+
# @overload lerp(x, y, z, amount)
|
133
|
+
#
|
134
|
+
# @param v [Vector] vector to interpolate
|
135
|
+
# @param x [Numeric] x of vector to interpolate
|
136
|
+
# @param y [Numeric] y of vector to interpolate
|
137
|
+
# @param z [Numeric] z of vector to interpolate
|
138
|
+
# @param amount [Numeric] amount to interpolate
|
139
|
+
#
|
140
|
+
# @return [Vector] interporated vector
|
141
|
+
#
|
142
|
+
def lerp (*args, amount)
|
143
|
+
v = toVector__ *args
|
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
|
+
self
|
148
|
+
end
|
149
|
+
|
150
|
+
# Returns the interpolated vector between 2 vectors.
|
151
|
+
#
|
152
|
+
# @param v1 [Vector] vector to interpolate
|
153
|
+
# @param v2 [Vector] vector to interpolate
|
154
|
+
# @param amount [Numeric] amount to interpolate
|
155
|
+
#
|
156
|
+
# @return [Vector] interporated vector
|
157
|
+
#
|
158
|
+
def self.lerp (v1, v2, amount)
|
159
|
+
v1.dup.lerp v2, amount
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns x, y, z as an array
|
163
|
+
#
|
164
|
+
# @return [Array] array of x, y, z
|
165
|
+
#
|
166
|
+
def array ()
|
167
|
+
@point.to_a 3
|
168
|
+
end
|
169
|
+
|
170
|
+
# Adds a vector.
|
171
|
+
#
|
172
|
+
# @overload add(v)
|
173
|
+
# @overload add(x, y)
|
174
|
+
# @overload add(x, y, z)
|
175
|
+
#
|
176
|
+
# @param v [Vector] vector to add
|
177
|
+
# @param x [Vector] x of vector to add
|
178
|
+
# @param y [Vector] y of vector to add
|
179
|
+
# @param z [Vector] z of vector to add
|
180
|
+
#
|
181
|
+
# @return [Vector] added vector
|
182
|
+
#
|
183
|
+
def add (*args)
|
184
|
+
@point += toVector__(*args).getInternal__
|
185
|
+
self
|
186
|
+
end
|
187
|
+
|
188
|
+
# Subtracts a vector.
|
189
|
+
#
|
190
|
+
# @overload sub(v)
|
191
|
+
# @overload sub(x, y)
|
192
|
+
# @overload sub(x, y, z)
|
193
|
+
#
|
194
|
+
# @param v [Vector] vector to subtract
|
195
|
+
# @param x [Vector] x of vector to subtract
|
196
|
+
# @param y [Vector] y of vector to subtract
|
197
|
+
# @param z [Vector] z of vector to subtract
|
198
|
+
#
|
199
|
+
# @return [Vector] subtracted vector
|
200
|
+
#
|
201
|
+
def sub (*args)
|
202
|
+
@point -= toVector__(*args).getInternal__
|
203
|
+
self
|
204
|
+
end
|
205
|
+
|
206
|
+
# Multiplies a vector by scalar.
|
207
|
+
#
|
208
|
+
# @param num [Numeric] number to multiply the vector
|
209
|
+
#
|
210
|
+
# @return [Vector] multiplied vector
|
211
|
+
#
|
212
|
+
def mult (num)
|
213
|
+
@point *= num
|
214
|
+
self
|
215
|
+
end
|
216
|
+
|
217
|
+
# Divides a vector by scalar.
|
218
|
+
#
|
219
|
+
# @param num [Numeric] number to divide the vector
|
220
|
+
#
|
221
|
+
# @return [Vector] divided vector
|
222
|
+
#
|
223
|
+
def div (num)
|
224
|
+
@point /= num
|
225
|
+
self
|
226
|
+
end
|
227
|
+
|
228
|
+
# Adds a vector.
|
229
|
+
#
|
230
|
+
# @param v [Vector] vector to add
|
231
|
+
#
|
232
|
+
# @return [Vector] added vector
|
233
|
+
#
|
234
|
+
def + (v)
|
235
|
+
dup.add v
|
236
|
+
end
|
237
|
+
|
238
|
+
# Subtracts a vector.
|
239
|
+
#
|
240
|
+
# @param v [Vector] vector to subtract
|
241
|
+
#
|
242
|
+
# @return [Vector] subtracted vector
|
243
|
+
#
|
244
|
+
def - (v)
|
245
|
+
dup.sub v
|
246
|
+
end
|
247
|
+
|
248
|
+
# Multiplies a vector by scalar.
|
249
|
+
#
|
250
|
+
# @param num [Numeric] number to multiply the vector
|
251
|
+
#
|
252
|
+
# @return [Vector] multiplied vector
|
253
|
+
#
|
254
|
+
def * (num)
|
255
|
+
dup.mult num
|
256
|
+
end
|
257
|
+
|
258
|
+
# Divides a vector by scalar.
|
259
|
+
#
|
260
|
+
# @param num [Numeric] number to divide the vector
|
261
|
+
#
|
262
|
+
# @return [Vector] divided vector
|
263
|
+
#
|
264
|
+
def / (num)
|
265
|
+
dup.div num
|
266
|
+
end
|
267
|
+
|
268
|
+
# Adds 2 vectors.
|
269
|
+
#
|
270
|
+
# @overload add(v1, v2)
|
271
|
+
# @overload add(v1, v2, target)
|
272
|
+
#
|
273
|
+
# @param v1 [Vector] a vector
|
274
|
+
# @param v2 [Vector] another vector
|
275
|
+
# @param target [Vector] vector to store added vector
|
276
|
+
#
|
277
|
+
# @return [Vector] added vector
|
278
|
+
#
|
279
|
+
def self.add (v1, v2, target = nil)
|
280
|
+
v = v1 + v2
|
281
|
+
target.set v if self === target
|
282
|
+
v
|
283
|
+
end
|
284
|
+
|
285
|
+
# Subtracts 2 vectors.
|
286
|
+
#
|
287
|
+
# @overload sub(v1, v2)
|
288
|
+
# @overload sub(v1, v2, target)
|
289
|
+
#
|
290
|
+
# @param v1 [Vector] a vector
|
291
|
+
# @param v2 [Vector] another vector
|
292
|
+
# @param target [Vector] vector to store subtracted vector
|
293
|
+
#
|
294
|
+
# @return [Vector] subtracted vector
|
295
|
+
#
|
296
|
+
def self.sub (v1, v2, target = nil)
|
297
|
+
v = v1 - v2
|
298
|
+
target.set v if self === target
|
299
|
+
v
|
300
|
+
end
|
301
|
+
|
302
|
+
# Multiplies a vector by scalar.
|
303
|
+
#
|
304
|
+
# @overload mult(v, num)
|
305
|
+
# @overload mult(v, num, target)
|
306
|
+
#
|
307
|
+
# @param v [Vector] a vector
|
308
|
+
# @param num [Numeric] number to multiply the vector
|
309
|
+
# @param target [Vector] vector to store multiplied vector
|
310
|
+
#
|
311
|
+
# @return [Vector] multiplied vector
|
312
|
+
#
|
313
|
+
def self.mult (v1, num, target = nil)
|
314
|
+
v = v1 * num
|
315
|
+
target.set v if self === target
|
316
|
+
v
|
317
|
+
end
|
318
|
+
|
319
|
+
# Divides a vector by scalar.
|
320
|
+
#
|
321
|
+
# @overload div(v, num)
|
322
|
+
# @overload div(v, num, target)
|
323
|
+
#
|
324
|
+
# @param v [Vector] a vector
|
325
|
+
# @param num [Numeric] number to divide the vector
|
326
|
+
# @param target [Vector] vector to store divided vector
|
327
|
+
#
|
328
|
+
# @return [Vector] divided vector
|
329
|
+
#
|
330
|
+
def self.div (v1, num, target = nil)
|
331
|
+
v = v1 / num
|
332
|
+
target.set v if self === target
|
333
|
+
v
|
334
|
+
end
|
335
|
+
|
336
|
+
# Returns the length of the vector.
|
337
|
+
#
|
338
|
+
# @return [Numeric] length
|
339
|
+
#
|
340
|
+
def mag ()
|
341
|
+
@point.length
|
342
|
+
end
|
343
|
+
|
344
|
+
# Returns squared length of the vector.
|
345
|
+
#
|
346
|
+
# @return [Numeric] squared length
|
347
|
+
#
|
348
|
+
def magSq ()
|
349
|
+
Rays::Point::dot(@point, @point)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Changes the length of the vector.
|
353
|
+
#
|
354
|
+
# @overload setMag(len)
|
355
|
+
# @overload setMag(target, len)
|
356
|
+
#
|
357
|
+
# @param len [Numeric] length of new vector
|
358
|
+
# @param target [Vector] vector to store new vector
|
359
|
+
#
|
360
|
+
# @return [Vector] vector with new length
|
361
|
+
#
|
362
|
+
def setMag (target = nil, len)
|
363
|
+
(target || self).set @point.normal * len
|
364
|
+
end
|
365
|
+
|
366
|
+
# Changes the length of the vector to 1.0.
|
367
|
+
#
|
368
|
+
# @param target [Vector] vector to store the normalized vector
|
369
|
+
#
|
370
|
+
# @return [Vector] normalized vector
|
371
|
+
#
|
372
|
+
def normalize (target = nil)
|
373
|
+
(target || self).set @point.normal
|
374
|
+
end
|
375
|
+
|
376
|
+
# Changes the length of the vector if it's length is greater than the max value.
|
377
|
+
#
|
378
|
+
# @param max [Numeric] max length
|
379
|
+
#
|
380
|
+
# @return [Vector] new vector
|
381
|
+
#
|
382
|
+
def limit (max)
|
383
|
+
setMag max if magSq > max ** 2
|
384
|
+
self
|
385
|
+
end
|
386
|
+
|
387
|
+
# Returns the distance of 2 vectors.
|
388
|
+
#
|
389
|
+
# @param v [Vector] a vector
|
390
|
+
#
|
391
|
+
# @return [Numeric] the distance
|
392
|
+
#
|
393
|
+
def dist (v)
|
394
|
+
(self - v).mag
|
395
|
+
end
|
396
|
+
|
397
|
+
# Returns the distance of 2 vectors.
|
398
|
+
#
|
399
|
+
# @param v1 [Vector] a vector
|
400
|
+
# @param v2 [Vector] another vector
|
401
|
+
#
|
402
|
+
# @return [Numeric] the distance
|
403
|
+
#
|
404
|
+
def self.dist (v1, v2)
|
405
|
+
v1.dist v2
|
406
|
+
end
|
407
|
+
|
408
|
+
# Calculates the dot product of 2 vectors.
|
409
|
+
#
|
410
|
+
# @overload dot(v)
|
411
|
+
# @overload dot(x, y)
|
412
|
+
# @overload dot(x, y, z)
|
413
|
+
#
|
414
|
+
# @param v [Vector] a vector
|
415
|
+
# @param x [Numeric] x of vector
|
416
|
+
# @param y [Numeric] y of vector
|
417
|
+
# @param z [Numeric] z of vector
|
418
|
+
#
|
419
|
+
# @return [Numeric] result of dot product
|
420
|
+
#
|
421
|
+
def dot (*args)
|
422
|
+
Rays::Point::dot getInternal__, toVector__(*args).getInternal__
|
423
|
+
end
|
424
|
+
|
425
|
+
# Calculates the dot product of 2 vectors.
|
426
|
+
#
|
427
|
+
# @param v1 [Vector] a vector
|
428
|
+
# @param v2 [Vector] another vector
|
429
|
+
#
|
430
|
+
# @return [Numeric] result of dot product
|
431
|
+
#
|
432
|
+
def self.dot (v1, v2)
|
433
|
+
v1.dot v2
|
434
|
+
end
|
435
|
+
|
436
|
+
# Calculates the cross product of 2 vectors.
|
437
|
+
#
|
438
|
+
# @overload cross(v)
|
439
|
+
# @overload cross(x, y)
|
440
|
+
# @overload cross(x, y, z)
|
441
|
+
#
|
442
|
+
# @param v [Vector] a vector
|
443
|
+
# @param x [Numeric] x of vector
|
444
|
+
# @param y [Numeric] y of vector
|
445
|
+
# @param z [Numeric] z of vector
|
446
|
+
#
|
447
|
+
# @return [Numeric] result of cross product
|
448
|
+
#
|
449
|
+
def cross (a, *rest)
|
450
|
+
target = self.class === rest.last ? rest.pop : nil
|
451
|
+
v = self.class.new Rays::Point::cross getInternal__, toVector__(a, *rest).getInternal__
|
452
|
+
target.set v if self.class === target
|
453
|
+
v
|
454
|
+
end
|
455
|
+
|
456
|
+
# Calculates the cross product of 2 vectors.
|
457
|
+
#
|
458
|
+
# @param v1 [Vector] a vector
|
459
|
+
# @param v2 [Vector] another vector
|
460
|
+
#
|
461
|
+
# @return [Numeric] result of cross product
|
462
|
+
#
|
463
|
+
def self.cross (v1, v2, target = nil)
|
464
|
+
v1.cross v2, target
|
465
|
+
end
|
466
|
+
|
467
|
+
# Rotate the vector.
|
468
|
+
#
|
469
|
+
# @param angle [Numeric] the angle of rotation
|
470
|
+
#
|
471
|
+
# @return [Vector] rotated this object
|
472
|
+
#
|
473
|
+
def rotate (angle)
|
474
|
+
angle = @context ? @context.toAngle__(angle) : angle * RAD2DEG__
|
475
|
+
@point.rotate! angle
|
476
|
+
self
|
477
|
+
end
|
478
|
+
|
479
|
+
# Returns the angle of rotation for this vector.
|
480
|
+
#
|
481
|
+
# @return [Numeric] the angle in radians
|
482
|
+
#
|
483
|
+
def heading ()
|
484
|
+
Math.atan2 y, x
|
485
|
+
end
|
486
|
+
|
487
|
+
# Returns rotated new vector.
|
488
|
+
#
|
489
|
+
# @param angle [Numeric] the angle of rotation
|
490
|
+
# @param target [Vector] vector to store new vector
|
491
|
+
#
|
492
|
+
# @return [Vector] rotated vector
|
493
|
+
#
|
494
|
+
def self.fromAngle (angle, target = nil)
|
495
|
+
v = self.new(1, 0, 0).rotate(angle)
|
496
|
+
target.set v if target
|
497
|
+
v
|
498
|
+
end
|
499
|
+
|
500
|
+
# Returns angle between 2 vectors.
|
501
|
+
#
|
502
|
+
# @param v1 [Vector] a vector
|
503
|
+
# @param v2 [Vector] another vector
|
504
|
+
#
|
505
|
+
# @return [Numeric] angle in radians
|
506
|
+
#
|
507
|
+
def self.angleBetween (v1, v2)
|
508
|
+
x1, y1, z1 = v1.array
|
509
|
+
x2, y2, z2 = v2.array
|
510
|
+
return 0 if (x1 == 0 && y1 == 0 && z1 == 0) || (x2 == 0 && y2 == 0 && z2 == 0)
|
511
|
+
|
512
|
+
x = dot(v1, v2) / (v1.mag * v2.mag)
|
513
|
+
return Math::PI if x <= -1
|
514
|
+
return 0 if x >= 1
|
515
|
+
return Math.acos x
|
516
|
+
end
|
517
|
+
|
518
|
+
# Returns a new 2D unit vector with a random direction.
|
519
|
+
#
|
520
|
+
# @param target [Vector] a vector to store the new vector
|
521
|
+
#
|
522
|
+
# @return [Vector] a random vector
|
523
|
+
#
|
524
|
+
def self.random2D (target = nil)
|
525
|
+
v = self.fromAngle rand 0.0...(Math::PI * 2)
|
526
|
+
target.set v if target
|
527
|
+
v
|
528
|
+
end
|
529
|
+
|
530
|
+
# Returns a new 3D unit vector with a random direction.
|
531
|
+
#
|
532
|
+
# @param target [Vector] a vector to store the new vector
|
533
|
+
#
|
534
|
+
# @return [Vector] a random vector
|
535
|
+
#
|
536
|
+
def self.random3D (target = nil)
|
537
|
+
angle = rand 0.0...(Math::PI * 2)
|
538
|
+
z = rand -1.0..1.0
|
539
|
+
z2 = z ** 2
|
540
|
+
x = Math.sqrt(1.0 - z2) * Math.cos(angle)
|
541
|
+
y = Math.sqrt(1.0 - z2) * Math.sin(angle)
|
542
|
+
v = self.new x, y, z
|
543
|
+
target.set v if target
|
544
|
+
v
|
545
|
+
end
|
546
|
+
|
547
|
+
# @private
|
548
|
+
def inspect ()
|
549
|
+
"<##{self.class.name} #{x}, #{y}, #{z}>"
|
550
|
+
end
|
551
|
+
|
552
|
+
# @private
|
553
|
+
def <=> (o)
|
554
|
+
@point <=> o.getInternal__
|
555
|
+
end
|
556
|
+
|
557
|
+
# @private
|
558
|
+
protected def getInternal__ ()
|
559
|
+
@point
|
560
|
+
end
|
561
|
+
|
562
|
+
# @private
|
563
|
+
private def toVector__ (*args)
|
564
|
+
self.class === args.first ? args.first : self.class.new(*args)
|
565
|
+
end
|
566
|
+
|
567
|
+
end# Vector
|
568
|
+
|
569
|
+
|
9
570
|
# Image object.
|
10
571
|
#
|
11
572
|
class Image
|
12
573
|
|
13
574
|
# @private
|
14
575
|
def initialize (image)
|
15
|
-
@
|
576
|
+
@image = image
|
16
577
|
end
|
17
578
|
|
18
579
|
# Gets width of image.
|
@@ -20,7 +581,7 @@ module RubySketch
|
|
20
581
|
# @return [Numeric] width of image
|
21
582
|
#
|
22
583
|
def width ()
|
23
|
-
@
|
584
|
+
@image.width
|
24
585
|
end
|
25
586
|
|
26
587
|
# Gets height of image.
|
@@ -28,7 +589,7 @@ module RubySketch
|
|
28
589
|
# @return [Numeric] height of image
|
29
590
|
#
|
30
591
|
def height ()
|
31
|
-
@
|
592
|
+
@image.height
|
32
593
|
end
|
33
594
|
|
34
595
|
# Resizes image.
|
@@ -39,8 +600,8 @@ module RubySketch
|
|
39
600
|
# @return [nil] nil
|
40
601
|
#
|
41
602
|
def resize (width, height)
|
42
|
-
@
|
43
|
-
painter.image @
|
603
|
+
@image = Rays::Image.new(width, height).paint do |painter|
|
604
|
+
painter.image @image, 0, 0, width, height
|
44
605
|
end
|
45
606
|
nil
|
46
607
|
end
|
@@ -64,7 +625,7 @@ module RubySketch
|
|
64
625
|
#
|
65
626
|
def copy (img = nil, sx, sy, sw, sh, dx, dy, dw, dh)
|
66
627
|
img ||= self
|
67
|
-
@
|
628
|
+
@image.paint do |painter|
|
68
629
|
painter.image img.getInternal__, sx, sy, sw, sh, dx, dy, dw, dh
|
69
630
|
end
|
70
631
|
end
|
@@ -74,12 +635,12 @@ module RubySketch
|
|
74
635
|
# @param filename [String] file name to save image
|
75
636
|
#
|
76
637
|
def save (filename)
|
77
|
-
@
|
638
|
+
@image.save filename
|
78
639
|
end
|
79
640
|
|
80
641
|
# @private
|
81
642
|
def getInternal__ ()
|
82
|
-
@
|
643
|
+
@image
|
83
644
|
end
|
84
645
|
|
85
646
|
end# Image
|
@@ -167,43 +728,110 @@ module RubySketch
|
|
167
728
|
end# Touch
|
168
729
|
|
169
730
|
|
170
|
-
#
|
731
|
+
# Camera object.
|
171
732
|
#
|
172
|
-
|
733
|
+
class Capture
|
173
734
|
|
174
|
-
#
|
735
|
+
# Returns a list of available camera device names
|
175
736
|
#
|
176
|
-
|
177
|
-
|
178
|
-
# PI / 4
|
737
|
+
# @return [Array] device name list
|
179
738
|
#
|
180
|
-
|
739
|
+
def self.list ()
|
740
|
+
['default']
|
741
|
+
end
|
181
742
|
|
182
|
-
#
|
743
|
+
# Initialize camera object.
|
183
744
|
#
|
184
|
-
|
745
|
+
def initialize ()
|
746
|
+
@camera = Rays::Camera.new
|
747
|
+
end
|
185
748
|
|
186
|
-
#
|
749
|
+
# Start capturing.
|
187
750
|
#
|
188
|
-
|
189
|
-
|
190
|
-
# RGB mode for colorMode().
|
751
|
+
# @return [Capture] self
|
191
752
|
#
|
192
|
-
|
753
|
+
def start ()
|
754
|
+
raise "Failed to start capture" unless @camera.start
|
755
|
+
self
|
756
|
+
end
|
193
757
|
|
194
|
-
#
|
758
|
+
# Stop capturing.
|
195
759
|
#
|
196
|
-
|
197
|
-
|
198
|
-
# Radian mode for angleMode().
|
760
|
+
# @return [nil] nil
|
199
761
|
#
|
200
|
-
|
762
|
+
def stop ()
|
763
|
+
@camera.stop
|
764
|
+
nil
|
765
|
+
end
|
201
766
|
|
202
|
-
#
|
767
|
+
# Returns is the next captured image available?
|
203
768
|
#
|
204
|
-
|
205
|
-
|
206
|
-
|
769
|
+
# @return [Boolean] true means object has next frame
|
770
|
+
#
|
771
|
+
def available ()
|
772
|
+
@camera.active?
|
773
|
+
end
|
774
|
+
|
775
|
+
# Reads next frame image
|
776
|
+
#
|
777
|
+
def read ()
|
778
|
+
@camera.image
|
779
|
+
end
|
780
|
+
|
781
|
+
# @private
|
782
|
+
def getInternal__ ()
|
783
|
+
@camera.image || dummyImage__
|
784
|
+
end
|
785
|
+
|
786
|
+
# @private
|
787
|
+
private def dummyImage__ ()
|
788
|
+
@dummy ||= Rays::Image.new 1, 1
|
789
|
+
end
|
790
|
+
|
791
|
+
end# Capture
|
792
|
+
|
793
|
+
|
794
|
+
# Drawing context
|
795
|
+
#
|
796
|
+
module GraphicsContext
|
797
|
+
|
798
|
+
# PI
|
799
|
+
#
|
800
|
+
PI = Math::PI
|
801
|
+
|
802
|
+
# PI / 2
|
803
|
+
#
|
804
|
+
HALF_PI = PI / 2
|
805
|
+
|
806
|
+
# PI / 4
|
807
|
+
#
|
808
|
+
QUARTER_PI = PI / 4
|
809
|
+
|
810
|
+
# PI * 2
|
811
|
+
#
|
812
|
+
TWO_PI = PI * 2
|
813
|
+
|
814
|
+
# PI * 2
|
815
|
+
#
|
816
|
+
TAU = PI * 2
|
817
|
+
|
818
|
+
# RGB mode for colorMode().
|
819
|
+
#
|
820
|
+
RGB = :RGB
|
821
|
+
|
822
|
+
# HSB mode for colorMode().
|
823
|
+
#
|
824
|
+
HSB = :HSB
|
825
|
+
|
826
|
+
# Radian mode for angleMode().
|
827
|
+
#
|
828
|
+
RADIANS = :RADIANS
|
829
|
+
|
830
|
+
# Degree mode for angleMode().
|
831
|
+
#
|
832
|
+
DEGREES = :DEGREES
|
833
|
+
|
834
|
+
# Mode for rectMode(), ellipseMode() and imageMode().
|
207
835
|
#
|
208
836
|
CORNER = :CORNER
|
209
837
|
|
@@ -254,7 +882,7 @@ module RubySketch
|
|
254
882
|
@painter__ = painter
|
255
883
|
@painter__.miter_limit = 10
|
256
884
|
|
257
|
-
@
|
885
|
+
@drawing__ = false
|
258
886
|
@hsbColor__ = false
|
259
887
|
@colorMaxes__ = [1.0] * 4
|
260
888
|
@angleScale__ = 1.0
|
@@ -280,11 +908,11 @@ module RubySketch
|
|
280
908
|
def beginDraw ()
|
281
909
|
@matrixStack__.clear
|
282
910
|
@styleStack__.clear
|
283
|
-
@
|
911
|
+
@drawing__ = true
|
284
912
|
end
|
285
913
|
|
286
914
|
def endDraw ()
|
287
|
-
@
|
915
|
+
@drawing__ = false
|
288
916
|
end
|
289
917
|
|
290
918
|
def width ()
|
@@ -361,7 +989,7 @@ module RubySketch
|
|
361
989
|
#
|
362
990
|
def angleMode (mode)
|
363
991
|
@angleScale__ = case mode.upcase.to_sym
|
364
|
-
when RADIANS then
|
992
|
+
when RADIANS then RAD2DEG__
|
365
993
|
when DEGREES then 1.0
|
366
994
|
else raise ArgumentError, "invalid angle mode: #{mode}"
|
367
995
|
end
|
@@ -369,7 +997,7 @@ module RubySketch
|
|
369
997
|
end
|
370
998
|
|
371
999
|
# @private
|
372
|
-
|
1000
|
+
def toAngle__ (angle)
|
373
1001
|
angle * @angleScale__
|
374
1002
|
end
|
375
1003
|
|
@@ -848,8 +1476,9 @@ module RubySketch
|
|
848
1476
|
#
|
849
1477
|
def image (img, a, b, c = nil, d = nil)
|
850
1478
|
assertDrawing__
|
851
|
-
|
852
|
-
|
1479
|
+
i = img.getInternal__
|
1480
|
+
x, y, w, h = toXYWH__ @imageMode__, a, b, c || i.width, d || i.height
|
1481
|
+
@painter__.image i, x, y, w, h
|
853
1482
|
nil
|
854
1483
|
end
|
855
1484
|
|
@@ -1030,8 +1659,8 @@ module RubySketch
|
|
1030
1659
|
end
|
1031
1660
|
|
1032
1661
|
# @private
|
1033
|
-
def assertDrawing__ ()
|
1034
|
-
raise "call beginDraw() before drawing" unless @
|
1662
|
+
private def assertDrawing__ ()
|
1663
|
+
raise "call beginDraw() before drawing" unless @drawing__
|
1035
1664
|
end
|
1036
1665
|
|
1037
1666
|
end# GraphicsContext
|
@@ -1043,17 +1672,23 @@ module RubySketch
|
|
1043
1672
|
|
1044
1673
|
include GraphicsContext
|
1045
1674
|
|
1675
|
+
# Initialize graphics object.
|
1676
|
+
#
|
1046
1677
|
def initialize (width, height)
|
1047
1678
|
@image__ = Rays::Image.new width, height
|
1048
1679
|
setup__ @image__.painter
|
1049
1680
|
end
|
1050
1681
|
|
1682
|
+
# Start drawing.
|
1683
|
+
#
|
1051
1684
|
def beginDraw ()
|
1052
1685
|
@painter__.__send__ :begin_paint
|
1053
1686
|
super
|
1054
1687
|
push
|
1055
1688
|
end
|
1056
1689
|
|
1690
|
+
# End drawing.
|
1691
|
+
#
|
1057
1692
|
def endDraw ()
|
1058
1693
|
pop
|
1059
1694
|
super
|
@@ -1063,86 +1698,325 @@ module RubySketch
|
|
1063
1698
|
end# Graphics
|
1064
1699
|
|
1065
1700
|
|
1066
|
-
|
1701
|
+
# Processing context
|
1702
|
+
#
|
1703
|
+
class Context
|
1067
1704
|
|
1068
|
-
|
1069
|
-
|
1705
|
+
include GraphicsContext
|
1706
|
+
|
1707
|
+
Vector = Processing::Vector
|
1708
|
+
Capture = Processing::Capture
|
1709
|
+
Graphics = Processing::Graphics
|
1710
|
+
|
1711
|
+
@@context__ = nil
|
1712
|
+
|
1713
|
+
def self.context__ ()
|
1714
|
+
@@context__
|
1715
|
+
end
|
1070
1716
|
|
1071
1717
|
# @private
|
1072
|
-
|
1718
|
+
def initialize (window)
|
1719
|
+
@@context__ = self
|
1073
1720
|
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1721
|
+
@window__ = window
|
1722
|
+
@image__ = @window__.canvas
|
1723
|
+
setup__ @window__.canvas_painter.paint {background 0.8}
|
1724
|
+
|
1725
|
+
@loop__ = true
|
1726
|
+
@redraw__ = false
|
1727
|
+
@frameCount__ = 0
|
1728
|
+
@mousePos__ =
|
1729
|
+
@mousePrevPos__ = Rays::Point.new 0
|
1730
|
+
@mousePressed__ = false
|
1731
|
+
@touches__ = []
|
1732
|
+
|
1733
|
+
@window__.before_draw = proc {beginDraw}
|
1734
|
+
@window__.after_draw = proc {endDraw}
|
1735
|
+
|
1736
|
+
drawFrame = -> {
|
1737
|
+
@image__ = @window__.canvas
|
1738
|
+
@painter__ = @window__.canvas_painter
|
1739
|
+
begin
|
1740
|
+
push
|
1741
|
+
@drawBlock__.call if @drawBlock__
|
1742
|
+
ensure
|
1743
|
+
pop
|
1744
|
+
@frameCount__ += 1
|
1745
|
+
end
|
1746
|
+
}
|
1747
|
+
|
1748
|
+
@window__.draw = proc do |e|
|
1749
|
+
if @loop__ || @redraw__
|
1750
|
+
@redraw__ = false
|
1751
|
+
drawFrame.call
|
1752
|
+
end
|
1753
|
+
@mousePrevPos__ = @mousePos__
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
updatePointerStates = -> event, pressed = nil {
|
1757
|
+
@mousePos__ = event.pos
|
1758
|
+
@mousePressed__ = pressed if pressed != nil
|
1759
|
+
@touches__ = event.positions.map {|pos| Touch.new pos.x, pos.y}
|
1760
|
+
}
|
1761
|
+
|
1762
|
+
@window__.pointer_down = proc do |e|
|
1763
|
+
updatePointerStates.call e, true
|
1764
|
+
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
1765
|
+
end
|
1766
|
+
|
1767
|
+
@window__.pointer_up = proc do |e|
|
1768
|
+
updatePointerStates.call e, false
|
1769
|
+
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
@window__.pointer_move = proc do |e|
|
1773
|
+
updatePointerStates.call e
|
1774
|
+
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
@window__.pointer_drag = proc do |e|
|
1778
|
+
updatePointerStates.call e
|
1779
|
+
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
1780
|
+
end
|
1082
1781
|
end
|
1083
1782
|
|
1084
|
-
#
|
1085
|
-
#
|
1086
|
-
# @param radian [Numeric] radian to convert
|
1087
|
-
#
|
1088
|
-
# @return [Numeric] degree
|
1783
|
+
# Define setup block.
|
1089
1784
|
#
|
1090
|
-
def
|
1091
|
-
|
1785
|
+
def setup (&block)
|
1786
|
+
@window__.setup = block
|
1787
|
+
nil
|
1092
1788
|
end
|
1093
1789
|
|
1094
|
-
#
|
1790
|
+
# Define draw block.
|
1095
1791
|
#
|
1096
|
-
|
1792
|
+
def draw (&block)
|
1793
|
+
@drawBlock__ = block if block
|
1794
|
+
nil
|
1795
|
+
end
|
1796
|
+
|
1797
|
+
def key (&block)
|
1798
|
+
@window__.key = block
|
1799
|
+
nil
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
def mousePressed (&block)
|
1803
|
+
@mousePressedBlock__ = block if block
|
1804
|
+
@mousePressed__
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
def mouseReleased (&block)
|
1808
|
+
@mouseReleasedBlock__ = block if block
|
1809
|
+
nil
|
1810
|
+
end
|
1811
|
+
|
1812
|
+
def mouseMoved (&block)
|
1813
|
+
@mouseMovedBlock__ = block if block
|
1814
|
+
nil
|
1815
|
+
end
|
1816
|
+
|
1817
|
+
def mouseDragged (&block)
|
1818
|
+
@mouseDraggedBlock__ = block if block
|
1819
|
+
nil
|
1820
|
+
end
|
1821
|
+
|
1822
|
+
def touchStarted (&block)
|
1823
|
+
@touchStartedBlock__ = block if block
|
1824
|
+
nil
|
1825
|
+
end
|
1826
|
+
|
1827
|
+
def touchEnded (&block)
|
1828
|
+
@touchEndedBlock__ = block if block
|
1829
|
+
nil
|
1830
|
+
end
|
1831
|
+
|
1832
|
+
def touchMoved (&block)
|
1833
|
+
@touchMovedBlock__ = block if block
|
1834
|
+
nil
|
1835
|
+
end
|
1836
|
+
|
1837
|
+
# @private
|
1838
|
+
private def size__ (width, height)
|
1839
|
+
raise 'size() must be called on startup or setup block' if @started__
|
1840
|
+
|
1841
|
+
@painter__.__send__ :end_paint
|
1842
|
+
@window__.__send__ :reset_canvas, width, height
|
1843
|
+
@painter__.__send__ :begin_paint
|
1844
|
+
|
1845
|
+
@auto_resize__ = false
|
1846
|
+
end
|
1847
|
+
|
1848
|
+
def windowWidth ()
|
1849
|
+
@window__.width
|
1850
|
+
end
|
1851
|
+
|
1852
|
+
def windowHeight ()
|
1853
|
+
@window__.height
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
# Returns number of frames since program started.
|
1097
1857
|
#
|
1098
|
-
# @return [
|
1858
|
+
# @return [Integer] total number of frames
|
1099
1859
|
#
|
1100
|
-
def
|
1101
|
-
|
1860
|
+
def frameCount ()
|
1861
|
+
@frameCount__
|
1102
1862
|
end
|
1103
1863
|
|
1104
|
-
# Returns
|
1105
|
-
#
|
1106
|
-
# @param value [Numeric] number
|
1864
|
+
# Returns number of frames per second.
|
1107
1865
|
#
|
1108
|
-
# @return [
|
1866
|
+
# @return [Float] frames per second
|
1109
1867
|
#
|
1110
|
-
def
|
1111
|
-
|
1868
|
+
def frameRate ()
|
1869
|
+
@window__.event.fps
|
1112
1870
|
end
|
1113
1871
|
|
1114
|
-
# Returns
|
1115
|
-
#
|
1116
|
-
# @param value [Numeric] number
|
1872
|
+
# Returns pixel density
|
1117
1873
|
#
|
1118
|
-
# @return [Numeric]
|
1874
|
+
# @return [Numeric] pixel density
|
1119
1875
|
#
|
1120
|
-
def
|
1121
|
-
|
1876
|
+
def displayDensity ()
|
1877
|
+
@painter__.pixel_density
|
1122
1878
|
end
|
1123
1879
|
|
1124
|
-
# Returns
|
1125
|
-
#
|
1126
|
-
# @param value [Numeric] number
|
1880
|
+
# Returns mouse x position
|
1127
1881
|
#
|
1128
|
-
# @return [Numeric]
|
1882
|
+
# @return [Numeric] horizontal position of mouse
|
1129
1883
|
#
|
1130
|
-
def
|
1131
|
-
|
1884
|
+
def mouseX ()
|
1885
|
+
@mousePos__.x
|
1132
1886
|
end
|
1133
1887
|
|
1134
|
-
# Returns
|
1135
|
-
#
|
1136
|
-
# @param value [Numeric] base number
|
1137
|
-
# @param exponent [Numeric] exponent number
|
1888
|
+
# Returns mouse y position
|
1138
1889
|
#
|
1139
|
-
# @return [Numeric]
|
1890
|
+
# @return [Numeric] vertical position of mouse
|
1140
1891
|
#
|
1141
|
-
def
|
1142
|
-
|
1892
|
+
def mouseY ()
|
1893
|
+
@mousePos__.y
|
1143
1894
|
end
|
1144
1895
|
|
1145
|
-
# Returns
|
1896
|
+
# Returns mouse x position in previous frame
|
1897
|
+
#
|
1898
|
+
# @return [Numeric] horizontal position of mouse
|
1899
|
+
#
|
1900
|
+
def pmouseX ()
|
1901
|
+
@mousePrevPos__.x
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
# Returns mouse y position in previous frame
|
1905
|
+
#
|
1906
|
+
# @return [Numeric] vertical position of mouse
|
1907
|
+
#
|
1908
|
+
def pmouseY ()
|
1909
|
+
@mousePrevPos__.y
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
# Returns array of touches
|
1913
|
+
#
|
1914
|
+
# @return [Array] Touch objects
|
1915
|
+
#
|
1916
|
+
def touches ()
|
1917
|
+
@touches__
|
1918
|
+
end
|
1919
|
+
|
1920
|
+
# Enables calling draw block on every frame.
|
1921
|
+
#
|
1922
|
+
# @return [nil] nil
|
1923
|
+
#
|
1924
|
+
def loop ()
|
1925
|
+
@loop__ = true
|
1926
|
+
end
|
1927
|
+
|
1928
|
+
# Disables calling draw block on every frame.
|
1929
|
+
#
|
1930
|
+
# @return [nil] nil
|
1931
|
+
#
|
1932
|
+
def noLoop ()
|
1933
|
+
@loop__ = false
|
1934
|
+
end
|
1935
|
+
|
1936
|
+
# Calls draw block to redraw frame.
|
1937
|
+
#
|
1938
|
+
# @return [nil] nil
|
1939
|
+
#
|
1940
|
+
def redraw ()
|
1941
|
+
@redraw__ = true
|
1942
|
+
end
|
1943
|
+
|
1944
|
+
#
|
1945
|
+
# Utilities
|
1946
|
+
#
|
1947
|
+
|
1948
|
+
# Returns the absolute number of the value.
|
1949
|
+
#
|
1950
|
+
# @param value [Numeric] number
|
1951
|
+
#
|
1952
|
+
# @return [Numeric] absolute number
|
1953
|
+
#
|
1954
|
+
def abs (value)
|
1955
|
+
value.abs
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
# Returns the closest integer number greater than or equal to the value.
|
1959
|
+
#
|
1960
|
+
# @param value [Numeric] number
|
1961
|
+
#
|
1962
|
+
# @return [Numeric] rounded up number
|
1963
|
+
#
|
1964
|
+
def ceil (value)
|
1965
|
+
value.ceil
|
1966
|
+
end
|
1967
|
+
|
1968
|
+
# Returns the closest integer number less than or equal to the value.
|
1969
|
+
#
|
1970
|
+
# @param value [Numeric] number
|
1971
|
+
#
|
1972
|
+
# @return [Numeric] rounded down number
|
1973
|
+
#
|
1974
|
+
def floor (value)
|
1975
|
+
value.floor
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
# Returns the closest integer number.
|
1979
|
+
#
|
1980
|
+
# @param value [Numeric] number
|
1981
|
+
#
|
1982
|
+
# @return [Numeric] rounded number
|
1983
|
+
#
|
1984
|
+
def round (value)
|
1985
|
+
value.round
|
1986
|
+
end
|
1987
|
+
|
1988
|
+
# Returns the natural logarithm (the base-e logarithm) of a number.
|
1989
|
+
#
|
1990
|
+
# @param value [Numeric] number (> 0.0)
|
1991
|
+
#
|
1992
|
+
# @return [Numeric] result number
|
1993
|
+
#
|
1994
|
+
def log (n)
|
1995
|
+
Math.log n
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
# Returns Euler's number e raised to the power of value.
|
1999
|
+
#
|
2000
|
+
# @param value [Numeric] number
|
2001
|
+
#
|
2002
|
+
# @return [Numeric] result number
|
2003
|
+
#
|
2004
|
+
def exp (n)
|
2005
|
+
Math.exp n
|
2006
|
+
end
|
2007
|
+
|
2008
|
+
# Returns value raised to the power of exponent.
|
2009
|
+
#
|
2010
|
+
# @param value [Numeric] base number
|
2011
|
+
# @param exponent [Numeric] exponent number
|
2012
|
+
#
|
2013
|
+
# @return [Numeric] value ** exponent
|
2014
|
+
#
|
2015
|
+
def pow (value, exponent)
|
2016
|
+
value ** exponent
|
2017
|
+
end
|
2018
|
+
|
2019
|
+
# Returns squared value.
|
1146
2020
|
#
|
1147
2021
|
# @param value [Numeric] number
|
1148
2022
|
#
|
@@ -1152,6 +2026,16 @@ module RubySketch
|
|
1152
2026
|
value * value
|
1153
2027
|
end
|
1154
2028
|
|
2029
|
+
# Returns squared value.
|
2030
|
+
#
|
2031
|
+
# @param value [Numeric] number
|
2032
|
+
#
|
2033
|
+
# @return [Numeric] squared value
|
2034
|
+
#
|
2035
|
+
def sqrt (value)
|
2036
|
+
Math.sqrt value
|
2037
|
+
end
|
2038
|
+
|
1155
2039
|
# Returns the magnitude (or length) of a vector.
|
1156
2040
|
#
|
1157
2041
|
# @overload mag(x, y)
|
@@ -1284,292 +2168,199 @@ module RubySketch
|
|
1284
2168
|
value < min ? min : (value > max ? max : value)
|
1285
2169
|
end
|
1286
2170
|
|
1287
|
-
#
|
1288
|
-
#
|
1289
|
-
# @overload noise(x)
|
1290
|
-
# @overload noise(x, y)
|
1291
|
-
# @overload noise(x, y, z)
|
2171
|
+
# Converts degree to radian.
|
1292
2172
|
#
|
1293
|
-
# @param
|
1294
|
-
# @param y [Numeric] vertical point in noise space
|
1295
|
-
# @param z [Numeric] depth point in noise space
|
2173
|
+
# @param degree [Numeric] degree to convert
|
1296
2174
|
#
|
1297
|
-
# @return [Numeric]
|
2175
|
+
# @return [Numeric] radian
|
1298
2176
|
#
|
1299
|
-
def
|
1300
|
-
|
2177
|
+
def radians (degree)
|
2178
|
+
degree * DEG2RAD__
|
1301
2179
|
end
|
1302
2180
|
|
1303
|
-
#
|
2181
|
+
# Converts radian to degree.
|
1304
2182
|
#
|
1305
|
-
# @param
|
1306
|
-
# @param extension [String] type of image to load (ex. 'png')
|
2183
|
+
# @param radian [Numeric] radian to convert
|
1307
2184
|
#
|
1308
|
-
# @return [
|
2185
|
+
# @return [Numeric] degree
|
1309
2186
|
#
|
1310
|
-
def
|
1311
|
-
|
1312
|
-
Image.new Rays::Image.load filename
|
1313
|
-
end
|
1314
|
-
|
1315
|
-
# @private
|
1316
|
-
private def getImage__ (uri, ext)
|
1317
|
-
ext ||= File.extname uri
|
1318
|
-
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png)$/i
|
1319
|
-
|
1320
|
-
tmpdir = Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name)
|
1321
|
-
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
1322
|
-
path = path.sub_ext ext
|
1323
|
-
|
1324
|
-
unless path.file?
|
1325
|
-
URI.open uri do |input|
|
1326
|
-
tmpdir.mkdir unless tmpdir.directory?
|
1327
|
-
path.open('w') do |output|
|
1328
|
-
while buf = input.read(2 ** 16)
|
1329
|
-
output.write buf
|
1330
|
-
end
|
1331
|
-
end
|
1332
|
-
end
|
1333
|
-
end
|
1334
|
-
path.to_s
|
1335
|
-
end
|
1336
|
-
|
1337
|
-
def createGraphics (width, height)
|
1338
|
-
Graphics.new width, height
|
1339
|
-
end
|
1340
|
-
|
1341
|
-
end# Utility
|
1342
|
-
|
1343
|
-
|
1344
|
-
# Processing context
|
1345
|
-
#
|
1346
|
-
module Context
|
1347
|
-
|
1348
|
-
include GraphicsContext, Utility, Math
|
1349
|
-
|
1350
|
-
# @private
|
1351
|
-
def setup__ (window)
|
1352
|
-
@window__ = window
|
1353
|
-
@image__ = @window__.canvas
|
1354
|
-
super @window__.canvas_painter.paint {background 0.8}
|
1355
|
-
|
1356
|
-
@loop__ = true
|
1357
|
-
@redraw__ = false
|
1358
|
-
@frameCount__ = 0
|
1359
|
-
@mousePos__ =
|
1360
|
-
@mousePrevPos__ = Rays::Point.new 0
|
1361
|
-
@mousePressed__ = false
|
1362
|
-
@touches__ = []
|
1363
|
-
|
1364
|
-
@window__.before_draw = proc {beginDraw}
|
1365
|
-
@window__.after_draw = proc {endDraw}
|
1366
|
-
|
1367
|
-
drawFrame = -> {
|
1368
|
-
@image__ = @window__.canvas
|
1369
|
-
@painter__ = @window__.canvas_painter
|
1370
|
-
begin
|
1371
|
-
push
|
1372
|
-
@drawBlock__.call if @drawBlock__
|
1373
|
-
ensure
|
1374
|
-
pop
|
1375
|
-
@frameCount__ += 1
|
1376
|
-
end
|
1377
|
-
}
|
1378
|
-
|
1379
|
-
@window__.draw = proc do |e|
|
1380
|
-
if @loop__ || @redraw__
|
1381
|
-
@redraw__ = false
|
1382
|
-
drawFrame.call
|
1383
|
-
end
|
1384
|
-
@mousePrevPos__ = @mousePos__
|
1385
|
-
end
|
1386
|
-
|
1387
|
-
updatePointerStates = -> event, pressed = nil {
|
1388
|
-
@mousePos__ = event.pos
|
1389
|
-
@mousePressed__ = pressed if pressed != nil
|
1390
|
-
@touches__ = event.positions.map {|pos| Touch.new pos.x, pos.y}
|
1391
|
-
}
|
1392
|
-
|
1393
|
-
@window__.pointer_down = proc do |e|
|
1394
|
-
updatePointerStates.call e, true
|
1395
|
-
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
1396
|
-
end
|
1397
|
-
|
1398
|
-
@window__.pointer_up = proc do |e|
|
1399
|
-
updatePointerStates.call e, false
|
1400
|
-
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
1401
|
-
end
|
1402
|
-
|
1403
|
-
@window__.pointer_move = proc do |e|
|
1404
|
-
updatePointerStates.call e
|
1405
|
-
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
1406
|
-
end
|
1407
|
-
|
1408
|
-
@window__.pointer_drag = proc do |e|
|
1409
|
-
updatePointerStates.call e
|
1410
|
-
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
1411
|
-
end
|
2187
|
+
def degrees (radian)
|
2188
|
+
radian * RAD2DEG__
|
1412
2189
|
end
|
1413
2190
|
|
1414
|
-
#
|
2191
|
+
# Returns the sine of an angle.
|
1415
2192
|
#
|
1416
|
-
|
1417
|
-
@window__.setup = block
|
1418
|
-
nil
|
1419
|
-
end
|
1420
|
-
|
1421
|
-
# Define draw block.
|
2193
|
+
# @param angle [Numeric] angle in radians
|
1422
2194
|
#
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
def key (&block)
|
1429
|
-
@window__.key = block
|
1430
|
-
nil
|
1431
|
-
end
|
1432
|
-
|
1433
|
-
def mousePressed (&block)
|
1434
|
-
@mousePressedBlock__ = block if block
|
1435
|
-
@mousePressed__
|
1436
|
-
end
|
1437
|
-
|
1438
|
-
def mouseReleased (&block)
|
1439
|
-
@mouseReleasedBlock__ = block if block
|
1440
|
-
nil
|
1441
|
-
end
|
1442
|
-
|
1443
|
-
def mouseMoved (&block)
|
1444
|
-
@mouseMovedBlock__ = block if block
|
1445
|
-
nil
|
1446
|
-
end
|
1447
|
-
|
1448
|
-
def mouseDragged (&block)
|
1449
|
-
@mouseDraggedBlock__ = block if block
|
1450
|
-
nil
|
1451
|
-
end
|
1452
|
-
|
1453
|
-
def touchStarted (&block)
|
1454
|
-
@touchStartedBlock__ = block if block
|
1455
|
-
nil
|
1456
|
-
end
|
1457
|
-
|
1458
|
-
def touchEnded (&block)
|
1459
|
-
@touchEndedBlock__ = block if block
|
1460
|
-
nil
|
1461
|
-
end
|
1462
|
-
|
1463
|
-
def touchMoved (&block)
|
1464
|
-
@touchMovedBlock__ = block if block
|
1465
|
-
nil
|
1466
|
-
end
|
1467
|
-
|
1468
|
-
# @private
|
1469
|
-
private def size__ (width, height)
|
1470
|
-
raise 'size() must be called on startup or setup block' if @started__
|
1471
|
-
|
1472
|
-
@painter__.__send__ :end_paint
|
1473
|
-
@window__.__send__ :reset_canvas, width, height
|
1474
|
-
@painter__.__send__ :begin_paint
|
1475
|
-
|
1476
|
-
@auto_resize__ = false
|
1477
|
-
end
|
1478
|
-
|
1479
|
-
def windowWidth ()
|
1480
|
-
@window__.width
|
2195
|
+
# @return [Numeric] the sine
|
2196
|
+
#
|
2197
|
+
def sin (angle)
|
2198
|
+
Math.sin angle
|
1481
2199
|
end
|
1482
2200
|
|
1483
|
-
|
1484
|
-
|
2201
|
+
# Returns the cosine of an angle.
|
2202
|
+
#
|
2203
|
+
# @param angle [Numeric] angle in radians
|
2204
|
+
#
|
2205
|
+
# @return [Numeric] the cosine
|
2206
|
+
#
|
2207
|
+
def cos (angle)
|
2208
|
+
Math.cos angle
|
1485
2209
|
end
|
1486
2210
|
|
1487
|
-
# Returns
|
2211
|
+
# Returns the ratio of the sine and cosine of an angle.
|
1488
2212
|
#
|
1489
|
-
# @
|
2213
|
+
# @param angle [Numeric] angle in radians
|
1490
2214
|
#
|
1491
|
-
|
1492
|
-
|
2215
|
+
# @return [Numeric] the tangent
|
2216
|
+
#
|
2217
|
+
def tan (angle)
|
2218
|
+
Math.tan angle
|
1493
2219
|
end
|
1494
2220
|
|
1495
|
-
# Returns
|
2221
|
+
# Returns the inverse of sin().
|
1496
2222
|
#
|
1497
|
-
# @
|
2223
|
+
# @param value [Numeric] value for calculation
|
1498
2224
|
#
|
1499
|
-
|
1500
|
-
|
2225
|
+
# @return [Numeric] the arc sine
|
2226
|
+
#
|
2227
|
+
def asin (value)
|
2228
|
+
Math.asin value
|
1501
2229
|
end
|
1502
2230
|
|
1503
|
-
# Returns
|
2231
|
+
# Returns the inverse of cos().
|
1504
2232
|
#
|
1505
|
-
# @
|
2233
|
+
# @param value [Numeric] value for calculation
|
1506
2234
|
#
|
1507
|
-
|
1508
|
-
|
2235
|
+
# @return [Numeric] the arc cosine
|
2236
|
+
#
|
2237
|
+
def acos (value)
|
2238
|
+
Math.acos value
|
1509
2239
|
end
|
1510
2240
|
|
1511
|
-
# Returns
|
2241
|
+
# Returns the inverse of tan().
|
1512
2242
|
#
|
1513
|
-
# @
|
2243
|
+
# @param value [Numeric] value for valculation
|
1514
2244
|
#
|
1515
|
-
|
1516
|
-
|
2245
|
+
# @return [Numeric] the arc tangent
|
2246
|
+
#
|
2247
|
+
def atan (value)
|
2248
|
+
Math.atan value
|
1517
2249
|
end
|
1518
2250
|
|
1519
|
-
# Returns
|
2251
|
+
# Returns the angle from a specified point.
|
1520
2252
|
#
|
1521
|
-
# @
|
2253
|
+
# @param y [Numeric] y of the point
|
2254
|
+
# @param x [Numeric] x of the point
|
1522
2255
|
#
|
1523
|
-
|
1524
|
-
|
2256
|
+
# @return [Numeric] the angle in radians
|
2257
|
+
#
|
2258
|
+
def atan2 (y, x)
|
2259
|
+
Math.atan2 y, x
|
1525
2260
|
end
|
1526
2261
|
|
1527
|
-
# Returns
|
2262
|
+
# Returns the perlin noise value.
|
1528
2263
|
#
|
1529
|
-
# @
|
2264
|
+
# @overload noise(x)
|
2265
|
+
# @overload noise(x, y)
|
2266
|
+
# @overload noise(x, y, z)
|
1530
2267
|
#
|
1531
|
-
|
1532
|
-
|
2268
|
+
# @param x [Numeric] horizontal point in noise space
|
2269
|
+
# @param y [Numeric] vertical point in noise space
|
2270
|
+
# @param z [Numeric] depth point in noise space
|
2271
|
+
#
|
2272
|
+
# @return [Numeric] noise value (0.0..1.0)
|
2273
|
+
#
|
2274
|
+
def noise (x, y = 0, z = 0)
|
2275
|
+
Rays.perlin(x, y, z) / 2.0 + 0.5
|
1533
2276
|
end
|
1534
2277
|
|
1535
|
-
# Returns
|
2278
|
+
# Returns a random number in range low...high
|
1536
2279
|
#
|
1537
|
-
# @
|
2280
|
+
# @overload random()
|
2281
|
+
# @overload random(high)
|
2282
|
+
# @overload random(low, high)
|
2283
|
+
# @overload random(choices)
|
1538
2284
|
#
|
1539
|
-
|
1540
|
-
|
2285
|
+
# @param low [Numeric] lower limit
|
2286
|
+
# @param high [Numeric] upper limit
|
2287
|
+
# @param choices [Array] array to choose from
|
2288
|
+
#
|
2289
|
+
# @return [Float] random number
|
2290
|
+
#
|
2291
|
+
def random (*args)
|
2292
|
+
return args.first.sample if args.first.kind_of? Array
|
2293
|
+
high, low = args.reverse
|
2294
|
+
rand (low || 0).to_f...(high || 1).to_f
|
1541
2295
|
end
|
1542
2296
|
|
1543
|
-
#
|
2297
|
+
# Creates a new vector.
|
1544
2298
|
#
|
1545
|
-
# @
|
2299
|
+
# @overload createVector()
|
2300
|
+
# @overload createVector(x, y)
|
2301
|
+
# @overload createVector(x, y, z)
|
1546
2302
|
#
|
1547
|
-
|
1548
|
-
|
2303
|
+
# @param x [Numeric] x of new vector
|
2304
|
+
# @param y [Numeric] y of new vector
|
2305
|
+
# @param z [Numeric] z of new vector
|
2306
|
+
#
|
2307
|
+
# @return [Vector] new vector
|
2308
|
+
#
|
2309
|
+
def createVector (*args)
|
2310
|
+
Vector.new *args
|
1549
2311
|
end
|
1550
2312
|
|
1551
|
-
#
|
2313
|
+
# Creates a camera object as a video input device.
|
1552
2314
|
#
|
1553
|
-
# @return [
|
2315
|
+
# @return [Capture] camera object
|
1554
2316
|
#
|
1555
|
-
def
|
1556
|
-
|
2317
|
+
def createCapture (*args)
|
2318
|
+
Capture.new *args
|
1557
2319
|
end
|
1558
2320
|
|
1559
|
-
#
|
2321
|
+
# Creates a new off-screen graphics context object.
|
1560
2322
|
#
|
1561
|
-
# @
|
2323
|
+
# @param width [Numeric] width of graphics image
|
2324
|
+
# @param height [Numeric] height of graphics image
|
1562
2325
|
#
|
1563
|
-
|
1564
|
-
|
2326
|
+
# @return [Graphics] graphics object
|
2327
|
+
#
|
2328
|
+
def createGraphics (width, height)
|
2329
|
+
Graphics.new width, height
|
1565
2330
|
end
|
1566
2331
|
|
1567
|
-
#
|
2332
|
+
# Loads image.
|
1568
2333
|
#
|
1569
|
-
# @
|
2334
|
+
# @param filename [String] file name to load image
|
2335
|
+
# @param extension [String] type of image to load (ex. 'png')
|
1570
2336
|
#
|
1571
|
-
|
1572
|
-
|
2337
|
+
# @return [Image] loaded image object
|
2338
|
+
#
|
2339
|
+
def loadImage (filename, extension = nil)
|
2340
|
+
filename = getImage__ filename, extension if filename =~ %r|^https?://|
|
2341
|
+
Image.new Rays::Image.load filename
|
2342
|
+
end
|
2343
|
+
|
2344
|
+
# @private
|
2345
|
+
private def getImage__ (uri, ext)
|
2346
|
+
ext ||= File.extname uri
|
2347
|
+
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png)$/i
|
2348
|
+
|
2349
|
+
tmpdir = Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name)
|
2350
|
+
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
2351
|
+
path = path.sub_ext ext
|
2352
|
+
|
2353
|
+
unless path.file?
|
2354
|
+
URI.open uri do |input|
|
2355
|
+
tmpdir.mkdir unless tmpdir.directory?
|
2356
|
+
path.open('w') do |output|
|
2357
|
+
while buf = input.read(2 ** 16)
|
2358
|
+
output.write buf
|
2359
|
+
end
|
2360
|
+
end
|
2361
|
+
end
|
2362
|
+
end
|
2363
|
+
path.to_s
|
1573
2364
|
end
|
1574
2365
|
|
1575
2366
|
end# Context
|