From 21a9603fb5522467776409972be21a87964c244d Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Mon, 9 Jul 2012 16:56:43 -0700 Subject: Normalize HTML DOCTYPE Was lower-case. Now upper-case. Also fixed BOMs, trailing white-space, DOS line terminators. Did not expand tabs to spaces. --- node_modules/montage/ui/flow-bezier-spline.js | 904 +++++++++++++------------- 1 file changed, 452 insertions(+), 452 deletions(-) (limited to 'node_modules/montage/ui/flow-bezier-spline.js') diff --git a/node_modules/montage/ui/flow-bezier-spline.js b/node_modules/montage/ui/flow-bezier-spline.js index 3475be8b..ce441d90 100755 --- a/node_modules/montage/ui/flow-bezier-spline.js +++ b/node_modules/montage/ui/flow-bezier-spline.js @@ -1,452 +1,452 @@ -var Montage = require("montage").Montage, - FlowBezierSpline = exports.FlowBezierSpline = Montage.create(Montage, { - - init: { - value: function() { - this._densities = []; - this._densitySummation = []; - return this; - } - }, - - knots: { - get: function () { - if (!this._knots) { - this._knots = []; - } - return this._knots; - }, - set: function (value) { - this._knots = value; - } - }, - - previousHandlers: { - get: function () { - if (!this._previousHandlers) { - this._previousHandlers = []; - } - return this._previousHandlers; - }, - set: function (value) { - this._previousHandlers = value; - } - }, - - nextHandlers: { - get: function () { - if (!this._nextHandlers) { - this._nextHandlers = []; - } - return this._nextHandlers; - }, - set: function (value) { - this._nextHandlers = value; - } - }, - - _densities: { - enumerable: false, - value: null - }, - - densities: { - get: function () { - return this._densities; - }, - set: function (value) { - this._densities = value; - this._densitiesLength = this._densities.length; - this._densitySummation.wipe(); - this._maxTime = null; - } - }, - - _parameters: { - value: { - rotateX: { - data: [0], - units: "rad" - }, - rotateY: { - data: [0], - units: "rad" - }, - rotateZ: { - data: [0], - units: "rad" - }, - opacity: { - data: [1], - units: "" - } - } - }, - - parameters: { - get: function () { - if (!this._parameters) { - this._parameters = {}; - } - return this._parameters; - }, - set: function (value) { - this._parameters = value; - this._parametersLength = this._parameters.length; - } - }, - - knotsLength: { - get: function () { - if (!this._knots) { - return 0; - } - return this._knots.length; - }, - set: function () {} - }, - - getKnot: { - value: function (index) { - return this._knots[index]; - } - }, - - getPreviousHandler: { - value: function (index) { - return this._previousHandlers[index]; - } - }, - - getNextHandler: { - value: function (index) { - return this._nextHandlers[index]; - } - }, - - removeKnot: { - value: function (index) { - this._knots.splice(index, 1); - this._nextHandlers.splice(index, 1); - this._previousHandlers.splice(index, 1); - this._densities.splice(index, 1); - } - }, - - _maxTime: { - enumerable: false, - value: null - }, - - maxTime: { - get: function () { - if ((this._densitySummation === null) || this._densitySummation.length) { - this._computeDensitySummation(); - } - return this._densitySummation[this._densitySummation.length - 1]; - }, - set: function () {} - }, - - _densitySummation: { - enumerable: false, - value: null - }, - - _computeDensitySummation: { - enumerable: false, - value: function () { - var densities = this.densities, length = densities.length - 1, - sum = 0, - i, - densitySummation = this._densitySummation; - - densitySummation.wipe(); - for (i = 0; i < length; i++) { - sum += (densities[i] + densities[i + 1]) / 2; - densitySummation[i] = sum; - } - } - }, - - getPositionAtTime: { - value: function (time, position, parameters) { - var p0, p1, p2, p3, - a, b, c, - t, y, - start, - _parameters = this._parameters, - i, j, - parameterKeys, - parameterKeyCount, - jParameter, - jParameterData, - densitySummation = this._densitySummation; - - position.length = 0; - parameters.wipe(); - - if ((time >= 0) && (time < this.maxTime)) { - if (this._previousIndex && (time >= densitySummation[this._previousIndex - 1])) { - i = this._previousIndex; - } else { - i = 0; - } - while (time >= densitySummation[i]) { - i++; - } - this._previousIndex = i; - start = i ? densitySummation[i - 1] : 0; - p0 = this._knots[i], - p1 = this._nextHandlers[i], - p2 = this._previousHandlers[i + 1], - p3 = this._knots[i + 1], - a = this._densities[i], - b = this._densities[i + 1], - c = a - b; - if ((c < -1e-10) || (c > 1e-10)) { - t = (a - Math.sqrt(a * a + (b - a) * 2 * (time - start))) / c; - } else { - t = (time - start) / a; - } - y = 1 - t; - // TODO: Redo this and create getParametersAtTime or getPositionAndParametersAtTime - - parameterKeys = Object.keys(_parameters); - parameterKeyCount = parameterKeys.length; - - for (j = 0; j < parameterKeyCount; j++) { - jParameter = _parameters[parameterKeys[j]]; - jParameterData = jParameter.data; - if ((typeof jParameterData[i] !== "undefined") && (typeof jParameterData[i + 1] !== "undefined")) { - parameters[parameterKeys[j]] = (jParameterData[i] * y + jParameterData[i + 1] * t).toFixed(5) + jParameter.units; - } else { - parameters[parameterKeys[j]] = jParameterData[jParameterData.length - 1].toFixed(5) + jParameter.units; - } - - } - - position.push(p0[0]*(y*y*y)+p1[0]*(y*y*t*3)+p2[0]*(y*t*t*3)+p3[0]*(t*t*t)); - position.push(p0[1]*(y*y*y)+p1[1]*(y*y*t*3)+p2[1]*(y*t*t*3)+p3[1]*(t*t*t)); - position.push(p0[2]*(y*y*y)+p1[2]*(y*y*t*3)+p2[2]*(y*t*t*3)+p3[2]*(t*t*t)); - position.push(parameters); - - } - - return position; - } - }, - - transformVectorArray: { - value: function (vectors, matrix) { - var length = vectors.length, - out = [], - iVector, - i; - - for (i = 0; i < length; i++) { - iVector = vectors[i]; - out[i] = [ - iVector[0] * matrix[0] + iVector[1] * matrix[4] + iVector[2] * matrix [8] + matrix[12], - iVector[0] * matrix[1] + iVector[1] * matrix[5] + iVector[2] * matrix [9] + matrix[13], - iVector[0] * matrix[2] + iVector[1] * matrix[6] + iVector[2] * matrix [10] + matrix[14] - ]; - } - return out; - } - }, - - transform: { - value: function (matrix) { - var spline = Montage.create(FlowBezierSpline).init(); - - spline._densities = this._densities; - spline._densitySummation = this._densitySummation; - spline._knots = this.transformVectorArray(this.knots, matrix); - spline._previousHandlers = this.transformVectorArray(this.previousHandlers, matrix); - spline._nextHandlers = this.transformVectorArray(this.nextHandlers, matrix); - return spline; - } - }, - - deCasteljau: { - value: function (b0, b1, b2, b3, t) { - var t1 = 1 - t, - p1x = t1 * b0[0] + t * b1[0], p2x = t1 * b1[0] + t * b2[0], p3x = t1 * b2[0] + t * b3[0], - p4x = t1 * p1x + t * p2x, p5x = t1 * p2x + t * p3x, p6x = t1 * p4x + t * p5x, - p1y = t1 * b0[1] + t * b1[1], p2y = t1 * b1[1] + t * b2[1], p3y = t1 * b2[1] + t * b3[1], - p4y = t1 * p1y + t * p2y, p5y = t1 * p2y + t * p3y, p6y = t1 * p4y + t * p5y, - p1z = t1 * b0[2] + t * b1[2], p2z = t1 * b1[2] + t * b2[2], p3z = t1 * b2[2] + t * b3[2], - p4z = t1 * p1z + t * p2z, p5z = t1 * p2z + t * p3z, p6z = t1 * p4z + t * p5z; - - return [ - [b0, [p1x, p1y, p1z], [p4x, p4y, p4z], [p6x, p6y, p6z]], - [[p6x, p6y, p6z], [p5x, p5y, p5z], [p3x, p3y, p3z], b3] - ]; - } - }, - - cubic: { - enumerable: false, - value: function (a, b, c, d, x) { - return ((a * x + b) * x + c) * x + d; - } - }, - - cubeRoot: { - enumerable: false, - value: function (value) { - return (value > 0) ? Math.pow(value, 1/3) : -Math.pow(-value, 1/3); - } - }, - - cubicRealRoots: { - enumerable: false, - value: function (a, b, c, d) { - var epsilon = 1e-100, math = Math; - - if ((a < -epsilon) || (a > epsilon)) { - var dv = 1 / a, - A = b * dv, - B = c * dv, - Q = (3 * B - A * A) * (1 / 9), - R = (4.5 * A * B - 13.5 * d * dv - A * A * A) * (1 / 27), - D = Q * Q * Q + R * R; - - if (D > epsilon) { - var sqD = math.sqrt(D); - - return [this.cubeRoot(R + sqD) + this.cubeRoot(R - sqD) + A * (-1 / 3)]; - } else { - if (D > -epsilon) { - if ((R < -epsilon) || (R > epsilon)) { - var S = this.cubeRoot(R), - r1 = S * 2 + A * (-1 / 3), - r2 = A * (-1 / 3) - S; - - if (r1 < r2) { - return [r1, r2]; - } else { - return [r2, r1]; - } - } else { - return [A * (-1 / 3)]; - } - } else { - var O = math.acos(R / math.sqrt(-Q * Q * Q)) * (1 / 3), - tmp1 = math.sqrt(-Q), - sinO = tmp1 * math.sin(O) * 1.7320508075688772, - tmp2 = A * (-1 / 3); - - tmp1 *= math.cos(O); - return [tmp2 - tmp1 - sinO, tmp2 - tmp1 + sinO, tmp2 + tmp1 * 2]; - } - } - } else { - if ((b < -epsilon) || (b > epsilon)) { - var sq = c * c - 4 * b * d; - - if (sq >= 0) { - sq = math.sqrt(sq); - return [(-c - sq) / (2 * b), (sq - c) / (2 * b)]; - } else { - return []; - } - } else { - if ((c < -epsilon) || (c > epsilon)) { - return [-d / c]; - } else { - return []; - } - } - } - } - }, - - _halfPI: { - enumerable: false, - value: Math.PI*0.5 - }, - - reflectionMatrix: { - enumerable: false, - value: function (planeNormal0,planeNormal1,planeNormal2,reflectionMatrixBuffer) { - var math = Math, angleZ = this._halfPI - math.atan2(planeNormal1, planeNormal0), - sinAngleZ = math.sin(angleZ), - cosAngleZ = math.cos(angleZ), - angleX = this._halfPI - math.atan2(/*p2*/ planeNormal2, /*p1*/ planeNormal0 * sinAngleZ + planeNormal1 * cosAngleZ), - sinAngleX = math.sin(angleX); - - reflectionMatrixBuffer[0] = sinAngleX * sinAngleZ; - reflectionMatrixBuffer[1] = cosAngleZ * sinAngleX; - reflectionMatrixBuffer[2] = math.cos(angleX); - - return reflectionMatrixBuffer; - } - }, - - reflectedY: { - enumerable: false, - value: function (x, y, z, matrix) { - return x * matrix[0] + y * matrix[1] + z * matrix[2]; - } - }, - - planeBezierIntersection: { - enumerable: false, - value: function (planeOrigin, planeNormal, b0, b1, b2, b3) { - var matrix = this.reflectionMatrix(planeNormal), // TODO: cache for matrix and cache for cubicRealRoots - d = this.reflectedY(b0[0] - planeOrigin[0], b0[1] - planeOrigin[1], b0[2] - planeOrigin[2], matrix), - r1 = this.reflectedY(b1[0] - planeOrigin[0], b1[1] - planeOrigin[1], b1[2] - planeOrigin[2], matrix), - r2 = this.reflectedY(b2[0] - planeOrigin[0], b2[1] - planeOrigin[1], b2[2] - planeOrigin[2], matrix), - r3 = this.reflectedY(b3[0] - planeOrigin[0], b3[1] - planeOrigin[1], b3[2] - planeOrigin[2], matrix); - - return this.cubicRealRoots( - (r1 - r2) * 3 + r3 - d, - (d + r2) * 3 - 6 * r1, - (r1 - d) * 3, - d - ); - } - }, - - directedPlaneBezierIntersection: { - enumerable: false, - value: function (planeOrigin0, planeOrigin1, planeOrigin2, planeNormal, b0, b1, b2, b3, reflectionMatrixBuffer, segments) { - var matrix = this.reflectionMatrix(planeNormal[0],planeNormal[1],planeNormal[2],reflectionMatrixBuffer), // TODO: cache for matrix and cache for cubicRealRoots - d = this.reflectedY(b0[0] - planeOrigin0, b0[1] - planeOrigin1, b0[2] - planeOrigin2, matrix), - r1 = this.reflectedY(b1[0] - planeOrigin0, b1[1] - planeOrigin1, b1[2] - planeOrigin2, matrix), - r2 = this.reflectedY(b2[0] - planeOrigin0, b2[1] - planeOrigin1, b2[2] - planeOrigin2, matrix), - r3 = this.reflectedY(b3[0] - planeOrigin0, b3[1] - planeOrigin1, b3[2] - planeOrigin2, matrix), - a = (r1 - r2) * 3 + r3 - d, - b = (d + r2) * 3 - 6 * r1, - c = (r1 - d) * 3, - r = this.cubicRealRoots(a, b, c, d), - min, - max = 0, - mid, - i = 0; - - segments.wipe(); - - while ((i < r.length) && (r[i] <= 0)) { - i++; - } - while ((i < r.length) && (r[i] < 1)) { - min = max; - max = r[i]; - mid = (min + max) * .5; - if (this.cubic(a, b, c, d, mid) >= 0) { - segments.push([min, max]); - } - i++; - } - mid = (max + 1) * .5; - if (this.cubic(a, b, c, d, mid) >= 0) { - segments.push([max, 1]); - } - - return segments; - } - } -}); +var Montage = require("montage").Montage, + FlowBezierSpline = exports.FlowBezierSpline = Montage.create(Montage, { + + init: { + value: function() { + this._densities = []; + this._densitySummation = []; + return this; + } + }, + + knots: { + get: function () { + if (!this._knots) { + this._knots = []; + } + return this._knots; + }, + set: function (value) { + this._knots = value; + } + }, + + previousHandlers: { + get: function () { + if (!this._previousHandlers) { + this._previousHandlers = []; + } + return this._previousHandlers; + }, + set: function (value) { + this._previousHandlers = value; + } + }, + + nextHandlers: { + get: function () { + if (!this._nextHandlers) { + this._nextHandlers = []; + } + return this._nextHandlers; + }, + set: function (value) { + this._nextHandlers = value; + } + }, + + _densities: { + enumerable: false, + value: null + }, + + densities: { + get: function () { + return this._densities; + }, + set: function (value) { + this._densities = value; + this._densitiesLength = this._densities.length; + this._densitySummation.wipe(); + this._maxTime = null; + } + }, + + _parameters: { + value: { + rotateX: { + data: [0], + units: "rad" + }, + rotateY: { + data: [0], + units: "rad" + }, + rotateZ: { + data: [0], + units: "rad" + }, + opacity: { + data: [1], + units: "" + } + } + }, + + parameters: { + get: function () { + if (!this._parameters) { + this._parameters = {}; + } + return this._parameters; + }, + set: function (value) { + this._parameters = value; + this._parametersLength = this._parameters.length; + } + }, + + knotsLength: { + get: function () { + if (!this._knots) { + return 0; + } + return this._knots.length; + }, + set: function () {} + }, + + getKnot: { + value: function (index) { + return this._knots[index]; + } + }, + + getPreviousHandler: { + value: function (index) { + return this._previousHandlers[index]; + } + }, + + getNextHandler: { + value: function (index) { + return this._nextHandlers[index]; + } + }, + + removeKnot: { + value: function (index) { + this._knots.splice(index, 1); + this._nextHandlers.splice(index, 1); + this._previousHandlers.splice(index, 1); + this._densities.splice(index, 1); + } + }, + + _maxTime: { + enumerable: false, + value: null + }, + + maxTime: { + get: function () { + if ((this._densitySummation === null) || this._densitySummation.length) { + this._computeDensitySummation(); + } + return this._densitySummation[this._densitySummation.length - 1]; + }, + set: function () {} + }, + + _densitySummation: { + enumerable: false, + value: null + }, + + _computeDensitySummation: { + enumerable: false, + value: function () { + var densities = this.densities, length = densities.length - 1, + sum = 0, + i, + densitySummation = this._densitySummation; + + densitySummation.wipe(); + for (i = 0; i < length; i++) { + sum += (densities[i] + densities[i + 1]) / 2; + densitySummation[i] = sum; + } + } + }, + + getPositionAtTime: { + value: function (time, position, parameters) { + var p0, p1, p2, p3, + a, b, c, + t, y, + start, + _parameters = this._parameters, + i, j, + parameterKeys, + parameterKeyCount, + jParameter, + jParameterData, + densitySummation = this._densitySummation; + + position.length = 0; + parameters.wipe(); + + if ((time >= 0) && (time < this.maxTime)) { + if (this._previousIndex && (time >= densitySummation[this._previousIndex - 1])) { + i = this._previousIndex; + } else { + i = 0; + } + while (time >= densitySummation[i]) { + i++; + } + this._previousIndex = i; + start = i ? densitySummation[i - 1] : 0; + p0 = this._knots[i], + p1 = this._nextHandlers[i], + p2 = this._previousHandlers[i + 1], + p3 = this._knots[i + 1], + a = this._densities[i], + b = this._densities[i + 1], + c = a - b; + if ((c < -1e-10) || (c > 1e-10)) { + t = (a - Math.sqrt(a * a + (b - a) * 2 * (time - start))) / c; + } else { + t = (time - start) / a; + } + y = 1 - t; + // TODO: Redo this and create getParametersAtTime or getPositionAndParametersAtTime + + parameterKeys = Object.keys(_parameters); + parameterKeyCount = parameterKeys.length; + + for (j = 0; j < parameterKeyCount; j++) { + jParameter = _parameters[parameterKeys[j]]; + jParameterData = jParameter.data; + if ((typeof jParameterData[i] !== "undefined") && (typeof jParameterData[i + 1] !== "undefined")) { + parameters[parameterKeys[j]] = (jParameterData[i] * y + jParameterData[i + 1] * t).toFixed(5) + jParameter.units; + } else { + parameters[parameterKeys[j]] = jParameterData[jParameterData.length - 1].toFixed(5) + jParameter.units; + } + + } + + position.push(p0[0]*(y*y*y)+p1[0]*(y*y*t*3)+p2[0]*(y*t*t*3)+p3[0]*(t*t*t)); + position.push(p0[1]*(y*y*y)+p1[1]*(y*y*t*3)+p2[1]*(y*t*t*3)+p3[1]*(t*t*t)); + position.push(p0[2]*(y*y*y)+p1[2]*(y*y*t*3)+p2[2]*(y*t*t*3)+p3[2]*(t*t*t)); + position.push(parameters); + + } + + return position; + } + }, + + transformVectorArray: { + value: function (vectors, matrix) { + var length = vectors.length, + out = [], + iVector, + i; + + for (i = 0; i < length; i++) { + iVector = vectors[i]; + out[i] = [ + iVector[0] * matrix[0] + iVector[1] * matrix[4] + iVector[2] * matrix [8] + matrix[12], + iVector[0] * matrix[1] + iVector[1] * matrix[5] + iVector[2] * matrix [9] + matrix[13], + iVector[0] * matrix[2] + iVector[1] * matrix[6] + iVector[2] * matrix [10] + matrix[14] + ]; + } + return out; + } + }, + + transform: { + value: function (matrix) { + var spline = Montage.create(FlowBezierSpline).init(); + + spline._densities = this._densities; + spline._densitySummation = this._densitySummation; + spline._knots = this.transformVectorArray(this.knots, matrix); + spline._previousHandlers = this.transformVectorArray(this.previousHandlers, matrix); + spline._nextHandlers = this.transformVectorArray(this.nextHandlers, matrix); + return spline; + } + }, + + deCasteljau: { + value: function (b0, b1, b2, b3, t) { + var t1 = 1 - t, + p1x = t1 * b0[0] + t * b1[0], p2x = t1 * b1[0] + t * b2[0], p3x = t1 * b2[0] + t * b3[0], + p4x = t1 * p1x + t * p2x, p5x = t1 * p2x + t * p3x, p6x = t1 * p4x + t * p5x, + p1y = t1 * b0[1] + t * b1[1], p2y = t1 * b1[1] + t * b2[1], p3y = t1 * b2[1] + t * b3[1], + p4y = t1 * p1y + t * p2y, p5y = t1 * p2y + t * p3y, p6y = t1 * p4y + t * p5y, + p1z = t1 * b0[2] + t * b1[2], p2z = t1 * b1[2] + t * b2[2], p3z = t1 * b2[2] + t * b3[2], + p4z = t1 * p1z + t * p2z, p5z = t1 * p2z + t * p3z, p6z = t1 * p4z + t * p5z; + + return [ + [b0, [p1x, p1y, p1z], [p4x, p4y, p4z], [p6x, p6y, p6z]], + [[p6x, p6y, p6z], [p5x, p5y, p5z], [p3x, p3y, p3z], b3] + ]; + } + }, + + cubic: { + enumerable: false, + value: function (a, b, c, d, x) { + return ((a * x + b) * x + c) * x + d; + } + }, + + cubeRoot: { + enumerable: false, + value: function (value) { + return (value > 0) ? Math.pow(value, 1/3) : -Math.pow(-value, 1/3); + } + }, + + cubicRealRoots: { + enumerable: false, + value: function (a, b, c, d) { + var epsilon = 1e-100, math = Math; + + if ((a < -epsilon) || (a > epsilon)) { + var dv = 1 / a, + A = b * dv, + B = c * dv, + Q = (3 * B - A * A) * (1 / 9), + R = (4.5 * A * B - 13.5 * d * dv - A * A * A) * (1 / 27), + D = Q * Q * Q + R * R; + + if (D > epsilon) { + var sqD = math.sqrt(D); + + return [this.cubeRoot(R + sqD) + this.cubeRoot(R - sqD) + A * (-1 / 3)]; + } else { + if (D > -epsilon) { + if ((R < -epsilon) || (R > epsilon)) { + var S = this.cubeRoot(R), + r1 = S * 2 + A * (-1 / 3), + r2 = A * (-1 / 3) - S; + + if (r1 < r2) { + return [r1, r2]; + } else { + return [r2, r1]; + } + } else { + return [A * (-1 / 3)]; + } + } else { + var O = math.acos(R / math.sqrt(-Q * Q * Q)) * (1 / 3), + tmp1 = math.sqrt(-Q), + sinO = tmp1 * math.sin(O) * 1.7320508075688772, + tmp2 = A * (-1 / 3); + + tmp1 *= math.cos(O); + return [tmp2 - tmp1 - sinO, tmp2 - tmp1 + sinO, tmp2 + tmp1 * 2]; + } + } + } else { + if ((b < -epsilon) || (b > epsilon)) { + var sq = c * c - 4 * b * d; + + if (sq >= 0) { + sq = math.sqrt(sq); + return [(-c - sq) / (2 * b), (sq - c) / (2 * b)]; + } else { + return []; + } + } else { + if ((c < -epsilon) || (c > epsilon)) { + return [-d / c]; + } else { + return []; + } + } + } + } + }, + + _halfPI: { + enumerable: false, + value: Math.PI*0.5 + }, + + reflectionMatrix: { + enumerable: false, + value: function (planeNormal0,planeNormal1,planeNormal2,reflectionMatrixBuffer) { + var math = Math, angleZ = this._halfPI - math.atan2(planeNormal1, planeNormal0), + sinAngleZ = math.sin(angleZ), + cosAngleZ = math.cos(angleZ), + angleX = this._halfPI - math.atan2(/*p2*/ planeNormal2, /*p1*/ planeNormal0 * sinAngleZ + planeNormal1 * cosAngleZ), + sinAngleX = math.sin(angleX); + + reflectionMatrixBuffer[0] = sinAngleX * sinAngleZ; + reflectionMatrixBuffer[1] = cosAngleZ * sinAngleX; + reflectionMatrixBuffer[2] = math.cos(angleX); + + return reflectionMatrixBuffer; + } + }, + + reflectedY: { + enumerable: false, + value: function (x, y, z, matrix) { + return x * matrix[0] + y * matrix[1] + z * matrix[2]; + } + }, + + planeBezierIntersection: { + enumerable: false, + value: function (planeOrigin, planeNormal, b0, b1, b2, b3) { + var matrix = this.reflectionMatrix(planeNormal), // TODO: cache for matrix and cache for cubicRealRoots + d = this.reflectedY(b0[0] - planeOrigin[0], b0[1] - planeOrigin[1], b0[2] - planeOrigin[2], matrix), + r1 = this.reflectedY(b1[0] - planeOrigin[0], b1[1] - planeOrigin[1], b1[2] - planeOrigin[2], matrix), + r2 = this.reflectedY(b2[0] - planeOrigin[0], b2[1] - planeOrigin[1], b2[2] - planeOrigin[2], matrix), + r3 = this.reflectedY(b3[0] - planeOrigin[0], b3[1] - planeOrigin[1], b3[2] - planeOrigin[2], matrix); + + return this.cubicRealRoots( + (r1 - r2) * 3 + r3 - d, + (d + r2) * 3 - 6 * r1, + (r1 - d) * 3, + d + ); + } + }, + + directedPlaneBezierIntersection: { + enumerable: false, + value: function (planeOrigin0, planeOrigin1, planeOrigin2, planeNormal, b0, b1, b2, b3, reflectionMatrixBuffer, segments) { + var matrix = this.reflectionMatrix(planeNormal[0],planeNormal[1],planeNormal[2],reflectionMatrixBuffer), // TODO: cache for matrix and cache for cubicRealRoots + d = this.reflectedY(b0[0] - planeOrigin0, b0[1] - planeOrigin1, b0[2] - planeOrigin2, matrix), + r1 = this.reflectedY(b1[0] - planeOrigin0, b1[1] - planeOrigin1, b1[2] - planeOrigin2, matrix), + r2 = this.reflectedY(b2[0] - planeOrigin0, b2[1] - planeOrigin1, b2[2] - planeOrigin2, matrix), + r3 = this.reflectedY(b3[0] - planeOrigin0, b3[1] - planeOrigin1, b3[2] - planeOrigin2, matrix), + a = (r1 - r2) * 3 + r3 - d, + b = (d + r2) * 3 - 6 * r1, + c = (r1 - d) * 3, + r = this.cubicRealRoots(a, b, c, d), + min, + max = 0, + mid, + i = 0; + + segments.wipe(); + + while ((i < r.length) && (r[i] <= 0)) { + i++; + } + while ((i < r.length) && (r[i] < 1)) { + min = max; + max = r[i]; + mid = (min + max) * .5; + if (this.cubic(a, b, c, d, mid) >= 0) { + segments.push([min, max]); + } + i++; + } + mid = (max + 1) * .5; + if (this.cubic(a, b, c, d, mid) >= 0) { + segments.push([max, 1]); + } + + return segments; + } + } +}); -- cgit v1.2.3