mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -05:00
Implement correct checks for primitives (rect, ellipse, circle).
This commit is contained in:
parent
a6d19ac681
commit
4c51544b6e
3 changed files with 41 additions and 27 deletions
|
@ -487,7 +487,7 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{
|
||||||
getRotation: function() {
|
getRotation: function() {
|
||||||
var angle1 = -Math.atan2(this._b, this._d),
|
var angle1 = -Math.atan2(this._b, this._d),
|
||||||
angle2 = Math.atan2(this._c, this._a);
|
angle2 = Math.atan2(this._c, this._a);
|
||||||
return Math.abs(angle1 - angle2) < Numerical.TOLERANCE
|
return Math.abs(angle1 - angle2) < Numerical.EPSILON
|
||||||
? angle1 * 180 / Math.PI : undefined;
|
? angle1 * 180 / Math.PI : undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path.inject({ statics: new function() {
|
Path.inject({ statics: new function() {
|
||||||
var kappa = 2 / 3 * (Math.sqrt(2) - 1);
|
// Kappa, see: http://www.whizkidtech.redprince.net/bezier/circle/kappa/
|
||||||
|
var kappa = 2 * (Math.sqrt(2) - 1) / 3;
|
||||||
|
|
||||||
var ovalSegments = [
|
var ovalSegments = [
|
||||||
new Segment([0, 0.5], [0, kappa ], [0, -kappa]),
|
new Segment([0, 0.5], [0, kappa ], [0, -kappa]),
|
||||||
|
|
|
@ -224,44 +224,57 @@ var SvgExporter = this.SvgExporter = new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function determineType(path, segments) {
|
function determineType(path, segments) {
|
||||||
|
|
||||||
|
function isOrthogonal(i) {
|
||||||
|
var segment = segments[i],
|
||||||
|
point = segment.getPoint();
|
||||||
|
return Numerical.isZero(90 - Math.abs(
|
||||||
|
segment.getNext().getPoint().subtract(point).getAngle(
|
||||||
|
segment.getPrevious().getPoint().subtract(point))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kappa, see: http://www.whizkidtech.redprince.net/bezier/circle/kappa/
|
||||||
|
var kappa = 4 * (Math.sqrt(2) - 1) / 3;
|
||||||
|
|
||||||
|
function isArc(i) {
|
||||||
|
var segment = segments[i],
|
||||||
|
next = segment.getNext(),
|
||||||
|
handle1 = segment.getHandleOut(),
|
||||||
|
handle2 = next.getHandleIn();
|
||||||
|
if (Numerical.isZero(90 - Math.abs(handle1.getAngle(handle2)))) {
|
||||||
|
var from = segment.getPoint(),
|
||||||
|
to = next.getPoint(),
|
||||||
|
corner = new Line(from, handle1).intersect(new Line(to, handle2));
|
||||||
|
return Numerical.isZero(handle1.length / corner.subtract(from).length - kappa)
|
||||||
|
&& Numerical.isZero(handle2.length / corner.subtract(to).length - kappa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See if actually have any curves in the path. Differentiate
|
// See if actually have any curves in the path. Differentiate
|
||||||
// between straight objects (line, polyline, rect, and polygon) and
|
// between straight objects (line, polyline, rect, and polygon) and
|
||||||
// objects with curves(circle, ellipse, roundedRectangle).
|
// objects with curves(circle, ellipse, roundedRectangle).
|
||||||
if (path.isPolygon()) {
|
if (path.isPolygon()) {
|
||||||
// If the distance between (point0 and point1) and (point2 and
|
return segments.length === 4 && path._closed && isOrthogonal(0)
|
||||||
// point3) are equal, then it is a rectangle
|
&& isOrthogonal(1) && isOrthogonal(2) && isOrthogonal(3)
|
||||||
return segments.length == 4 && Numerical.isZero(
|
|
||||||
getDistance(segments, 0, 1) - getDistance(segments, 3, 2))
|
|
||||||
? 'rect'
|
? 'rect'
|
||||||
: segments.length >= 3
|
: segments.length >= 3
|
||||||
? path._closed ? 'polygon' : 'polyline'
|
? path._closed ? 'polygon' : 'polyline'
|
||||||
: 'line';
|
: 'line';
|
||||||
} else {
|
} else if (path._closed) {
|
||||||
if (segments.length == 8) {
|
if (segments.length === 8) {
|
||||||
// If the distance between (point0 and point3) and (point7 and
|
// If the distance between (point0 and point3) and (point7 and
|
||||||
// point4) are equal then it is a roundedRectangle
|
// point4) are equal then it is a roundedRectangle
|
||||||
if (Numerical.isZero(
|
if (Numerical.isZero(
|
||||||
getDistance(segments, 0, 3) - getDistance(segments, 7, 5)))
|
getDistance(segments, 0, 3) - getDistance(segments, 7, 5)))
|
||||||
return 'roundrect';
|
return 'roundrect';
|
||||||
} else if (segments.length == 4) {
|
} else if (segments.length === 4
|
||||||
// Check if the values of the point have values similar to
|
&& isArc(0) && isArc(1) && isArc(2) && isArc(3)) {
|
||||||
// circles and ellipses.
|
// If the distance between (point0 and point2) and (point1
|
||||||
var checkPointValues = true;
|
// and point3) are equal, then it is a circle
|
||||||
for (var i = 0; i < segments.length && checkPointValues; i++) {
|
return Numerical.isZero(getDistance(segments, 0, 2)
|
||||||
var handleIn = segments[i]._handleIn,
|
- getDistance(segments, 1, 3))
|
||||||
handleOut = segments[i]._handleOut;
|
? 'circle'
|
||||||
checkPointValues = !handleIn.isZero()
|
: 'ellipse';
|
||||||
&& Numerical.isZero(Math.abs(handleIn._x) - Math.abs(handleOut._x))
|
|
||||||
&& Numerical.isZero(Math.abs(handleIn._y) - Math.abs(handleOut._y));
|
|
||||||
}
|
|
||||||
if (checkPointValues) {
|
|
||||||
// If the distance between (point0 and point2) and (point1
|
|
||||||
// and point3) are equal, then it is a circle
|
|
||||||
return Numerical.isZero(getDistance(segments, 0, 2)
|
|
||||||
- getDistance(segments, 1, 3))
|
|
||||||
? 'circle'
|
|
||||||
: 'ellipse';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 'path';
|
return 'path';
|
||||||
|
|
Loading…
Reference in a new issue