/* POINT CLASS DEFINITION */ // Point can take either another Point or 2 x and y values _global.Point = function(x,y){ if (arguments.length) this.init.apply(this, arguments); }; Point.getVersion = function(){ return "0.9.1"; }; Point.prototype.init = function(){ this.setPt.apply(this, arguments); ASSetPropFlags(this,"$x,$y",3); return this; }; Point.random = function(x,y){ if (!arguments.length) return new Point(Math.random()*2-1, Math.random()*2-1); var x = (x instanceof Array) ? Math.floor(Math.random()*(x[1]-x[0]+1)) + x[0] : (Math.random()*2-1)*x); var y = (y instanceof Array) ? Math.floor(Math.random()*(y[1]-y[0]+1)) + y[0] : (Math.random()*2-1)*y); return new Point(x, y); }; Point.fromString = function(str){ var a = str.substring(str.indexOf("(")+1, str.indexOf(")")).split(","); return new Point(Number(a[0]), Number(a[1])); }; // Values Point.prototype.toString = function(){ return "Point("+this._x+", "+this._y+")"; }; Point.prototype.valueOf = function(){ return new Boolean(this._x || this._y); }; Point.prototype.setPt = Point.prototype.setTo = function(x, y){ if (x instanceof Point){ this._x = x._x; this._y = x._y; }else{ this._x = x; this._y = y; }; return this; }; Point.prototype.set_x = function(x){ if (this.$restricted.x){ if (x > this.$restricted.xmax) this.$x = this.$restricted.xmax; else if (x < this.$restricted.xmin) this.$x = this.$restricted.xmin; else this.$x = x; }else this.$x = x; return this; } Point.prototype.set_y = function(y){ if (this.$restricted.y){ if (y > this.$restricted.ymax) this.$y = this.$restricted.ymax; else if (y < this.$restricted.ymin) this.$y = this.$restricted.ymin; else this.$y = y; }else this.$y = y; return this; } Point.prototype.get_x = function(){ return this.$x; } Point.prototype.get_y = function(){ return this.$y; } Point.prototype.copy = function(){ return new Point(this._x, this._y); }; Point.prototype.asArray = function(){ return new Array(this._x, this._y); }; // Arithmatic Point.prototype.equals = function(pt){ return (this._x == pt._x && this._y == pt._y); }; Point.prototype.addN = function(n, trans){ if (trans){ this._x += n; this._y += n; return this; }; return new Point(this._x+n, this._y+n); }; Point.prototype.addPt = function(pt, trans){ if (trans){ this._x += pt._x; this._y += pt._y; return this; }; return new Point(this._x+pt._x, this._y+pt._y); }; Point.prototype.subtractN = function(n, trans){ if (trans){ this._x -= n; this._y -= n; return this; }; return new Point(this._x-n, this._y-n); }; Point.prototype.subtractPt = function(pt, trans){ if (trans){ this._x -= pt._x; this._y -= pt._y; return this; }; return new Point(this._x-pt._x, this._y-pt._y); }; Point.prototype.multiplyN = function(n, trans){ if (trans){ this._x *= n; this._y *= n; return this; }; return new Point(this._x*n, this._y*n); }; Point.prototype.multiplyPt = function(pt, trans){ if (trans){ this._x *= pt._x; this._y *= pt._y; return this; }; return new Point(this._x*pt._x, this._y*pt._y); }; Point.prototype.divideN = function(n, trans){ if (trans){ this._x /= n; this._y /= n; return this; }; return new Point(this._x/n, this._y/n); }; Point.prototype.dividePt = function(pt, trans){ if (trans){ this._x /= pt._x; this._y /= pt._y; return this;}; return new Point(this._x/pt._x, this._y/pt._y); }; Point.prototype.modN = function(n, trans){ if (trans){ this._x %= n; this._y %= n; return this;}; return new Point(this._x%n, this._y%n); }; Point.prototype.modPt = function(pt, trans){ if (trans){ this._x %= pt._x; this._y %= pt._y; return this;}; return new Point(this._x%pt._x, this._y%pt._y); }; Point.prototype.round = function(trans){ if (trans){ this._x = Math.round(this._x); this._y = Math.round(this._y); return this; }; return new Point(Math.round(this._x), Math.round(this._y)); }; Point.prototype.floor = function(trans){ if (trans){ this._x = Math.floor(this._x); this._y = Math.floor(this._y); return this; }; return new Point(Math.floor(this._x), Math.floor(this._y)); }; Point.prototype.ceil = function(trans){ if (trans){ this._x = Math.ceil(this._x); this._y = Math.ceil(this._y); return this; }; return new Point(Math.ceil(this._x), Math.ceil(this._y)); }; Point.prototype.abs = function(trans){ if (trans){ this._x = Math.abs(this._x); this._y = Math.abs(this._y); return this; }; return new Point(Math.abs(this._x), Math.abs(this._y)); }; Point.prototype.negate = function(trans){ if (trans){ this._x = -pt._x; this._y = -pt._y; return this;}; return new Point(-this._x, -this._y); }; // Screen Rendering Point.prototype.screenToIso = function(spacing, trans){ if (spacing == undefined) spacing = 1; var xs = this._x/spacing; var ys = this._y/spacing; var x = (xs + 2*ys)/2; var y = (xs - 2*ys)/2; if (trans){ this._x = x; this._y = y; return this; }; return new Point(x,y); }; Point.prototype.isoToScreen = function(spacing, trans){ if (spacing == undefined) spacing = 1; var x = spacing * (this._x + this._y); var y = spacing/2 * (this._x - this._y); if (trans){ this._x = x; this._y = y; return this; }; return new Point(x,y); }; Point.prototype.localToGlobal = function(local, trans){ var pt = {x: this._x, y:this._y}; local.localToGlobal(pt); return (trans) ? this.setPt(pt.x, pt.y) : new Point(pt.x, pt.y); }; Point.prototype.globalToLocal = function(local, trans){ var pt = {x: this._x, y:this._y}; local.globalToLocal(pt); return (trans) ? this.setPt(pt.x, pt.y) : new Point(pt.x, pt.y); }; Point.prototype.localToLocal = function(local1, local2, trans){ var pt = {x: this._x, y:this._y}; local1.localToGlobal(pt); local2.globalToLocal(pt); return (trans) ? this.setPt(pt.x, pt.y) : new Point(pt.x, pt.y); }; Point.prototype.addProperty("_quadrant", function(){ if (!this.valueOf()) return 0; if (this._x > 0){ if (this._y > 0) return 1; else return 4; }else{ if (this._y > 0) return 2; else return 3; } },function(q){ switch(q){ case 0: this.setPt(0,0); break; case 1: if (this._x<0) this._x = -this._x; if (this._y<0) this._y = -this._y; break; case 2: if (this._x>0) this._x = -this._x; if (this._y<0) this._y = -this._y; break; case 3: if (this._x>0) this._x = -this._x; if (this._y>0) this._y = -this._y; break; case 4: if (this._x<0) this._x = -this._x; if (this._y>0) this._y = -this._y; break; } }); // Point Relations Point.prototype.closerTo = function(p1,p2){ var dx = this._x-p1._x, dy = this._y-p1._y; var d1 = dx*dx+dy*dy dx = this._x-p2._x; dy = this._y-p2._y; return (d1 < dx*dx+dy*dy) ? p1 : p2; }; Point.prototype.furtherFrom = function(p1,p2){ var dx = this._x-p1._x, dy = this._y-p1._y; var d1 = dx*dx+dy*dy dx = this._x-p2._x; dy = this._y-p2._y; return (d1 < dx*dx+dy*dy) ? p2 : p1; }; Point.prototype.distanceFrom = function(pt){ var x = pt._x-this._x; var y = pt._y-this._y; return Math.sqrt(x*x + y*y); }; Point.average = function(pts){ var pt = new Point(0,0), L = arguments.length; while(L--) pt.addPt(arguments[L], true); return pt.divideN(arguments.length); }; // Direction, Rotation, Angles Point.directionOf = function(rot){ rot *= Math.PI/180; return new Point(Math.cos(rot), Math.sin(rot)); }; Point.prototype.angleTo = function(pt){ return Math.atan2(pt._y-this._y, pt._x-this._x); }; Point.prototype.rotationTo = function(pt){ return this.angleTo(pt) *180/Math.PI; }; Point.prototype.directionTo = function(pt){ var a = this.angleTo(pt); return new Point(Math.cos(a), Math.sin(a)); }; Point.prototype.angle = function(angle, trans){ var c = Math.cos(angle), s = Math.sin(angle); var x = this._x*c-this._y*s; var y = this._x*s+this._y*c; if (trans) return this.setPt(x,y); return new Point(x,y); }; Point.prototype.rotate = function(rot, trans){ return this.angle(rot*Math.PI/180, trans); }; Point.prototype.getAngle = function(){ return Math.atan2(this._y, this._x); }; Point.prototype.setAngle = function(angle){ var len = this._length; this._x = Math.cos(angle)*len; this._y = Math.sin(angle)*len; return this; }; Point.prototype.getRotation = function(){ return this._angle *180/Math.PI; }; Point.prototype.setRotation = function(rot){ return this.setAngle(rot*Math.PI/180); }; Point.prototype.getDirection = function(){ var a = this._angle; return new Point(Math.cos(a), Math.sin(a)); }; Point.prototype.setDirection = function(dir){ if (dir instanceof Point){ dir = dir._angle; return this.setAngle(dir); } }; Point.prototype.getDistance = function(){ return this.distanceFrom(new Point(0,0)); }; Point.prototype.setDistance = function(d){ var a = this._angle; return this.setPt(Math.cos(a)*d, Math.sin(a)*d); }; Point.prototype.addProperty("_angle", Point.prototype.getAngle, Point.prototype.setAngle); Point.prototype.addProperty("_rotation", Point.prototype.getRotation, Point.prototype.setRotation); Point.prototype.addProperty("_direction", Point.prototype.getDirection, Point.prototype.setDirection); Point.prototype.addProperty("_distance", Point.prototype.getDistance, Point.prototype.setDistance); Point.prototype.closerToDirection = function(d1,d2){ var pi2 = Math.PI*2; var a = this._angle, a1 = d1._angle; var diff = a - a1; if (diff > Math.PI) a1 += pi2; else if (diff < -Math.PI) a1 -= pi2; var dis1 = Math.abs(a1-a); a1 = d2._angle; diff = a - a1; if (diff > Math.PI) a1 += pi2; else if (diff < -Math.PI) a1 -= pi2; return (dis1 < Math.abs(a1-a)) ? d1 : d2; }; Point.prototype.furtherFromDirection = function(d1,d2){ var pi2 = Math.PI*2; var a = this._angle, a1 =d1._angle; var diff = a - a1; if (diff > Math.PI) a1 += pi2; else if (diff < -Math.PI) a1 -= pi2; var d1 = Math.abs(a1-a); a1 = d2._angle; diff = a - a1; if (diff > Math.PI) a1 += pi2; else if (diff < -Math.PI) a1 -= pi2; return (d1 < Math.abs(a1-a)) ? d2 : d1; }; Point.prototype.isBetweenDirections = function(d1,d2){ var a = this._angle, a1 = d1._angle, a2 = d2._angle; if (a1a1 && aa1 || a1) t=1; return p1.addPt( p2.subtractPt(p1).multiplyN(t) ); }; Point.directionBetween = function(d1,d2, t){ if (t == undefined){ if (!(d2 instanceof Point)){ t = d2; d2 = d1; }else t = .5; }else if (t<0) t=0; else if (t>1) t=1; var a1, a2, pi2 = Math.PI*2; if (d1.equals(p2)){ a1 = d1._angle; a2 = a1 + pi2; }else{ a1 = d1._angle; a2 = d2._angle; if (a1<0) a1 += pi2; while (a1>a2) a2 += pi2; }; a1 += (a2-a1)*t; return new Point(Math.cos(a1), Math.sin(a1)); }; Point.prototype.rotateTowardsPoint = function(pt, speed){ var a1 = pt._angle; if (speed == undefined) return this.setAngle(a1); var pi2 = Math.PI*2; var a = this._angle; var diff = a - a1; if (diff > Math.PI) a1 += pi2; else if (diff < -Math.PI) a1 -= pi2; var d1 = Math.abs(a1-a); if (Math.abs(speed) > d1) return this.setAngle(a1); if (a < a1) return this.rotate(speed, true); return this.rotate(-speed, true); }; Point.prototype.moveTowardsPoint = function(pt, speed){ if (this.equals(pt)) return this; var x = pt._x-this._x; var y = pt._y-this._y; var dist = Math.sqrt(x*x + y*y); if (dist <= speed) return this.setPt(pt); var theta = Math.atan2(y, x); return this.addPt(new Point(Math.cos(theta)*speed, Math.sin(theta)*speed), true); }; Point.prototype.moveInDirectionOfPoint = function(dir, speed){ if (speed == undefined) return this.addPt(dir, true); var ratio = speed/dir._length; return this.addPt(dir.multiplyN(ratio), true); }; // Constrain/Restrict Point.prototype.constrain = function(left, top, right, bottom, trans){ if (arguments.length < 4){ if (left instanceof Point){ trans=right; bottom=top; top=left._y; left=left._x; right=bottom._x; bottom=bottom._y; }else{ trans=top; bottom=left.ymax; right=left.xmax; top=left.ymin; left=left.xmin; } } if (trans){ this._x=Math.min(Math.max(left, this._x), right); this._y=Math.min(Math.max(top, this._y), bottom); return this; } return new Point(Math.min(Math.max(left, this._x), right), Math.min(Math.max(top, this._y), bottom)); }; Point.prototype.constrainDirection = function(d1, d2, trans){ // calls _angle twice for each direction with // isBetweenDirections and closerToDirection // could be optimized. if (this.isBetweenDirections(d1, d2)){ if (trans) return this; else return this.copy(); }else{ if (trans) return this.setPt(this.closerToDirection(d1, d2)); else return this.closerToDirection(d1, d2).copy(); }; }; Point.prototype.setRestrict_x = function(min, max){ if (!this.$restricted){ this.$restricted = {}; ASSetPropFlags(this, "$restricted", 7); }; this.$restricted.x = true; if (min != undefined){ this.$restricted.xmin = min; this.$restricted.xmax = (max == undefined) ? min : max; }; }; Point.prototype.setRestrict_y = function(min, max){ if (!this.$restricted){ this.$restricted = {}; ASSetPropFlags(this, "$restricted", 7); } this.$restricted.y = true; if (min != undefined){ this.$restricted.ymin = min; this.$restricted.ymax = (max == undefined) ? min : max; } } Point.prototype.setRestrict = function(minPt, maxPt){ this.setRestrict_x(minPt._x, maxPt._x); this.setRestrict_y(minPt._y, maxPt._y); } Point.prototype.unRestrict_x = function(){ this.$restricted.x = false; } Point.prototype.unRestrict_y = function(){ this.$restricted.y = false; } Point.prototype.unRestrict = function(){ this.unRestrict_y(); this.unRestrict_x(); }; Point.prototype.isRestricted_x = function(){ return new Boolean(this.$restricted.x); }; Point.prototype.isRestricted_y = function(){ return new Boolean(this.$restricted.y); }; Point.prototype.isRestricted = function(){ return new Boolean(this.$restricted.x || this.$restricted.y); }; ASSetPropFlags(Point.prototype,null,7); ASSetPropFlags(Point,null,7); // Point _x/_y Properties Point.prototype.addProperty("_x",Point.prototype.get_x, Point.prototype.set_x); Point.prototype.addProperty("_y",Point.prototype.get_y, Point.prototype.set_y); /* MOVIECLIP EXTENSIONS FOR POINTS */ // Properties MovieClip.prototype.addProperty("_loc", function(){ return new Point(this._x, this._y); },function(pt){ this._x = pt._x; this._y = pt._y; }); MovieClip.prototype.addProperty("_locP", function(){ var mc = this, pt = new Point(this._x, this._y); pt.addProperty("$x", function(){ return mc._x; }, function(x){ mc._x = x; } ); pt.addProperty("$y", function(){ return mc._y; }, function(y){ mc._y = y; } ); return pt; },function(pt){ this._x = pt._x; this._y = pt._y; }); MovieClip.prototype.addProperty("_direction", function(){ return Point.directionOf(this._rotation); },function(d){ this._rotation = d._rotation; }); MovieClip.prototype.addProperty("_mouseLoc", function(){ return new Point(this._xmouse, this._ymouse); },null); MovieClip.prototype.addProperty("_cursorLoc", function(){ return new Point(this._parent._xmouse, this._parent._ymouse); },null); MovieClip.prototype.addProperty("_mouseDirection", function(){ return new this._mouseLoc._direction; },null); MovieClip.prototype.addProperty("_cursorDirection", function(){ return new Point(this._parent._xmouse-this._x, this._parent._ymouse-this._y)._direction; },null); MovieClip.prototype.addProperty("_corners", function(){ var b = this.getBounds(this._parent); var getf, setf, clip = this; var obj = new Object([new Point(b.xmin, b.ymin), new Point(b.xmax, b.ymin), new Point(b.xmax, b.ymax), new Point(b.xmin, b.ymax)]); for (var i=0; i<4; i++){ getf = function(){ return this[arguments.callee.i]; } setf = function(pt){ if (pt instanceof Point == false) return false; clip._loc = clip._loc.subtractPt(this[arguments.callee.i]).addPt(pt); } getf.i = setf.i = i; obj.addProperty(i, getf, setf); } return obj; },null); MovieClip.prototype.addProperty("_center", function(){ var b = this.getBounds(this._parent); return new Point((b.xmax+b.xmin)/2, (b.ymax+b.ymin)/2); },function(pt){ var b = this.getBounds(this._parent); this._x += pt._x - (b.xmax+b.xmin)/2; this._y += pt._y - (b.ymax+b.ymin)/2; }); MovieClip.prototype.addProperty("_left", function(){ return this.getBounds(this._parent).xmin; },function(x){ if (x instanceof Point) this._x += x._x - this.getBounds(this._parent).xmin; else this._x += x - this.getBounds(this._parent).xmin; }); MovieClip.prototype.addProperty("_right", function(){ return this.getBounds(this._parent).xmax; }, function(x){ if (x instanceof Point) this._x += x._x - this.getBounds(this._parent).xmax; else this._x += x - this.getBounds(this._parent).xmax; }); MovieClip.prototype.addProperty("_top", function(){ return this.getBounds(this._parent).ymin; }, function(y){ if (y instanceof Point) this._y += y._y - this.getBounds(this._parent).ymin; else this._y += y - this.getBounds(this._parent).ymin; }); MovieClip.prototype.addProperty("_bottom", function(){ return this.getBounds(this._parent).ymax; }, function(y){ if (y instanceof Point) this._y += y._y - this.getBounds(this._parent).ymax; else this._y += y - this.getBounds(this._parent).ymax; }); // Operations MovieClip.prototype.moveToPt = function(pt){ this.moveTo(pt._x, pt._y); return this; }; MovieClip.prototype.lineToPt = function(pt){ this.lineTo(pt._x, pt._y); return this; }; MovieClip.prototype.lineToPts = function(pts){ if (!(pts instanceof Array)) pts = arguments; var l = pts.length; for (var i=0; i 180) angle += 360; else if (diff < -180) angle -= 360; if (this._rotation < angle) return this._rotation += speed; return this._rotation -= speed; } return this._rotation = this._loc.rotationTo(pt); }; MovieClip.prototype.moveInDirectionOfPoint = function(pt, speed){ if (speed == undefined) return this._loc = this._loc.addPt(pt); var ratio = speed/pt.distanceFrom(new Point(0,0)); return this._loc = this._loc.addPt(pt.multiplyN(ratio)); }; ASSetPropFlags(MovieClip.prototype,null,7);