Implement proper index independent argument list reading of basic types.

Implemented for Point, Size, Rectangle and Color.
This commit is contained in:
Jürg Lehni 2012-10-18 14:24:15 -07:00
parent 6f2ff18fa1
commit 30374ae3b4
13 changed files with 260 additions and 190 deletions

View file

@ -34,8 +34,8 @@ var Line = this.Line = Base.extend(/** @lends Line# */{
// intersection outside the line segment are allowed.
// With two parameters, the 2nd parameter is a direction, and infinite
// is automatially true, since we're describing an infinite line.
point1 = Point.read(arguments, 0, 1);
point2 = Point.read(arguments, 1, 1);
point1 = Point.read(arguments);
point2 = Point.read(arguments);
if (arguments.length == 3) {
this.point = point1;
this.vector = point2.subtract(point1);

View file

@ -128,24 +128,20 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{
* @param {Point} [center] The center for the scaling transformation
* @return {Matrix} This affine transform
*/
scale: function(/* scale | */ hor, ver, center) {
if (arguments.length < 2 || typeof ver === 'object') {
// hor is the single scale parameter, representing both hor and ver
// Read center first from argument 1, then set ver = hor (thus
// modifing the content of argument 1!)
center = Point.read(arguments, 1);
ver = hor;
} else {
center = Point.read(arguments, 2);
}
if (center)
this.translate(center);
this._a *= hor;
this._c *= hor;
this._b *= ver;
this._d *= ver;
if (center)
this.translate(center.negate());
scale: function(scale, center) {
// Do not modify scale, center, since that would arguments of which
// we're reading from!
var _scale = Point.read(arguments),
_center = Point.read(arguments);
// TODO: Isn't center always set this way??
if (_center)
this.translate(_center);
this._a *= _scale.x;
this._c *= _scale.x;
this._b *= _scale.y;
this._d *= _scale.y;
if (_center)
this.translate(_center.negate());
return this;
},
@ -168,7 +164,8 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{
*/
translate: function(point) {
point = Point.read(arguments);
var x = point.x, y = point.y;
var x = point.x,
y = point.y;
this._tx += x * this._a + y * this._b;
this._ty += x * this._c + y * this._d;
return this;
@ -219,24 +216,21 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{
* @param {Point} [center] The center for the shear transformation
* @return {Matrix} This affine transform
*/
shear: function(/* point | */ hor, ver, center) {
// See #scale() for explanation of this:
if (arguments.length < 2 || typeof ver === 'object') {
center = Point.read(arguments, 1);
ver = hor;
} else {
center = Point.read(arguments, 2);
}
if (center)
this.translate(center);
shear: function(point, center) {
// Do not modify point, center, since that would arguments of which
// we're reading from!
var _point = Point.read(arguments),
_center = Point.read(arguments);
if (_center)
this.translate(_center);
var a = this._a,
c = this._c;
this._a += ver * this._b;
this._c += ver * this._d;
this._b += hor * a;
this._d += hor * c;
if (center)
this.translate(center.negate());
this._a += _point.y * this._b;
this._c += _point.y * this._d;
this._b += _point.x * a;
this._d += _point.x * c;
if (_center)
this.translate(_center.negate());
return this;
},

View file

@ -28,6 +28,9 @@
* console.log(point.y); // 5
*/
var Point = this.Point = Base.extend(/** @lends Point# */{
// Tell Base.read that the Point constructor supporst reading with index
_readIndex: true,
/**
* Creates a Point object with the given x and y coordinates.
*
@ -132,25 +135,36 @@ var Point = this.Point = Base.extend(/** @lends Point# */{
initialize: function(arg0, arg1) {
var type = typeof arg0;
if (type === 'number') {
var hasY = typeof arg1 === 'number';
this.x = arg0;
this.y = typeof arg1 === 'number' ? arg1 : arg0;
this.y = hasY ? arg1 : arg0;
if (this._read)
this._read = hasY ? 2 : 1;
} else if (type === 'undefined' || arg0 === null) {
this.x = this.y = 0;
} else if (typeof arg0.x !== 'undefined') {
this.x = arg0.x;
this.y = arg0.y;
} else if (Array.isArray(arg0)) {
this.x = arg0[0];
this.y = arg0.length > 1 ? arg0[1] : arg0[0];
} else if (typeof arg0.width !== 'undefined') {
this.x = arg0.width;
this.y = arg0.height;
} else if (typeof arg0.angle !== 'undefined') {
this.x = arg0.length;
this.y = 0;
this.setAngle(arg0.angle);
if (this._read)
this._read = arg0 === null ? 1 : 0;
} else {
this.x = this.y = 0;
if (typeof arg0.x !== 'undefined') {
this.x = arg0.x;
this.y = arg0.y;
} else if (Array.isArray(arg0)) {
this.x = arg0[0];
this.y = arg0.length > 1 ? arg0[1] : arg0[0];
} else if (typeof arg0.width !== 'undefined') {
this.x = arg0.width;
this.y = arg0.height;
} else if (typeof arg0.angle !== 'undefined') {
this.x = arg0.length;
this.y = 0;
this.setAngle(arg0.angle);
} else {
this.x = this.y = 0;
if (this._read)
this._read = 0;
}
if (this._read)
this._read = 1;
}
},
@ -787,11 +801,11 @@ var Point = this.Point = Base.extend(/** @lends Point# */{
* console.log(minPoint); // {x: 10, y: 5}
*/
min: function(point1, point2) {
point1 = Point.read(arguments, 0, 1);
point2 = Point.read(arguments, 1, 1);
var _point1 = Point.read(arguments);
_point2 = Point.read(arguments);
return Point.create(
Math.min(point1.x, point2.x),
Math.min(point1.y, point2.y)
Math.min(_point1.x, _point2.x),
Math.min(_point1.y, _point2.y)
);
},
@ -811,11 +825,11 @@ var Point = this.Point = Base.extend(/** @lends Point# */{
* console.log(maxPoint); // {x: 200, y: 100}
*/
max: function(point1, point2) {
point1 = Point.read(arguments, 0, 1);
point2 = Point.read(arguments, 1, 1);
var _point1 = Point.read(arguments);
_point2 = Point.read(arguments);
return Point.create(
Math.max(point1.x, point2.x),
Math.max(point1.y, point2.y)
Math.max(_point1.x, _point2.x),
Math.max(_point1.y, _point2.y)
);
},

View file

@ -22,6 +22,9 @@
* rectangular path, it is not an item.
*/
var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{
// Tell Base.read that the Rectangle constructor supporst reading with index
_readIndex: true,
/**
* Creates a Rectangle object.
*
@ -54,21 +57,34 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{
* @param {Rectangle} rt
*/
initialize: function(arg0, arg1, arg2, arg3) {
if (arguments.length == 4) {
var type = typeof arg0;
if (type === 'number') {
// new Rectangle(x, y, width, height)
this.x = arg0;
this.y = arg1;
this.width = arg2;
this.height = arg3;
} else if (arguments.length == 2) {
if (arg1 && arg1.x !== undefined) {
if (this._read)
this._read = 4;
} else if (type === 'undefined' || arg0 === null) {
// new Rectangle(), new Rectangle(null)
this.x = this.y = this.width = this.height = 0;
if (this._read)
this._read = arg0 === null ? 1 : 0;
} else if (arguments.length > 1 && typeof arg0.width === 'undefined') {
// We're checking arg0.width to rule out Rectangles, which are
// handled separately below.
// Read a point argument and look at the next value to see wether
// it's a size or a point, then read accordingly
var point = Point.read(arguments),
next = Base.peekValue(arguments);
this.x = point.x;
this.y = point.y;
if (next && next.x !== undefined) {
// new Rectangle(point1, point2)
var point1 = Point.read(arguments, 0, 1);
var point2 = Point.read(arguments, 1, 1);
this.x = point1.x;
this.y = point1.y;
this.width = point2.x - point1.x;
this.height = point2.y - point1.y;
var point2 = Point.read(arguments);
this.width = point2.x - point.x;
this.height = point2.y - point.y;
if (this.width < 0) {
this.x = point2.x;
this.width = -this.width;
@ -79,22 +95,22 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{
}
} else {
// new Rectangle(point, size)
var point = Point.read(arguments, 0, 1);
var size = Size.read(arguments, 1, 1);
this.x = point.x;
this.y = point.y;
var size = Size.read(arguments);
this.width = size.width;
this.height = size.height;
}
if (this._read)
this._read = arguments._index;
} else if (arg0) {
// Use 0 as defaults, in case we're reading from a Point or Size
// new Rectangle(rect)
// Use 0 as defaults, in case we're not reading from a Rectangle,
// but a Point or Size instead
this.x = arg0.x || 0;
this.y = arg0.y || 0;
this.width = arg0.width || 0;
this.height = arg0.height || 0;
} else {
// new Rectangle()
this.x = this.y = this.width = this.height = 0;
if (this._read)
this._read = 1;
}
},

View file

@ -27,6 +27,9 @@
* console.log(size.height); // 5
*/
var Size = this.Size = Base.extend(/** @lends Size# */{
// Tell Base.read that the Point constructor supporst reading with index
_readIndex: true,
// DOCS: improve Size class description
/**
* Creates a Size object with the given width and height values.
@ -91,28 +94,34 @@ var Size = this.Size = Base.extend(/** @lends Size# */{
* console.log(size.height); // 50
*/
initialize: function(arg0, arg1) {
if (arg1 !== undefined) {
var type = typeof arg0;
if (type === 'number') {
var hasHeight = typeof arg1 === 'number';
this.width = arg0;
this.height = arg1;
} else if (arg0 !== undefined) {
if (arg0 == null) {
this.width = this.height = 0;
} else if (arg0.width !== undefined) {
this.height = hasHeight ? arg1 : arg0;
if (this._read)
this._read = hasHeight ? 2 : 1;
} else if (type === 'undefined' || arg0 === null) {
this.width = this.height = 0;
if (this._read)
this._read = arg0 === null ? 1 : 0;
} else {
if (typeof arg0.width !== 'undefined') {
this.width = arg0.width;
this.height = arg0.height;
} else if (arg0.x !== undefined) {
this.width = arg0.x;
this.height = arg0.y;
} else if (Array.isArray(arg0)) {
this.width = arg0[0];
this.height = arg0.length > 1 ? arg0[1] : arg0[0];
} else if (typeof arg0 === 'number') {
this.width = this.height = arg0;
} else if (typeof arg0.x !== 'undefined') {
this.width = arg0.x;
this.height = arg0.y;
} else {
this.width = this.height = 0;
if (this._read)
this._read = 0;
}
} else {
this.width = this.height = 0;
if (this._read)
this._read = 1;
}
},

View file

@ -207,16 +207,20 @@ var Color = this.Color = Base.extend(new function() {
};
var fields = /** @lends Color# */{
// Tell Base.read that we do not want null to be converted to a color.
_readNull: true,
// Tell Base.read that the Point constructor supporst reading with index
_readIndex: true,
initialize: function(arg) {
var isArray = Array.isArray(arg),
type = this._colorType;
type = this._colorType,
res;
if (typeof arg === 'object' && !isArray) {
if (!type) {
// Called on the abstract Color class. Guess color type
// from arg
return arg.red !== undefined
res = arg.red !== undefined
? new RgbColor(arg.red, arg.green, arg.blue, arg.alpha)
: arg.gray !== undefined
? new GrayColor(arg.gray, arg.alpha)
@ -227,33 +231,41 @@ var Color = this.Color = Base.extend(new function() {
? new HsbColor(arg.hue, arg.saturation, arg.brightness,
arg.alpha)
: new RgbColor(); // Fallback
if (this._read)
res._read = 1;
} else {
// Called on a subclass instance. Return the converted
// color.
return Color.read(arguments).convert(type);
res = Color.read(arguments).convert(type);
if (this._read)
res._read = arguments._read;
}
} else if (typeof arg === 'string') {
var rgbColor = arg.match(/^#[0-9a-f]{3,6}$/i)
? hexToRgbColor(arg)
: nameToRgbColor(arg);
return type
res = type
? rgbColor.convert(type)
: rgbColor;
if (this._read)
res._read = 1;
} else {
var components = isArray ? arg
: Array.prototype.slice.call(arguments);
if (!type) {
// Called on the abstract Color class. Guess color type
// from arg
//if (components.length >= 4)
// return new CmykColor(components);
if (components.length >= 3)
return new RgbColor(components);
return new GrayColor(components);
// var ctor = components.length >= 4
// ? CmykColor
// : components.length >= 3
var ctor = components.length >= 3
? RgbColor
: GrayColor;
res = new ctor(components);
} else {
// Called on a subclass instance. Just copy over
// components.
Base.each(this._components,
res = Base.each(this._components,
function(name, i) {
var value = components[i];
// Set internal propery directly
@ -262,7 +274,10 @@ var Color = this.Color = Base.extend(new function() {
},
this);
}
if (this._read)
res._read = res._components.length;
}
return res;
},
/**

View file

@ -63,18 +63,45 @@ this.Base = Base.inject(/** @lends Base# */{
* cloned if they are already provided in the required type
*/
read: function(list, start, length, clone) {
var start = start || 0,
length = length || list.length - start;
var obj = list[start];
var proto = this.prototype,
readIndex = proto._readIndex,
index = start || readIndex && list._index || 0;
if (!length)
length = list.length - index;
var obj = list[index];
if (obj instanceof this
// If the class defines _readNull, return null when nothing
// was provided
|| this.prototype._readNull && obj == null && length <= 1)
|| proto._readNull && obj == null && length <= 1) {
if (readIndex)
list._index = index + 1;
return obj && clone ? obj.clone() : obj;
}
obj = new this(this.dont);
return obj.initialize.apply(obj, start > 0 || length < list.length
? Array.prototype.slice.call(list, start, start + length)
if (readIndex)
obj._read = true;
obj = obj.initialize.apply(obj, index > 0 || length < list.length
? Array.prototype.slice.call(list, index, index + length)
: list) || obj;
if (readIndex) {
list._index = index + obj._read;
// Have arguments._read point to the amount of args read in the
// last read() call
list._read = obj._read;
delete obj._read;
}
return obj;
},
peekValue: function(list, start) {
return list[list._index = start || list._index || 0];
},
readValue: function(list, start) {
var value = this.peekValue(list, start);
list._index++;
list._read = 1;
return value;
},
/**

View file

@ -107,10 +107,9 @@ HitResult = Base.extend(/** @lends HitResult# */{
* @private
*/
getOptions: function(point, options) {
// Use _merged property to not repeatetly call merge in recursion.
return options && options._merged ? options : Base.merge({
// Use the converted options object to perform point conversion
// only once.
point: Point.read(arguments, 0, 1),
point: Point.read([point]),
// Type of item, for instanceof check: PathItem, TexItem, etc
type: null,
// Tolerance

View file

@ -115,7 +115,7 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
this._matrix = pointOrMatrix !== undefined
? pointOrMatrix instanceof Matrix
? pointOrMatrix.clone()
: new Matrix().translate(Point.read(arguments, 0))
: new Matrix().translate(Point.read(arguments))
: new Matrix();
},

View file

@ -338,17 +338,16 @@ var Raster = this.Raster = PlacedItem.extend(/** @lends Raster# */{
* @param color the color that the pixel will be set to
*/
setPixel: function(point, color) {
var hasPoint = arguments.length == 2;
point = Point.read(arguments, 0, hasPoint ? 1 : 2);
color = Color.read(arguments, hasPoint ? 1 : 2);
var _point = Point.read(arguments),
_color = Color.read(arguments);
var ctx = this.getContext(true),
imageData = ctx.createImageData(1, 1),
alpha = color.getAlpha();
imageData.data[0] = color.getRed() * 255;
imageData.data[1] = color.getGreen() * 255;
imageData.data[2] = color.getBlue() * 255;
imageData.data[0] = _color.getRed() * 255;
imageData.data[1] = _color.getGreen() * 255;
imageData.data[2] = _color.getBlue() * 255;
imageData.data[3] = alpha != null ? alpha * 255 : 255;
ctx.putImageData(imageData, point.x, point.y);
ctx.putImageData(imageData, _point.x, _point.y);
},
// DOCS: document Raster#createData

View file

@ -41,10 +41,9 @@ Path.inject({ statics: new function() {
* path.strokeColor = 'black';
*/
Line: function() {
var step = Math.floor(arguments.length / 2);
return new Path(
Segment.read(arguments, 0, step),
Segment.read(arguments, step, step)
Point.read(arguments),
Point.read(arguments)
);
},
@ -125,32 +124,27 @@ Path.inject({ statics: new function() {
* var path = new Path.RoundRectangle(rectangle, cornerSize);
*/
RoundRectangle: function(rect, size) {
if (arguments.length == 2) {
rect = Rectangle.read(arguments, 0, 1);
size = Size.read(arguments, 1, 1);
} else if (arguments.length == 6) {
rect = Rectangle.read(arguments, 0, 4);
size = Size.read(arguments, 4, 2);
}
size = Size.min(size, rect.getSize(true).divide(2));
var path = new Path(),
uSize = size.multiply(kappa * 2),
bl = rect.getBottomLeft(true),
tl = rect.getTopLeft(true),
tr = rect.getTopRight(true),
br = rect.getBottomRight(true);
var _rect = Rectangle.read(arguments),
_size = Size.min(Size.read(arguments),
_rect.getSize(true).divide(2)),
path = new Path(),
uSize = _size.multiply(kappa * 2),
bl = _rect.getBottomLeft(true),
tl = _rect.getTopLeft(true),
tr = _rect.getTopRight(true),
br = _rect.getBottomRight(true);
path._add([
new Segment(bl.add(size.width, 0), null, [-uSize.width, 0]),
new Segment(bl.subtract(0, size.height), [0, uSize.height], null),
new Segment(bl.add(_size.width, 0), null, [-uSize.width, 0]),
new Segment(bl.subtract(0, _size.height), [0, uSize.height], null),
new Segment(tl.add(0, size.height), null, [0, -uSize.height]),
new Segment(tl.add(size.width, 0), [-uSize.width, 0], null),
new Segment(tl.add(0, _size.height), null, [0, -uSize.height]),
new Segment(tl.add(_size.width, 0), [-uSize.width, 0], null),
new Segment(tr.subtract(size.width, 0), null, [uSize.width, 0]),
new Segment(tr.add(0, size.height), [0, -uSize.height], null),
new Segment(tr.subtract(_size.width, 0), null, [uSize.width, 0]),
new Segment(tr.add(0, _size.height), [0, -uSize.height], null),
new Segment(br.subtract(0, size.height), null, [0, uSize.height]),
new Segment(br.subtract(size.width, 0), [uSize.width, 0], null)
new Segment(br.subtract(0, _size.height), null, [0, uSize.height]),
new Segment(br.subtract(_size.width, 0), [uSize.width, 0], null)
]);
path._closed = true;
return path;
@ -204,14 +198,10 @@ Path.inject({ statics: new function() {
* var path = new Path.Circle(new Point(100, 100), 50);
*/
Circle: function(center, radius) {
if (arguments.length == 3) {
center = Point.read(arguments, 0, 2);
radius = arguments[2];
} else {
center = Point.read(arguments, 0, 1);
}
return Path.Oval(new Rectangle(center.subtract(radius),
Size.create(radius * 2, radius * 2)));
var _center = Point.read(arguments),
_radius = Base.readValue(arguments);
return Path.Oval(new Rectangle(_center.subtract(_radius),
Size.create(_radius * 2, _radius * 2)));
},
/**
@ -261,15 +251,17 @@ Path.inject({ statics: new function() {
* decahedron.fillColor = 'black';
*/
RegularPolygon: function(center, numSides, radius) {
center = Point.read(arguments, 0, 1);
var path = new Path(),
step = 360 / numSides,
three = !(numSides % 3),
vector = new Point(0, three ? -radius : radius),
var _center = Point.read(arguments),
_numSides = Base.readValue(arguments),
_radius = Base.readValue(arguments),
path = new Path(),
step = 360 / _numSides,
three = !(_numSides % 3),
vector = new Point(0, three ? -_radius : _radius),
offset = three ? -1 : 0.5,
segments = new Array(numSides);
for (var i = 0; i < numSides; i++) {
segments[i] = new Segment(center.add(
segments = new Array(_numSides);
for (var i = 0; i < _numSides; i++) {
segments[i] = new Segment(_center.add(
vector.rotate((i + offset) * step)));
}
path._add(segments);
@ -299,15 +291,17 @@ Path.inject({ statics: new function() {
* path.fillColor = 'black';
*/
Star: function(center, numPoints, radius1, radius2) {
center = Point.read(arguments, 0, 1);
numPoints *= 2;
var path = new Path(),
step = 360 / numPoints,
var _center = Point.read(arguments),
_numPoints = Base.readValue(arguments) * 2,
_radius1 = Base.readValue(arguments),
_radius2 = Base.readValue(arguments),
path = new Path(),
step = 360 / _numPoints,
vector = new Point(0, -1),
segments = new Array(numPoints);
for (var i = 0; i < numPoints; i++) {
segments[i] = new Segment(center.add(
vector.rotate(step * i).multiply(i % 2 ? radius2 : radius1)));
segments = new Array(_numPoints);
for (var i = 0; i < _numPoints; i++) {
segments[i] = new Segment(_center.add(
vector.rotate(step * i).multiply(i % 2 ? _radius2 : _radius1)));
}
path._add(segments);
path._closed = true;

View file

@ -1667,20 +1667,20 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
},
cubicCurveTo: function(handle1, handle2, to) {
handle1 = Point.read(arguments, 0, 1);
handle2 = Point.read(arguments, 1, 1);
to = Point.read(arguments, 2, 1);
var _handle1 = Point.read(arguments);
_handle2 = Point.read(arguments);
_to = Point.read(arguments);
// First modify the current segment:
var current = getCurrentSegment(this);
// Convert to relative values:
current.setHandleOut(handle1.subtract(current._point));
current.setHandleOut(_handle1.subtract(current._point));
// And add the new segment, with handleIn set to c2
this._add([ new Segment(to, handle2.subtract(to)) ]);
this._add([ new Segment(_to, _handle2.subtract(to)) ]);
},
quadraticCurveTo: function(handle, to) {
handle = Point.read(arguments, 0, 1);
to = Point.read(arguments, 1, 1);
var _handle = Point.read(arguments),
to = Point.read(arguments);
// This is exact:
// If we have the three quad points: A E D,
// and the cubic is A B C D,
@ -1688,26 +1688,26 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
// C = E + 1/3 (D - E)
var current = getCurrentSegment(this)._point;
this.cubicCurveTo(
handle.add(current.subtract(handle).multiply(1/3)),
handle.add(to.subtract(handle).multiply(1/3)),
to
_handle.add(current.subtract(_handle).multiply(1 / 3)),
_handle.add(to.subtract(_handle).multiply(1 / 3)),
_to
);
},
curveTo: function(through, to, parameter) {
through = Point.read(arguments, 0, 1);
to = Point.read(arguments, 1, 1);
var t = Base.pick(parameter, 0.5),
var _through = Point.read(arguments),
_to = Point.read(arguments),
t = Base.pick(Base.readValue(arguments), 0.5),
t1 = 1 - t,
current = getCurrentSegment(this)._point,
// handle = (through - (1 - t)^2 * current - t^2 * to) /
// (2 * (1 - t) * t)
handle = through.subtract(current.multiply(t1 * t1))
.subtract(to.multiply(t * t)).divide(2 * t * t1);
handle = _through.subtract(current.multiply(t1 * t1))
.subtract(_to.multiply(t * t)).divide(2 * t * t1);
if (handle.isNaN())
throw new Error(
'Cannot put a curve through points with parameter = ' + t);
this.quadraticCurveTo(handle, to);
this.quadraticCurveTo(handle, _to);
},
// PORT: New implementation back to Scriptographer
@ -1715,17 +1715,20 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
// Get the start point:
var current = getCurrentSegment(this),
from = current._point,
through;
if (clockwise === undefined)
clockwise = true;
if (typeof clockwise === 'boolean') {
to = Point.read(arguments, 0, 1);
through,
point = Point.read(arguments),
next = Base.peekValue(arguments);
if (/boolean|undefined/.test(typeof next)) {
// arcTo(to, clockwise)
to = point;
clockwise = next;
var middle = from.add(to).divide(2),
through = middle.add(middle.subtract(from).rotate(
clockwise ? -90 : 90));
} else {
through = Point.read(arguments, 0, 1);
to = Point.read(arguments, 1, 1);
// arcTo(through, to)
through = point;
to = Point.read(arguments);
}
// Construct the two perpendicular middle lines to (from, through)
// and (through, to), and intersect them to get the center

View file

@ -73,7 +73,7 @@ var SegmentPoint = Point.extend({
} else {
// If not Point-like already, read Point from pt = 3rd argument
if ((x = pt.x) === undefined) {
pt = Point.read(arguments, 2, 1);
pt = Point.read(arguments, 2);
x = pt.x;
}
y = pt.y;