From 8b67d8a1dcb9deed6b8e952f14341549f2504c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sun, 6 Sep 2015 12:47:35 +0200 Subject: [PATCH] Remove #isStraight() in favor of #hasHandles() and implement #clearHandles() Relates to #652 --- src/path/Curve.js | 29 ++++++++++++----------------- src/path/Path.js | 10 ++++++++++ src/path/PathItem.Boolean.js | 22 +++++++++------------- src/path/Segment.js | 29 ++++++++++++----------------- test/tests/Path_Curves.js | 8 ++++---- 5 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/path/Curve.js b/src/path/Curve.js index aed9b659..89dca428 100644 --- a/src/path/Curve.js +++ b/src/path/Curve.js @@ -120,11 +120,11 @@ var Curve = Base.extend(/** @lends Curve# */{ }, _serialize: function(options) { - // If it is straight, only serialize point, otherwise handles too. - return Base.serialize(this.isStraight() - ? [this.getPoint1(), this.getPoint2()] - : [this.getPoint1(), this.getHandle1(), this.getHandle2(), - this.getPoint2()], + // If it has no handles, only serialize points, otherwise handles too. + return Base.serialize(this.hasHandles() + ? [this.getPoint1(), this.getHandle1(), this.getHandle2(), + this.getPoint2()] + : [this.getPoint1(), this.getPoint2()], options, true); }, @@ -329,22 +329,17 @@ var Curve = Base.extend(/** @lends Curve# */{ * @see Path#hasHandles() */ hasHandles: function() { - return !this.isStraight(); + return !this._segment1._handleOut.isZero() + || !this._segment2._handleIn.isZero(); }, /** - * Checks whether the curve is straight, meaning it has no curve handles - * defined and thus appears as a line. - * Note that this is not the same as {@link #isLinear()}, which performs a - * full linearity check that includes handles running collinear to the line - * direction. - * - * @return {Boolean} {@true if the curve is straight} - * @see Segment#isStraight() + * Clears the curve's handles by setting their coordinates to zero, + * turning the curve into a straight line. */ - isStraight: function() { - return this._segment1._handleOut.isZero() - && this._segment2._handleIn.isZero(); + clearHandles: function() { + this._segment1._handleOut.set(0, 0); + this._segment2._handleIn.set(0, 0); }, /** diff --git a/src/path/Path.js b/src/path/Path.js index b61c3c0d..e645f9a0 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -402,6 +402,16 @@ var Path = PathItem.extend(/** @lends Path# */{ return false; }, + /** + * Clears the path's handles by setting their coordinates to zero, + * turning the path into a polygon (or a polyline if it isn't closed). + */ + clearHandles: function() { + var segments = this._segments; + for (var i = 0, l = segments.length; i < l; i++) + segments[i].clearHandles(); + }, + _transformContent: function(matrix) { var coords = new Array(6); for (var i = 0, l = this._segments.length; i < l; i++) diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index ba9fc09e..decd58d0 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -242,8 +242,8 @@ PathItem.inject(new function() { // TODO: Make public in API, since useful! var tMin = /*#=*/Numerical.TOLERANCE, tMax = 1 - tMin, - isStraight = false, - straightSegments = []; + noHandles = false, + clearSegments = []; for (var i = intersections.length - 1, curve, prev; i >= 0; i--) { var loc = intersections[i], @@ -255,7 +255,7 @@ PathItem.inject(new function() { t /= prev._parameter; } else { curve = loc._curve; - isStraight = curve.isStraight(); + noHandles = !curve.hasHandles(); } var segment; if (t < tMin) { @@ -270,22 +270,18 @@ PathItem.inject(new function() { curve = newCurve.getPrevious(); // Keep track of segments of once straight curves, so they can // be set back straight at the end. - if (isStraight) - straightSegments.push(segment); + if (noHandles) + clearSegments.push(segment); } // Link the new segment with the intersection on the other curve segment._intersection = loc.getIntersection(); loc._segment = segment; prev = loc; } - // Reset linear segments if they were part of a linear curve - // and if we are done with the entire curve. - for (var i = 0, l = straightSegments.length; i < l; i++) { - var segment = straightSegments[i]; - // TODO: Implement Segment#makeStraight(), - // or #adjustHandles({ straight: true })) - segment._handleIn.set(0, 0); - segment._handleOut.set(0, 0); + // Clear segment handles if they were part of a curve with no handles, + // once we are done with the entire curve. + for (var i = 0, l = clearSegments.length; i < l; i++) { + clearSegments[i].clearHandles(); } } diff --git a/src/path/Segment.js b/src/path/Segment.js index cb56c7a8..575992bc 100644 --- a/src/path/Segment.js +++ b/src/path/Segment.js @@ -145,9 +145,10 @@ var Segment = Base.extend(/** @lends Segment# */{ }, _serialize: function(options) { - // If it is straight, only serialize point, otherwise handles too. - return Base.serialize(this.isStraight() ? this._point - : [this._point, this._handleIn, this._handleOut], + // If it is has no handles, only serialize point, otherwise handles too. + return Base.serialize(this.hasHandles() + ? [this._point, this._handleIn, this._handleOut] + : this._point, options, true); }, @@ -237,22 +238,16 @@ var Segment = Base.extend(/** @lends Segment# */{ * @see Path#hasHandles() */ hasHandles: function() { - return !this.isStraight(); + return !this._handleIn.isZero() || !this._handleOut.isZero(); }, /** - * Checks whether the segment is straight, meaning it has no curve handles - * defined. If two straight segments follow each each other in a path, the - * curve between them will appear as a straight line. - * Note that this is not the same as {@link #isLinear()}, which performs a - * full linearity check that includes handles running collinear to the line - * direction. - * - * @return {Boolean} {@true if the segment is straight} - * @see Curve#isStraight() + * Clears the segment's handles by setting their coordinates to zero, + * turning the segment into a corner. */ - isStraight: function() { - return this._handleIn.isZero() && this._handleOut.isZero(); + clearHandles: function() { + this._handleIn.set(0, 0); + this._handleOut.set(0, 0); }, /** @@ -579,7 +574,7 @@ var Segment = Base.extend(/** @lends Segment# */{ }, isCollinear: function(seg1, seg2, seg3, seg4) { - // TODO: This assumes isStraight(), while isLinear() allows handles! + // TODO: This assumes !hasHandles(), while isLinear() allows handles! return seg1._handleOut.isZero() && seg2._handleIn.isZero() && seg3._handleOut.isZero() && seg4._handleIn.isZero() && seg2._point.subtract(seg1._point).isCollinear( @@ -587,7 +582,7 @@ var Segment = Base.extend(/** @lends Segment# */{ }, isOrthogonal: function(seg1, seg2, seg3) { - // TODO: This assumes isStraight(), while isLinear() allows handles! + // TODO: This assumes !hasHandles(), while isLinear() allows handles! return seg1._handleOut.isZero() && seg2._handleIn.isZero() && seg2._handleOut.isZero() && seg3._handleIn.isZero() && seg2._point.subtract(seg1._point).isOrthogonal( diff --git a/test/tests/Path_Curves.js b/test/tests/Path_Curves.js index c697e9b1..faebbd47 100644 --- a/test/tests/Path_Curves.js +++ b/test/tests/Path_Curves.js @@ -107,10 +107,10 @@ test('Curve list after removing a segment - 2', function() { }, 1, 'After removing the last segment, we should be left with one curve'); }); -test('Splitting a straight path should produce straight segments', function() { - var path = new Path.Line([0, 0], [50, 50]); - var path2 = path.split(0, 0.5); +test('Splitting a straight path should produce segments without handles', function() { + var path1 = new Path.Line([0, 0], [50, 50]); + var path2 = path1.split(0, 0.5); equals(function() { - return path2.firstSegment.isStraight(); + return !path1.lastSegment.hasHandles() && !path2.firstSegment.hasHandles(); }, true); });