UNPKG

js-2dmath

Version:

Fast 2d geometry math: Vector2, Rectangle, Circle, Matrix2x3 (2D transformation), Circle, BoundingBox, Line2, Segment2, Intersections, Distances, Transitions (animation/tween), Random numbers, Noise

183 lines (169 loc) 4.59 kB
/** * Stability: 1 (Only additions & fixes) * * @reference http://pomax.github.io/bezierinfo/ * @reference https://github.com/jackcviers/Degrafa/blob/master/Degrafa/com/degrafa/geometry/utilities/BezierUtils.as * @reference http://cagd.cs.byu.edu/~557/text/ch7.pdf * @reference http://algorithmist.wordpress.com/2009/02/02/degrafa-closest-point-on-quad-bezier/ * @reference http://algorithmist.wordpress.com/2009/01/26/degrafa-bezierutils-class/ */ var sqrt = Math.sqrt, cl0 = 0, cl1 = 0, cl2 = 0, cl3 = 0, t1 = 0, t2 = 0, t3 = 0; /** * cp0 - start point * cp1 - start control point * cp2 - end control point * cp3 - end point * * @param {Number} cp0x * @param {Number} cp0y * @param {Number} cp1x * @param {Number} cp1y * @param {Number} cp2x * @param {Number} cp2y * @param {Number} cp3x * @param {Number} cp3y * @return {Beizer} */ function cubic(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y) { return [[cp0x, cp0y], [cp1x, cp1y], [cp2x, cp2y], [cp3x, cp3y]]; } /** * For implementation see Figure 21.2 * @reference http://pomax.github.io/bezierinfo/ * @todo DO IT! * * @param {Number} cp0x * @param {Number} cp0y * @param {Number} cp1x * @param {Number} cp1y * @param {Number} cp2x * @param {Number} cp2y * @return {Beizer} */ function from3Points(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y) { } /** * @param {Number} cp0x * @param {Number} cp0y * @param {Number} cp1x * @param {Number} cp1y * @param {Number} cp2x * @param {Number} cp2y * @return {Beizer} */ function quadric(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y) { return [[cp0x, cp0y], [cp1x, cp1y], [cp2x, cp2y]]; } /** * For implementation see Figure 21.1 * @reference http://pomax.github.io/bezierinfo/ * @param {Number} cp0x * @param {Number} cp0y * @param {Number} cp1x * @param {Number} cp1y * @param {Number} cp2x * @param {Number} cp2y */ function quadricFrom3Points(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y) { } /** * Solves the curve (quadric or cubic) for any given parameter t. * @source https://github.com/hyperandroid/CAAT/blob/master/src/Math/Bezier.js * @param {Vec2} out_vec2 * @param {Beizer} curve * @param {Number} t [0-1] * @return {Vec2} */ function solve(out_vec2, curve, t) { if (curve.length === 4) { //cubic t2 = t * t; t3 = t * t2; cl0 = curve[0]; cl1 = curve[1]; cl2 = curve[2]; cl3 = curve[3]; out_vec2[0] = (cl0[0] + t * (-cl0[0] * 3 + t * (3 * cl0[0] - cl0[0] * t))) + t * (3 * cl1[0] + t * (-6 * cl1[0] + cl1[0] * 3 * t)) + t2 * (cl2[0] * 3 - cl2[0] * 3 * t) + cl3[0] * t3; out_vec2[1] = (cl0[1] + t * (-cl0[1] * 3 + t * (3 * cl0[1] - cl0[1] * t))) + t * (3 * cl1[1] + t * (-6 * cl1[1] + cl1[1] * 3 * t)) + t2 * (cl2[1] * 3 - cl2[1] * 3 * t) + cl3[1] * t3; } else { // quadric cl0 = curve[0]; cl1 = curve[1]; cl2 = curve[2]; t1 = 1 - t; out_vec2[0] = t1 * t1 * cl0[0] + 2 * t1 * t * cl1[0] + t * t * cl2[0]; out_vec2[1] = t1 * t1 * cl0[1] + 2 * t1 * t * cl1[1] + t * t * cl2[1]; } return out_vec2; } /** * Solve the curve npoints times and return the solution array. * * @see Polygon.fromBeizer * * @param {Beizer} curve * @param {Number} npoints * @return {Vec2[]} */ function getPoints(curve, npoints) { var inv_npoints = 1 / npoints, i, output = [], vec2; for (i = 0; i <= 1; i += inv_npoints) { vec2 = [0, 0]; output.push(solve(vec2, curve, i)); } return output; } /** * Calculate the curve length by incrementally solving the curve every substep=CAAT.Curve.k. This value defaults * to .05 so at least 20 iterations will be performed. * @todo some kind of cache maybe it's needed! * @param {Beizer} curve * @param {Number} step * @return {Number} the approximate curve length. */ function length(curve, step) { step = step || 0.05; var x1, y1, llength = 0, pt = [0, 0], t; x1 = curve[0][0]; y1 = curve[0][1]; for (t = step; t <= 1 + step; t += step) { solve(pt, curve, t); llength += sqrt((pt[0] - x1) * (pt[0] - x1) + (pt[1] - y1) * (pt[1] - y1)); x1 = pt[0]; y1 = pt[1]; } return llength; } /** * credits - CAAT * * @class Beizer */ var Beizer = { cubic: cubic, quadric: quadric, solve: solve, length: length, getPoints: getPoints }; module.exports = Beizer;