Skip to content

Commit 4e52ea2

Browse files
committed
refactor rotate
1 parent 7117367 commit 4e52ea2

File tree

2 files changed

+25
-33
lines changed

2 files changed

+25
-33
lines changed

contributed/library/branch3D/branch3D.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ def run
4040
def grow
4141
check_bounds(position + (dir * speed))
4242
@position += (dir * speed)
43-
Rotate.rotate_x!(dir, rand(-0.5..0.5) * THETA)
44-
Rotate.rotate_y!(dir, rand(-0.5..0.5) * THETA)
45-
Rotate.rotate_z!(dir, rand(-0.5..0.5) * THETA)
43+
(0..2).each do |axis|
44+
Rotate.axis!(axis, dir, rand(-0.5..0.5) * THETA)
45+
end
4646
path << position
4747
if (length < MAX_GEN) && (rand < BRANCH_CHANCE)
4848
branch_dir = dir.copy
49-
Rotate.rotate_x!(branch_dir, rand(-0.5..0.5) * BRANCH_THETA)
50-
Rotate.rotate_y!(branch_dir, rand(-0.5..0.5) * BRANCH_THETA)
51-
Rotate.rotate_z!(branch_dir, rand(-0.5..0.5) * BRANCH_THETA)
49+
(0..2).each do |axis|
50+
Rotate.axis!(axis, branch_dir, rand(-0.5..0.5) * BRANCH_THETA)
51+
end
5252
self << Branch.new(app, position.copy, branch_dir, speed * 0.99)
5353
end
5454
each(&:grow)
Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
1-
# Rotator module is required because rotate is not implemented for PiCrate
2-
# Vec3D (below implementation based on Euler angles)
3-
# NB: we use quaternions in ArcBall (avoiding possible gimbal lock)
1+
# Rotator module is required because rotate is not implemented for
2+
# PiCrate 3D. Here we use Vec2D.rotate! to do Euclid rotation about an
3+
# axis (we can then apply the rotation to each axis in turn)
4+
# NB: we use quaternions in ArcBall (to avoid gimbal lock)
45
module Rotate
5-
def self.rotate_x!(vec, theta)
6-
co = Math.cos(theta)
7-
si = Math.sin(theta)
8-
zz = co * vec.z - si * vec.y
9-
vec.y = si * vec.z + co * vec.y
10-
vec.z = zz
11-
vec
12-
end
13-
14-
def self.rotate_y!(vec, theta)
15-
co = Math.cos(theta)
16-
si = Math.sin(theta)
17-
xx = co * vec.x - si * vec.z
18-
vec.z = si * vec.x + co * vec.z
19-
vec.x = xx
20-
vec
21-
end
22-
23-
def self.rotate_z!(vec, theta)
24-
co = Math.cos(theta)
25-
si = Math.sin(theta)
26-
xx = co * vec.x - si * vec.y
27-
vec.y = si * vec.x + co * vec.y
28-
vec.x = xx
6+
def self.axis!(axis, vec, theta)
7+
array = vec.to_a
8+
array.slice! axis
9+
other = Vec2D.new(*array).rotate! theta
10+
case axis
11+
when 0 # xaxis
12+
vec.y = other.x
13+
vec.z = other.y
14+
when 1 # yaxis
15+
vec.x = other.x
16+
vec.z = other.y
17+
else # zaxis, by default
18+
vec.x = other.x
19+
vec.y = other.y
20+
end
2921
vec
3022
end
3123
end

0 commit comments

Comments
 (0)