Published
Edited
Jul 16, 2019
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
a = vec2.create()
Insert cell
Insert cell
b = vec2create()
Insert cell
Insert cell
vec2 = ({
EPSILON,
create: vec2create,
clone: vec2clone,
fromValues: vec2fromValues,
copy: vec2copy,
set: vec2set,
equals: vec2equals,
exactEquals: vec2exactEquals,
add: vec2add,
subtract: vec2subtract,
sub: vec2sub,
multiply: vec2multiply,
mul: vec2mul,
divide: vec2divide,
div: vec2div,
inverse: vec2inverse,
min: vec2min,
max: vec2max,
rotate: vec2rotate,
floor: vec2floor,
ceil: vec2ceil,
round: vec2round,
scale: vec2scale,
scaleAndAdd: vec2scaleAndAdd,
distance: vec2distance,
dist: vec2dist,
squaredDistance: vec2squaredDistance,
sqrDist: vec2sqrDist,
length: vec2length,
len: vec2len,
squaredLength: vec2squaredLength,
sqrLen: vec2sqrLen,
negate: vec2negate,
normalize: vec2normalize,
dot: vec2dot,
cross: vec2cross,
lerp: vec2lerp,
random: vec2random,
transformMat2: vec2transformMat2,
transformMat2d: vec2transformMat2d,
transformMat3: vec2transformMat3,
transformMat4: vec2transformMat4,
forEach: vec2forEach,
limit: vec2limit,
})
Insert cell
EPSILON = 0.000001
Insert cell
/**
* Adds two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
function vec2add(out, a, b) {
out[0] = a[0] + b[0]
out[1] = a[1] + b[1]
return out
}
Insert cell
/**
* Math.ceil the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to ceil
* @returns {vec2} out
*/
function vec2ceil(out, a) {
out[0] = Math.ceil(a[0])
out[1] = Math.ceil(a[1])
return out
}
Insert cell
/**
* Creates a new vec2 initialized with values from an existing vector
*
* @param {vec2} a vector to clone
* @returns {vec2} a new 2D vector
*/
function vec2clone(a) {
var out = new Float32Array(2)
out[0] = a[0]
out[1] = a[1]
return out
}
Insert cell
/**
* Copy the values from one vec2 to another
*
* @param {vec2} out the receiving vector
* @param {vec2} a the source vector
* @returns {vec2} out
*/
function vec2copy(out, a) {
out[0] = a[0]
out[1] = a[1]
return out
}
Insert cell
/**
* Creates a new, empty vec2
*
* @returns {vec2} a new 2D vector
*/
function vec2create() {
var out = new Float32Array(2)
out[0] = 0
out[1] = 0
return out
}
Insert cell
/**
* Computes the cross product of two vec2's
* Note that the cross product must by definition produce a 3D vector
*
* @param {vec3} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec3} out
*/
function vec2cross(out, a, b) {
var z = a[0] * b[1] - a[1] * b[0]
out[0] = out[1] = 0
out[2] = z
return out
}
Insert cell
/**
* Calculates the euclidian distance between two vec2's
*
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {Number} distance between a and b
*/
function vec2distance(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1]
return Math.sqrt(x*x + y*y)
}
Insert cell
vec2dist = vec2distance
Insert cell
/**
* Divides two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
function vec2divide(out, a, b) {
out[0] = a[0] / b[0]
out[1] = a[1] / b[1]
return out
}
Insert cell
vec2div = vec2divide
Insert cell
/**
* Calculates the dot product of two vec2's
*
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {Number} dot product of a and b
*/
function vec2dot(a, b) {
return a[0] * b[0] + a[1] * b[1]
}
Insert cell
/**
* Returns whether or not the vectors have approximately the same elements in the same position.
*
* @param {vec2} a The first vector.
* @param {vec2} b The second vector.
* @returns {Boolean} True if the vectors are equal, false otherwise.
*/
function vec2equals(a, b) {
var a0 = a[0]
var a1 = a[1]
var b0 = b[0]
var b1 = b[1]
return (Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) &&
Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)))
}
Insert cell
/**
* Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)
*
* @param {vec2} a The first vector.
* @param {vec2} b The second vector.
* @returns {Boolean} True if the vectors are equal, false otherwise.
*/
function vec2exactEquals(a, b) {
return a[0] === b[0] && a[1] === b[1]
}
Insert cell
/**
* Math.floor the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to floor
* @returns {vec2} out
*/
function vec2floor(out, a) {
out[0] = Math.floor(a[0])
out[1] = Math.floor(a[1])
return out
}
Insert cell
/**
* Perform some operation over an array of vec2s.
*
* @param {Array} a the array of vectors to iterate over
* @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
* @param {Number} offset Number of elements to skip at the beginning of the array
* @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
* @param {Function} fn Function to call for each vector in the array
* @param {Object} [arg] additional argument to pass to fn
* @returns {Array} a
* @function
*/
vec2forEach = {
let vec = vec2create();
return function forEach(a, stride, offset, count, fn, arg) {
var i, l
if(!stride) {
stride = 2
}

if(!offset) {
offset = 0
}

if(count) {
l = Math.min((count * stride) + offset, a.length)
} else {
l = a.length
}

for(i = offset; i < l; i += stride) {
vec[0] = a[i]
vec[1] = a[i+1]
fn(vec, vec, arg)
a[i] = vec[0]
a[i+1] = vec[1]
}

return a
}
}
Insert cell
/**
* Creates a new vec2 initialized with the given values
*
* @param {Number} x X component
* @param {Number} y Y component
* @returns {vec2} a new 2D vector
*/
function vec2fromValues(x, y) {
var out = new Float32Array(2)
out[0] = x
out[1] = y
return out
}
Insert cell
/**
* Returns the inverse of the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to invert
* @returns {vec2} out
*/
function vec2inverse(out, a) {
out[0] = 1.0 / a[0]
out[1] = 1.0 / a[1]
return out
}
Insert cell
/**
* Calculates the length of a vec2
*
* @param {vec2} a vector to calculate length of
* @returns {Number} length of a
*/
function vec2length(a) {
var x = a[0],
y = a[1]
return Math.sqrt(x*x + y*y)
}
Insert cell
vec2len = vec2length
Insert cell
/**
* Performs a linear interpolation between two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @param {Number} t interpolation amount between the two inputs
* @returns {vec2} out
*/
function vec2lerp(out, a, b, t) {
var ax = a[0],
ay = a[1]
out[0] = ax + t * (b[0] - ax)
out[1] = ay + t * (b[1] - ay)
return out
}
Insert cell
/**
* Limit the magnitude of this vector to the value used for the `max`
* parameter.
*
* @param {vec2} the vector to limit
* @param {Number} max the maximum magnitude for the vector
* @returns {vec2} out
*/
function vec2limit(out, a, max) {
var mSq = a[0] * a[0] + a[1] * a[1];

if (mSq > max * max) {
var n = Math.sqrt(mSq);
out[0] = a[0] / n * max;
out[1] = a[1] / n * max;
} else {
out[0] = a[0];
out[1] = a[1];
}

return out;
}
Insert cell
/**
* Returns the maximum of two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
function vec2max(out, a, b) {
out[0] = Math.max(a[0], b[0])
out[1] = Math.max(a[1], b[1])
return out
}
Insert cell
/**
* Returns the minimum of two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
function vec2min(out, a, b) {
out[0] = Math.min(a[0], b[0])
out[1] = Math.min(a[1], b[1])
return out
}
Insert cell
/**
* Multiplies two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
function vec2multiply(out, a, b) {
out[0] = a[0] * b[0]
out[1] = a[1] * b[1]
return out
}
Insert cell
vec2mul = vec2multiply
Insert cell
/**
* Negates the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to negate
* @returns {vec2} out
*/
function vec2negate(out, a) {
out[0] = -a[0]
out[1] = -a[1]
return out
}
Insert cell
/**
* Normalize a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to normalize
* @returns {vec2} out
*/
function vec2normalize(out, a) {
var x = a[0],
y = a[1]
var len = x*x + y*y
if (len > 0) {
//TODO: evaluate use of glm_invsqrt here?
len = 1 / Math.sqrt(len)
out[0] = a[0] * len
out[1] = a[1] * len
}
return out
}
Insert cell
/**
* Generates a random vector with the given scale
*
* @param {vec2} out the receiving vector
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
* @returns {vec2} out
*/
function vec2random(out, scale) {
scale = scale || 1.0
var r = Math.random() * 2.0 * Math.PI
out[0] = Math.cos(r) * scale
out[1] = Math.sin(r) * scale
return out
}
Insert cell
/**
* Rotates a vec2 by an angle
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to rotate
* @param {Number} angle the angle of rotation (in radians)
* @returns {vec2} out
*/
function vec2rotate(out, a, angle) {
var c = Math.cos(angle),
s = Math.sin(angle)
var x = a[0],
y = a[1]

out[0] = x * c - y * s
out[1] = x * s + y * c

return out
}
Insert cell
/**
* Math.round the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to round
* @returns {vec2} out
*/
function vec2round(out, a) {
out[0] = Math.round(a[0])
out[1] = Math.round(a[1])
return out
}
Insert cell
/**
* Scales a vec2 by a scalar number
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to scale
* @param {Number} b amount to scale the vector by
* @returns {vec2} out
*/
function vec2scale(out, a, b) {
out[0] = a[0] * b
out[1] = a[1] * b
return out
}
Insert cell
/**
* Adds two vec2's after scaling the second operand by a scalar value
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @param {Number} scale the amount to scale b by before adding
* @returns {vec2} out
*/
function vec2scaleAndAdd(out, a, b, scale) {
out[0] = a[0] + (b[0] * scale)
out[1] = a[1] + (b[1] * scale)
return out
}
Insert cell
/**
* Set the components of a vec2 to the given values
*
* @param {vec2} out the receiving vector
* @param {Number} x X component
* @param {Number} y Y component
* @returns {vec2} out
*/
function vec2set(out, x, y) {
out[0] = x
out[1] = y
return out
}
Insert cell
/**
* Calculates the squared euclidian distance between two vec2's
*
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {Number} squared distance between a and b
*/
function vec2squaredDistance(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1]
return x*x + y*y
}
Insert cell
vec2sqrDist = vec2squaredDistance
Insert cell
/**
* Calculates the squared length of a vec2
*
* @param {vec2} a vector to calculate squared length of
* @returns {Number} squared length of a
*/
function vec2squaredLength(a) {
var x = a[0],
y = a[1]
return x*x + y*y
}
Insert cell
vec2sqrLen = vec2squaredLength
Insert cell
/**
* Subtracts vector b from vector a
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
function vec2subtract(out, a, b) {
out[0] = a[0] - b[0]
out[1] = a[1] - b[1]
return out
}
Insert cell
vec2sub = vec2subtract
Insert cell
/**
* Transforms the vec2 with a mat2
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat2} m matrix to transform with
* @returns {vec2} out
*/
function vec2transformMat2(out, a, m) {
var x = a[0],
y = a[1]
out[0] = m[0] * x + m[2] * y
out[1] = m[1] * x + m[3] * y
return out
}
Insert cell
/**
* Transforms the vec2 with a mat2d
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat2d} m matrix to transform with
* @returns {vec2} out
*/
function vec2transformMat2d(out, a, m) {
var x = a[0],
y = a[1]
out[0] = m[0] * x + m[2] * y + m[4]
out[1] = m[1] * x + m[3] * y + m[5]
return out
}
Insert cell
/**
* Transforms the vec2 with a mat3
* 3rd vector component is implicitly '1'
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat3} m matrix to transform with
* @returns {vec2} out
*/
function vec2transformMat3(out, a, m) {
var x = a[0],
y = a[1]
out[0] = m[0] * x + m[3] * y + m[6]
out[1] = m[1] * x + m[4] * y + m[7]
return out
}
Insert cell
/**
* Transforms the vec2 with a mat4
* 3rd vector component is implicitly '0'
* 4th vector component is implicitly '1'
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat4} m matrix to transform with
* @returns {vec2} out
*/
function vec2transformMat4(out, a, m) {
var x = a[0],
y = a[1]
out[0] = m[0] * x + m[4] * y + m[12]
out[1] = m[1] * x + m[5] * y + m[13]
return out
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more