mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -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() {
|
||||
var angle1 = -Math.atan2(this._b, this._d),
|
||||
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;
|
||||
},
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
*/
|
||||
|
||||
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 = [
|
||||
new Segment([0, 0.5], [0, kappa ], [0, -kappa]),
|
||||
|
|
|
@ -224,44 +224,57 @@ var SvgExporter = this.SvgExporter = new function() {
|
|||
}
|
||||
|
||||
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
|
||||
// between straight objects (line, polyline, rect, and polygon) and
|
||||
// objects with curves(circle, ellipse, roundedRectangle).
|
||||
if (path.isPolygon()) {
|
||||
// If the distance between (point0 and point1) and (point2 and
|
||||
// point3) are equal, then it is a rectangle
|
||||
return segments.length == 4 && Numerical.isZero(
|
||||
getDistance(segments, 0, 1) - getDistance(segments, 3, 2))
|
||||
return segments.length === 4 && path._closed && isOrthogonal(0)
|
||||
&& isOrthogonal(1) && isOrthogonal(2) && isOrthogonal(3)
|
||||
? 'rect'
|
||||
: segments.length >= 3
|
||||
? path._closed ? 'polygon' : 'polyline'
|
||||
: 'line';
|
||||
} else {
|
||||
if (segments.length == 8) {
|
||||
} else if (path._closed) {
|
||||
if (segments.length === 8) {
|
||||
// If the distance between (point0 and point3) and (point7 and
|
||||
// point4) are equal then it is a roundedRectangle
|
||||
if (Numerical.isZero(
|
||||
getDistance(segments, 0, 3) - getDistance(segments, 7, 5)))
|
||||
return 'roundrect';
|
||||
} else if (segments.length == 4) {
|
||||
// Check if the values of the point have values similar to
|
||||
// circles and ellipses.
|
||||
var checkPointValues = true;
|
||||
for (var i = 0; i < segments.length && checkPointValues; i++) {
|
||||
var handleIn = segments[i]._handleIn,
|
||||
handleOut = segments[i]._handleOut;
|
||||
checkPointValues = !handleIn.isZero()
|
||||
&& 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';
|
||||
}
|
||||
} else if (segments.length === 4
|
||||
&& isArc(0) && isArc(1) && isArc(2) && isArc(3)) {
|
||||
// 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';
|
||||
|
|
Loading…
Reference in a new issue