Skip to content

The vecmath library

Martin Prout edited this page Aug 1, 2014 · 56 revisions

This library now replaces the arcball library, so where previously you may have used load_library :arcball, you now need to load_library :vecmath. However the main purpose of this library is provide a more rubified version of the processing PVector class, that apart from not having a very ruby like interface, appears to be trying to do too much. PVector is designed to be used for both 2D and 3D vector work, the vecmath library separates out these concerns to two classes Vec2D and Vec3D. Theses classes provide most of the functionality of PVector, but in more ruby like manner. There is much less need to use clone/copy with Vec2D and Vec3D ( than use the unfathomable PVector get(), which is becoming copy() for processing-3.0 ) owing to the fact that most operations (including +, -, /, *) return a new instance (allows chaining). For the future it might be nice to extend the vecmath library to support rotational geometry (AABB mesh etc), already included is Quaternion class but this is currently only designed to support arcball manipulations. Worked examples of the vecmath library are included in samples/processing_app/library/vecmath folder.

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