mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
Rework handling of weighted and normalized curve tangents and normals.
Relates to #563
This commit is contained in:
parent
eb8c5b4a3e
commit
da82116501
7 changed files with 164 additions and 87 deletions
|
@ -518,8 +518,7 @@ statics: {
|
|||
return values;
|
||||
},
|
||||
|
||||
// TODO: Instead of constants for type, use a "enum" and code substitution.
|
||||
evaluate: function(v, t, type) {
|
||||
_evaluate: function(v, t, type, normalized) {
|
||||
// Do not produce results if parameter is out of range or invalid.
|
||||
if (t == null || t < 0 || t > 1)
|
||||
return null;
|
||||
|
@ -552,31 +551,45 @@ statics: {
|
|||
// 1: tangent, 1st derivative
|
||||
// 2: normal, 1st derivative
|
||||
// 3: curvature, 1st derivative & 2nd derivative
|
||||
// Simply use the derivation of the bezier function for both
|
||||
// the x and y coordinates:
|
||||
// Prevent tangents and normals of length 0:
|
||||
// http://stackoverflow.com/questions/10506868/
|
||||
if (t < tolerance && c1x === p1x && c1y === p1y
|
||||
|| t > 1 - tolerance && c2x === p2x && c2y === p2y) {
|
||||
x = c2x - c1x;
|
||||
y = c2y - c1y;
|
||||
} else if (t < tolerance) {
|
||||
if (t < tolerance) {
|
||||
x = cx;
|
||||
y = cy;
|
||||
} else if (t > 1 - tolerance) {
|
||||
x = 3 * (p2x - c2x);
|
||||
y = 3 * (p2y - c2y);
|
||||
} else {
|
||||
// Simply use the derivation of the bezier function for both
|
||||
// the x and y coordinates:
|
||||
x = (3 * ax * t + 2 * bx) * t + cx;
|
||||
y = (3 * ay * t + 2 * by) * t + cy;
|
||||
}
|
||||
if (normalized) {
|
||||
// When the tangent at t is zero and we're at the beginning
|
||||
// or the end, we can use the vector between the handles,
|
||||
// but only when normalizing as its weighted length is 0.
|
||||
if (x === 0 && y === 0
|
||||
&& (t < tolerance || t > 1 - tolerance)) {
|
||||
x = c2x - c1x;
|
||||
y = c2y - c1y;
|
||||
}
|
||||
// Now normalize x & y
|
||||
var len = Math.sqrt(x * x + y * y);
|
||||
x /= len;
|
||||
y /= len;
|
||||
}
|
||||
if (type === 3) {
|
||||
// Calculate 2nd derivative, and curvature from there:
|
||||
// http://cagd.cs.byu.edu/~557/text/ch2.pdf page#31
|
||||
// k = |dx * d2y - dy * d2x| / (( dx^2 + dy^2 )^(3/2))
|
||||
var x2 = 6 * ax * t + 2 * bx,
|
||||
y2 = 6 * ay * t + 2 * by;
|
||||
return (x * y2 - y * x2) / Math.pow(x * x + y * y, 3 / 2);
|
||||
y2 = 6 * ay * t + 2 * by,
|
||||
d = Math.pow(x * x + y * y, 3 / 2);
|
||||
// For JS optimizations we always return a Point, although
|
||||
// curvature is just a numeric value, stored in x:
|
||||
x = d !== 0 ? (x * y2 - y * x2) / d : 0;
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,6 +597,30 @@ statics: {
|
|||
return type === 2 ? new Point(y, -x) : new Point(x, y);
|
||||
},
|
||||
|
||||
getPoint: function(v, t) {
|
||||
return Curve._evaluate(v, t, 0, false);
|
||||
},
|
||||
|
||||
getTangent: function(v, t) {
|
||||
return Curve._evaluate(v, t, 1, true);
|
||||
},
|
||||
|
||||
getWeightedTangent: function(v, t) {
|
||||
return Curve._evaluate(v, t, 1, false);
|
||||
},
|
||||
|
||||
getNormal: function(v, t) {
|
||||
return Curve._evaluate(v, t, 2, true);
|
||||
},
|
||||
|
||||
getWeightedNormal: function(v, t) {
|
||||
return Curve._evaluate(v, t, 2, false);
|
||||
},
|
||||
|
||||
getCurvature: function(v, t) {
|
||||
return Curve._evaluate(v, t, 3, false).x;
|
||||
},
|
||||
|
||||
subdivide: function(v, t) {
|
||||
var p1x = v[0], p1y = v[1],
|
||||
c1x = v[2], c1y = v[3],
|
||||
|
@ -835,22 +872,18 @@ statics: {
|
|||
* @type Rectangle
|
||||
* @ignore
|
||||
*/
|
||||
}), Base.each(['getPoint', 'getTangent', 'getNormal', 'getCurvature'],
|
||||
}), Base.each(['getPoint', 'getTangent', 'getNormal', 'getWeightedTangent',
|
||||
'getWeightedNormal', 'getCurvature'],
|
||||
// Note: Although Curve.getBounds() exists, we are using Path.getBounds() to
|
||||
// determine the bounds of Curve objects with defined segment1 and segment2
|
||||
// values Curve.getBounds() can be used directly on curve arrays, without
|
||||
// the need to create a Curve object first, as required by the code that
|
||||
// finds path interesections.
|
||||
function(name, index) {
|
||||
function(name) {
|
||||
this[name + 'At'] = function(offset, isParameter) {
|
||||
var values = this.getValues();
|
||||
return Curve.evaluate(values, isParameter
|
||||
? offset : Curve.getParameterAt(values, offset, 0), index);
|
||||
};
|
||||
// Deprecated and undocumented, but keep around for now.
|
||||
// TODO: Remove once enough time has passed (28.01.2013)
|
||||
this[name] = function(parameter) {
|
||||
return Curve.evaluate(this.getValues(), parameter, index);
|
||||
return Curve[name](values, isParameter ? offset
|
||||
: Curve.getParameterAt(values, offset, 0));
|
||||
};
|
||||
},
|
||||
/** @lends Curve# */{
|
||||
|
@ -936,8 +969,7 @@ statics: {
|
|||
|
||||
function refine(t) {
|
||||
if (t >= 0 && t <= 1) {
|
||||
var dist = point.getDistance(
|
||||
Curve.evaluate(values, t, 0), true);
|
||||
var dist = point.getDistance(Curve.getPoint(values, t), true);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
minT = t;
|
||||
|
@ -955,7 +987,7 @@ statics: {
|
|||
if (!refine(minT - step) && !refine(minT + step))
|
||||
step /= 2;
|
||||
}
|
||||
var pt = Curve.evaluate(values, minT, 0);
|
||||
var pt = Curve.getPoint(values, minT);
|
||||
return new CurveLocation(this, minT, pt, null, null, null,
|
||||
point.getDistance(pt));
|
||||
},
|
||||
|
@ -973,11 +1005,12 @@ statics: {
|
|||
* parameter if {@code isParameter} is {@code true}
|
||||
* @param {Boolean} [isParameter=false] pass {@code true} if {@code offset}
|
||||
* is a curve time parameter
|
||||
* @return {Point} the point on the curve at the specified offset
|
||||
* @return {Point} the point on the curve at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the tangent vector of the curve at the given offset.
|
||||
* Calculates the normalized tangent vector of the curve at the given
|
||||
* offset.
|
||||
*
|
||||
* @name Curve#getTangentAt
|
||||
* @function
|
||||
|
@ -985,7 +1018,7 @@ statics: {
|
|||
* parameter if {@code isParameter} is {@code true}
|
||||
* @param {Boolean} [isParameter=false] pass {@code true} if {@code offset}
|
||||
* is a curve time parameter
|
||||
* @return {Point} the tangent of the curve at the specified offset
|
||||
* @return {Point} the normalized tangent of the curve at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -997,7 +1030,33 @@ statics: {
|
|||
* parameter if {@code isParameter} is {@code true}
|
||||
* @param {Boolean} [isParameter=false] pass {@code true} if {@code offset}
|
||||
* is a curve time parameter
|
||||
* @return {Point} the normal of the curve at the specified offset
|
||||
* @return {Point} the normal of the curve at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the weighted tangent vector of the curve at the given
|
||||
* offset, its length reflecting the curve velocity at that location.
|
||||
*
|
||||
* @name Curve#getWeightedTangentAt
|
||||
* @function
|
||||
* @param {Number} offset the offset on the curve, or the curve time
|
||||
* parameter if {@code isParameter} is {@code true}
|
||||
* @param {Boolean} [isParameter=false] pass {@code true} if {@code offset}
|
||||
* is a curve time parameter
|
||||
* @return {Point} the weighted tangent of the curve at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the weighted normal vector of the curve at the given offset,
|
||||
* its length reflecting the curve velocity at that location.
|
||||
*
|
||||
* @name Curve#getWeightedNormalAt
|
||||
* @function
|
||||
* @param {Number} offset the offset on the curve, or the curve time
|
||||
* parameter if {@code isParameter} is {@code true}
|
||||
* @param {Boolean} [isParameter=false] pass {@code true} if {@code offset}
|
||||
* is a curve time parameter
|
||||
* @return {Point} the weighted normal of the curve at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -1012,7 +1071,7 @@ statics: {
|
|||
* parameter if {@code isParameter} is {@code true}
|
||||
* @param {Boolean} [isParameter=false] pass {@code true} if {@code offset}
|
||||
* is a curve time parameter
|
||||
* @return {Number} the curvature of the curve at the specified offset
|
||||
* @return {Number} the curvature of the curve at the given offset
|
||||
*/
|
||||
}),
|
||||
new function() { // Scope for methods that require numerical integration
|
||||
|
@ -1210,12 +1269,12 @@ new function() { // Scope for methods that require numerical integration
|
|||
t2 = uMin + (uMax - uMin) / 2;
|
||||
if (reverse) {
|
||||
addLocation(locations, include,
|
||||
curve2, t2, Curve.evaluate(v2, t2, 0),
|
||||
curve1, t1, Curve.evaluate(v1, t1, 0));
|
||||
curve2, t2, Curve.getPoint(v2, t2),
|
||||
curve1, t1, Curve.getPoint(v1, t1));
|
||||
} else {
|
||||
addLocation(locations, include,
|
||||
curve1, t1, Curve.evaluate(v1, t1, 0),
|
||||
curve2, t2, Curve.evaluate(v2, t2, 0));
|
||||
curve1, t1, Curve.getPoint(v1, t1),
|
||||
curve2, t2, Curve.getPoint(v2, t2));
|
||||
}
|
||||
} else if (tDiff > 0) { // Iterate
|
||||
addCurveIntersections(v2, v1, curve2, curve1, locations, include,
|
||||
|
@ -1393,7 +1452,7 @@ new function() { // Scope for methods that require numerical integration
|
|||
// happen with lines, in which case we should not be here.
|
||||
for (var i = 0; i < count; i++) {
|
||||
var tc = roots[i],
|
||||
x = Curve.evaluate(rvc, tc, 0).x;
|
||||
x = Curve.getPoint(rvc, tc).x;
|
||||
// We do have a point on the infinite line. Check if it falls on
|
||||
// the line *segment*.
|
||||
if (x >= 0 && x <= rlx2) {
|
||||
|
@ -1402,8 +1461,8 @@ new function() { // Scope for methods that require numerical integration
|
|||
t1 = flip ? tl : tc,
|
||||
t2 = flip ? tc : tl;
|
||||
addLocation(locations, include,
|
||||
curve1, t1, Curve.evaluate(v1, t1, 0),
|
||||
curve2, t2, Curve.evaluate(v2, t2, 0));
|
||||
curve1, t1, Curve.getPoint(v1, t1),
|
||||
curve2, t2, Curve.getPoint(v2, t2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,7 +307,8 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
parts.push('distance: ' + f.number(this._distance));
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
}
|
||||
}, Base.each(['getTangent', 'getNormal', 'getCurvature'], function(name) {
|
||||
}, Base.each(['getTangent', 'getNormal', 'getWeightedTangent',
|
||||
'getWeightedNormal', 'getCurvature'], function(name) {
|
||||
// Produce getters for #getTangent() / #getNormal() / #getCurvature()
|
||||
var get = name + 'At';
|
||||
this[name] = function() {
|
||||
|
|
|
@ -996,7 +996,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
// Iterate over path and evaluate and add points at given offsets
|
||||
var segments = [];
|
||||
while (pos <= end) {
|
||||
segments.push(new Segment(iterator.evaluate(pos, 0)));
|
||||
segments.push(new Segment(iterator.getPointAt(pos)));
|
||||
pos += step;
|
||||
}
|
||||
this.setSegments(segments);
|
||||
|
@ -1638,7 +1638,8 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
|
||||
// TODO: intersects(item)
|
||||
// TODO: contains(item)
|
||||
}, Base.each(['getPoint', 'getTangent', 'getNormal', 'getCurvature'],
|
||||
}, Base.each(['getPoint', 'getTangent', 'getNormal', 'getWeightedTangent',
|
||||
'getWeightedNormal', 'getCurvature'],
|
||||
function(name) {
|
||||
this[name + 'At'] = function(offset, isParameter) {
|
||||
var loc = this.getLocationAt(offset, isParameter);
|
||||
|
@ -1713,8 +1714,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
if (isParameter) {
|
||||
// offset consists of curve index and curve parameter, before and
|
||||
// after the fractional digit.
|
||||
var index = ~~offset; // = Math.floor()
|
||||
return curves[index].getLocationAt(offset - index, true);
|
||||
var index = ~~offset, // = Math.floor()
|
||||
curve = curves[index];
|
||||
return curve ? curve.getLocationAt(offset - index, true) : null;
|
||||
}
|
||||
for (var i = 0, l = curves.length; i < l; i++) {
|
||||
var start = length,
|
||||
|
@ -1796,14 +1798,14 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
*/
|
||||
|
||||
/**
|
||||
* Calculates the tangent vector of the path at the given offset.
|
||||
* Calculates the normalized tangent vector of the path at the given offset.
|
||||
*
|
||||
* @name Path#getTangentAt
|
||||
* @function
|
||||
* @param {Number} offset the offset on the path, where {@code 0} is at
|
||||
* the beginning of the path and {@link Path#length} at the end
|
||||
* @param {Boolean} [isParameter=false]
|
||||
* @return {Point} the tangent vector at the given offset
|
||||
* @return {Point} the normalized tangent vector at the given offset
|
||||
*
|
||||
* @example {@paperscript height=150}
|
||||
* // Working with the tangent vector at a given offset:
|
||||
|
@ -1823,11 +1825,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* // Find the point on the path:
|
||||
* var point = path.getPointAt(offset);
|
||||
*
|
||||
* // Find the tangent vector at the given offset:
|
||||
* var tangent = path.getTangentAt(offset);
|
||||
*
|
||||
* // Make the tangent vector 60pt long:
|
||||
* tangent.length = 60;
|
||||
* // Find the tangent vector at the given offset
|
||||
* // and give it a length of 60:
|
||||
* var tangent = path.getTangentAt(offset) * 60;
|
||||
*
|
||||
* var line = new Path({
|
||||
* segments: [point, point + tangent],
|
||||
|
@ -1853,11 +1853,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* // Find the point on the path at the given offset:
|
||||
* var point = path.getPointAt(offset);
|
||||
*
|
||||
* // Find the normal vector on the path at the given offset:
|
||||
* var tangent = path.getTangentAt(offset);
|
||||
*
|
||||
* // Make the tangent vector 60pt long:
|
||||
* tangent.length = 60;
|
||||
* // Find the tangent vector on the path at the given offset
|
||||
* // and give it a length of 60:
|
||||
* var tangent = path.getTangentAt(offset) * 60;
|
||||
*
|
||||
* var line = new Path({
|
||||
* segments: [point, point + tangent],
|
||||
|
@ -1894,11 +1892,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* // Find the point on the path:
|
||||
* var point = path.getPointAt(offset);
|
||||
*
|
||||
* // Find the normal vector at the given offset:
|
||||
* var normal = path.getNormalAt(offset);
|
||||
*
|
||||
* // Make the normal vector 30pt long:
|
||||
* normal.length = 30;
|
||||
* // Find the normal vector on the path at the given offset
|
||||
* // and give it a length of 30:
|
||||
* var normal = path.getNormalAt(offset) * 30;
|
||||
*
|
||||
* var line = new Path({
|
||||
* segments: [point, point + normal],
|
||||
|
@ -1924,11 +1920,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* // Find the point on the path at the given offset:
|
||||
* var point = path.getPointAt(offset);
|
||||
*
|
||||
* // Find the normal vector on the path at the given offset:
|
||||
* var normal = path.getNormalAt(offset);
|
||||
*
|
||||
* // Make the normal vector 30pt long:
|
||||
* normal.length = 30;
|
||||
* // Find the normal vector on the path at the given offset
|
||||
* // and give it a length of 30:
|
||||
* var normal = path.getNormalAt(offset) * 30;
|
||||
*
|
||||
* var line = new Path({
|
||||
* segments: [point, point + normal],
|
||||
|
@ -1937,6 +1931,28 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the weighted tangent vector of the path at the given offset.
|
||||
*
|
||||
* @name Path#getWeightedTangentAt
|
||||
* @function
|
||||
* @param {Number} offset the offset on the path, where {@code 0} is at
|
||||
* the beginning of the path and {@link Path#length} at the end
|
||||
* @param {Boolean} [isParameter=false]
|
||||
* @return {Point} the weighted tangent vector at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the weighted normal vector of the path at the given offset.
|
||||
*
|
||||
* @name Path#getWeightedNormalAt
|
||||
* @function
|
||||
* @param {Number} offset the offset on the path, where {@code 0} is at
|
||||
* the beginning of the path and {@link Path#length} at the end
|
||||
* @param {Boolean} [isParameter=false]
|
||||
* @return {Point} the weighted normal vector at the given offset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the curvature of the path at the given offset. Curvatures
|
||||
* indicate how sharply a path changes direction. A straight line has zero
|
||||
|
@ -1949,7 +1965,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* the beginning of the path and {@link Path#length} at the end
|
||||
* @param {Boolean} [isParameter=false]
|
||||
* @return {Number} the normal vector at the given offset
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the nearest location on the path to the specified point.
|
||||
|
@ -2848,7 +2864,7 @@ statics: {
|
|||
// Calculate the corner points of butt and square caps
|
||||
var point = segment._point,
|
||||
loc = segment.getLocation(),
|
||||
normal = loc.getNormal().normalize(radius);
|
||||
normal = loc.getNormal().multiply(radius); // normal is normalized
|
||||
if (area) {
|
||||
addPoint(point.subtract(normal));
|
||||
addPoint(point.add(normal));
|
||||
|
|
|
@ -271,7 +271,7 @@ PathItem.inject(new function() {
|
|||
var values = curves[i].values;
|
||||
if (Curve.solveCubic(values, 0, px, roots, 0, 1) > 0) {
|
||||
for (var j = roots.length - 1; j >= 0; j--) {
|
||||
var y = Curve.evaluate(values, roots[j], 0).y;
|
||||
var y = Curve.getPoint(values, roots[j]).y;
|
||||
if (y < yBefore && y > yTop) {
|
||||
yTop = y;
|
||||
} else if (y > yAfter && y < yBottom) {
|
||||
|
@ -325,8 +325,8 @@ PathItem.inject(new function() {
|
|||
// sure we're still on the same loop.
|
||||
|| t < tMin && prevT > tMax
|
||||
&& curve.previous === prevCurve)) {
|
||||
var x = Curve.evaluate(values, t, 0).x,
|
||||
slope = Curve.evaluate(values, t, 1).y,
|
||||
var x = Curve.getPoint(values, t).x,
|
||||
slope = Curve.getTangent(values, t).y,
|
||||
counted = false;
|
||||
// Take care of cases where the curve and the preceding
|
||||
// curve merely touches the ray towards +-x direction,
|
||||
|
@ -334,11 +334,11 @@ PathItem.inject(new function() {
|
|||
// This essentially is not a crossing.
|
||||
if (Numerical.isZero(slope) && !Curve.isLinear(values)
|
||||
// Does the slope over curve beginning change?
|
||||
|| t < tMin && slope * Curve.evaluate(
|
||||
curve.previous.values, 1, 1).y < 0
|
||||
|| t < tMin && slope * Curve.getTangent(
|
||||
curve.previous.values, 1).y < 0
|
||||
// Does the slope over curve end change?
|
||||
|| t > tMax && slope * Curve.evaluate(
|
||||
curve.next.values, 0, 1).y < 0) {
|
||||
|| t > tMax && slope * Curve.getTangent(
|
||||
curve.next.values, 0).y < 0) {
|
||||
if (testContains && x >= xBefore && x <= xAfter) {
|
||||
++windLeft;
|
||||
++windRight;
|
||||
|
@ -695,7 +695,7 @@ Path.inject(/** @lends Path# */{
|
|||
|| y >= values[7] && y <= values[1])
|
||||
&& Curve.solveCubic(values, 1, y, roots, 0, 1) > 0) {
|
||||
for (var j = roots.length - 1; j >= 0; j--)
|
||||
xIntercepts.push(Curve.evaluate(values, roots[j], 0).x);
|
||||
xIntercepts.push(Curve.getPoint(values, roots[j]).x);
|
||||
}
|
||||
if (xIntercepts.length > 1)
|
||||
break;
|
||||
|
|
|
@ -134,11 +134,6 @@ var PathIterator = Base.extend({
|
|||
};
|
||||
},
|
||||
|
||||
evaluate: function(offset, type) {
|
||||
var param = this.getParameterAt(offset);
|
||||
return Curve.evaluate(this.curves[param.index], param.value, type);
|
||||
},
|
||||
|
||||
drawPart: function(ctx, from, to) {
|
||||
from = this.getParameterAt(from);
|
||||
to = this.getParameterAt(to);
|
||||
|
@ -151,10 +146,12 @@ var PathIterator = Base.extend({
|
|||
ctx.bezierCurveTo.apply(ctx, curve.slice(2));
|
||||
}
|
||||
}
|
||||
}, Base.each(['getPoint', 'getTangent', 'getNormal', 'getCurvature'],
|
||||
function(name, index) {
|
||||
this[name + 'At'] = function(offset) {
|
||||
return this.evaluate(offset, index);
|
||||
}, Base.each(['getPoint', 'getTangent', 'getNormal', 'getWeightedTangent',
|
||||
'getWeightedNormal', 'getCurvature'],
|
||||
function(name) {
|
||||
this[name + 'At'] = function(offset, weighted) {
|
||||
var param = this.getParameterAt(offset);
|
||||
return Curve[name](this.curves[param.index], param.value, weighted);
|
||||
};
|
||||
}, {})
|
||||
);
|
||||
|
|
|
@ -76,8 +76,10 @@ test('Curve#getTangentAt()', function() {
|
|||
|
||||
for (var i = 0; i < tangents.length; i++) {
|
||||
var entry = tangents[i];
|
||||
equals(curve.getTangentAt(entry[0], true), entry[1],
|
||||
equals(curve.getTangentAt(entry[0], true), entry[1].normalize(),
|
||||
'curve.getTangentAt(' + entry[0] + ', true);');
|
||||
equals(curve.getWeightedTangentAt(entry[0], true), entry[1],
|
||||
'curve.getWeightedTangentAt(' + entry[0] + ', true);');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -97,8 +99,10 @@ test('Curve#getNormalAt()', function() {
|
|||
|
||||
for (var i = 0; i < normals.length; i++) {
|
||||
var entry = normals[i];
|
||||
equals(curve.getNormalAt(entry[0], true), entry[1],
|
||||
equals(curve.getNormalAt(entry[0], true), entry[1].normalize(),
|
||||
'curve.getNormalAt(' + entry[0] + ', true);');
|
||||
equals(curve.getWeightedNormalAt(entry[0], true), entry[1],
|
||||
'curve.getWeightedNormalAt(' + entry[0] + ', true);');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -168,8 +168,8 @@ test('Path#contains() (Rectangle Contours)', function() {
|
|||
curves = path.getCurves();
|
||||
|
||||
for (var i = 0; i < curves.length; i++) {
|
||||
testPoint(path, curves[i].getPoint(0), true);
|
||||
testPoint(path, curves[i].getPoint(0.5), true);
|
||||
testPoint(path, curves[i].getPointAt(0, true), true);
|
||||
testPoint(path, curves[i].getPointAt(0.5, true), true);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -181,8 +181,8 @@ test('Path#contains() (Rotated Rectangle Contours)', function() {
|
|||
path.rotate(45);
|
||||
|
||||
for (var i = 0; i < curves.length; i++) {
|
||||
testPoint(path, curves[i].getPoint(0), true);
|
||||
testPoint(path, curves[i].getPoint(0.5), true);
|
||||
testPoint(path, curves[i].getPointAt(0, true), true);
|
||||
testPoint(path, curves[i].getPointAt(0.5, true), true);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue