mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-08-28 22:08:54 -04:00
Add tolerance argument to Path#join(path, tolerance)
This commit is contained in:
parent
68be3f102e
commit
de8b626033
4 changed files with 61 additions and 42 deletions
|
@ -168,6 +168,7 @@ contribute to the code.
|
|||
- Add new options to `#exportSVG()` to control output bounds and transformation
|
||||
matrix (#972).
|
||||
- Allow `Item#position` to be selected via `Item#position.selected` (#980).
|
||||
- Add `tolerance` argument to `Path#join(path, tolerance)`.
|
||||
|
||||
### Fixed
|
||||
- Fix calculations of `Item#strokeBounds` for all possible combinations of
|
||||
|
|
|
@ -694,7 +694,7 @@ var Point = Base.extend(/** @lends Point# */{
|
|||
isClose: function(/* point, tolerance */) {
|
||||
var point = Point.read(arguments),
|
||||
tolerance = Base.read(arguments);
|
||||
return this.getDistance(point) < tolerance;
|
||||
return this.getDistance(point) <= tolerance;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1090,15 +1090,19 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
return location != null ? this.splitAt(location) : null;
|
||||
},
|
||||
|
||||
// DOCS: document Path#join(path) in more detail.
|
||||
// DOCS: document Path#join() (joining with itself)
|
||||
// TODO: Consider adding a distance / tolerance parameter for merging.
|
||||
/**
|
||||
* Joins the path with the specified path, which will be removed in the
|
||||
* process.
|
||||
* Joins the path with the other specified path, which will be removed in
|
||||
* the process. They can be joined if the first or last segments of either
|
||||
* path lie in the same location. Locations are optionally compare with a
|
||||
* provide `tolerance` value.
|
||||
*
|
||||
* @param {Path} path the path to join this path with
|
||||
* @return {Path} the joined path
|
||||
* If `null` or `this` is passed as the other path, the path will be joined
|
||||
* with itself if the first and last segment are in the same location.
|
||||
*
|
||||
* @param {Path} path the path to join this path with; `null` or `this` to
|
||||
* join the path with itself
|
||||
* @param {Number} [tolerance=0] the tolerance with which to decide if two
|
||||
* segments are to be considered the same location when joining
|
||||
*
|
||||
* @example {@paperscript}
|
||||
* // Joining two paths:
|
||||
|
@ -1159,25 +1163,26 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* // Select the path to show that they have joined:
|
||||
* path.selected = true;
|
||||
*/
|
||||
join: function(path) {
|
||||
if (path) {
|
||||
join: function(path, tolerance) {
|
||||
var epsilon = tolerance || 0;
|
||||
if (path && path !== this) {
|
||||
var segments = path._segments,
|
||||
last1 = this.getLastSegment(),
|
||||
last2 = path.getLastSegment();
|
||||
if (!last2) // an empty path?
|
||||
return this;
|
||||
if (last1 && last1._point.equals(last2._point))
|
||||
if (last1 && last1._point.isClose(last2._point, epsilon))
|
||||
path.reverse();
|
||||
var first2 = path.getFirstSegment();
|
||||
if (last1 && last1._point.equals(first2._point)) {
|
||||
if (last1 && last1._point.isClose(first2._point, epsilon)) {
|
||||
last1.setHandleOut(first2._handleOut);
|
||||
this._add(segments.slice(1));
|
||||
} else {
|
||||
var first1 = this.getFirstSegment();
|
||||
if (first1 && first1._point.equals(first2._point))
|
||||
if (first1 && first1._point.isClose(first2._point, epsilon))
|
||||
path.reverse();
|
||||
last2 = path.getLastSegment();
|
||||
if (first1 && first1._point.equals(last2._point)) {
|
||||
if (first1 && first1._point.isClose(last2._point, epsilon)) {
|
||||
first1.setHandleIn(last2._handleIn);
|
||||
// Prepend all segments from path except the last one.
|
||||
this._add(segments.slice(0, segments.length - 1), 0);
|
||||
|
@ -1195,7 +1200,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
// only if its ends touch.
|
||||
var first = this.getFirstSegment(),
|
||||
last = this.getLastSegment();
|
||||
if (first !== last && first._point.equals(last._point)) {
|
||||
if (first !== last && first._point.isClose(last._point, epsilon)) {
|
||||
first.setHandleIn(last._handleIn);
|
||||
last.remove();
|
||||
this.setClosed(true);
|
||||
|
|
|
@ -57,57 +57,70 @@ test('curve.getTimeAt() with straight curve', function() {
|
|||
equals(t, 0.3869631475722452);
|
||||
});
|
||||
|
||||
test('path.join(path)', function() {
|
||||
var path = new Path();
|
||||
path.add(0, 0);
|
||||
path.add(10, 0);
|
||||
test('path1.join(path2)', function() {
|
||||
var path1 = new Path();
|
||||
path1.add(0, 0);
|
||||
path1.add(10, 0);
|
||||
|
||||
var path2 = new Path();
|
||||
path2.add(10, 0);
|
||||
path2.add(20, 10);
|
||||
|
||||
path.join(path2);
|
||||
equals(path.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }');
|
||||
equals(function() {
|
||||
return paper.project.activeLayer.children.length;
|
||||
}, 1);
|
||||
path1.join(path2);
|
||||
equals(path1.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }');
|
||||
equals(function() { return paper.project.activeLayer.children.length; }, 1);
|
||||
|
||||
var path = new Path();
|
||||
path.add(0, 0);
|
||||
path.add(10, 0);
|
||||
var path1 = new Path();
|
||||
path1.add(0, 0);
|
||||
path1.add(10, 0);
|
||||
|
||||
var path2 = new Path();
|
||||
path2.add(20, 10);
|
||||
path2.add(10, 0);
|
||||
path.join(path2);
|
||||
equals(path.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }');
|
||||
path1.join(path2);
|
||||
equals(path1.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } }');
|
||||
|
||||
var path = new Path();
|
||||
path.add(0, 0);
|
||||
path.add(10, 0);
|
||||
var path1 = new Path();
|
||||
path1.add(0, 0);
|
||||
path1.add(10, 0);
|
||||
|
||||
var path2 = new Path();
|
||||
path2.add(30, 10);
|
||||
path2.add(40, 0);
|
||||
path.join(path2);
|
||||
equals(path.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 30, y: 10 } },{ point: { x: 40, y: 0 } }');
|
||||
path1.join(path2);
|
||||
equals(path1.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 30, y: 10 } },{ point: { x: 40, y: 0 } }');
|
||||
|
||||
var path = new Path();
|
||||
path.add(0, 0);
|
||||
path.add(10, 0);
|
||||
path.add(20, 10);
|
||||
var path1 = new Path();
|
||||
path1.add(0, 0);
|
||||
path1.add(10, 0);
|
||||
path1.add(20, 10);
|
||||
|
||||
var path2 = new Path();
|
||||
path2.add(0, 0);
|
||||
path2.add(10, 5);
|
||||
path2.add(20, 10);
|
||||
|
||||
path.join(path2);
|
||||
path1.join(path2);
|
||||
|
||||
equals(path1.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } },{ point: { x: 10, y: 5 } }');
|
||||
equals(function() { return path1.closed; }, true);
|
||||
});
|
||||
|
||||
test('path1.join(path2, tolerance)', function() {
|
||||
var path1 = new Path();
|
||||
path1.add(0, 0);
|
||||
path1.add(10, 0);
|
||||
|
||||
var path2 = new Path();
|
||||
path2.add(path1.lastSegment.point.add(1e-14));
|
||||
path2.add(20, 10);
|
||||
|
||||
equals(path.segments.toString(), '{ point: { x: 0, y: 0 } },{ point: { x: 10, y: 0 } },{ point: { x: 20, y: 10 } },{ point: { x: 10, y: 5 } }');
|
||||
equals(function() {
|
||||
return path.closed;
|
||||
}, true);
|
||||
return path1.clone().join(path2.clone(), 0).segments.length;
|
||||
}, 4);
|
||||
equals(function() {
|
||||
return path1.clone().join(path2.clone(), 1e-12).segments.length;
|
||||
}, 3);
|
||||
});
|
||||
|
||||
test('path.remove()', function() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue