-
Notifications
You must be signed in to change notification settings - Fork 9
Vec2D, Vec3D, ArcBall and Deglut classes
The following are build into JRubyArt as jruby extensions
The main purpose of the built Vec2D and Vec3D classes is to provide a more rubified version of the processing PVector class. The PVector class tries to do too much and is used for both 2D and 3D vector work, further it has confusing assortment of static (class) and object methods.
Valid Operations with Vec2D and Vec3D:-
# creating a new vector
a = b * c # a is the new vector b is the original vector and c is a scalar
# assignment form
a *= c # a is the original vector, and c is a scalar
# creating a new vector
a = b / c # where a is new vector b is the original and c is a scalar
# assignment form
a /= c # a is the original vector, and c is a scalar
# creating a new vector
a = b + c # where a is new vector b and c are both vectors
# assignment form
a += c # where a is the original vector and c is a vector
# creating a new vector
a = b - c # where a is new vector b and c are both vectors
# assignment form
a -= c # where a is the original vector and c is a vector
Otherwise most operations are very similar to PVector excepting normalize!, that should be used to normalize the current vector, whereas the 'bare' normalize does not change the original (it returns a normalized copy the original vector). The above operations are more in keeping with ruby syntax, and lend themselves to the creation of more functional code, such as the following:-
# where a is an object of the Vec2D equal to the sum of an array Vec2D
a = array_of_vec2d.inject(Vec2D.new){|c, d| c + d}
# this short form option can also be used for simple cases (as above)
a = array_of_vec2d.inject(Vec2D.new, :+)
PVector has a limit function, which sets magnitude to a max value conditionally, both Vec2D and Vec3D use set_mag with an optional block, since version 2.4.4, that evaluates to a boolean to achieve the same outcome eg
# where MAX_SPEED is a scalar, and speed is a Vec2D or Vec3D object
speed.set_mag(MAX_SPEED){speed.mag > MAX_SPEED}
# NB: under the hood an efficient hypot function is used for mag
There is even a possiblity to write the Vec3D and Vec2D directly as processing vertices:-
begin_shape # Vec2D example
no_fill
stroke(255)
morph.each do |v|
v.to_vertex(renderer)
end
end_shape(CLOSE)
Where the renderer implements the Render interface, in this case the AppRender which achieves the same result as the following:-
begin_shape # Vec2D example
no_fill
stroke(255)
morph.each do |v|
vertex(v.x, v.y)
end
end_shape(CLOSE)
Initially designed as a convenience function, but it may also be more efficient (less ruby to java conversion). Currently the other implentation of the Render interface is the ShapeRender (but why not to povray obj etc in future). For advanced usage of ShapeRender see trefoil sketch, extract below, where the 'normals' n0, n1 and n2 are all instance of Vec3D as are the 'points' p0, p1 and p2:-
# Triangle p0-p2-p1
n0.to_normal(renderer)
(p0 * s).to_vertex_uv(renderer, u0, v0)
n2.to_normal(renderer)
(p2 * s).to_vertex_uv(renderer, u1, v1)
n1.to_normal(renderer)
(p1 * s).to_vertex_uv(renderer, u1, v0)
Also included is a DEGLUT sin/cos lookup table see clock.rb, and ArcBall functionality see arcball_box.rb