module.exports = { Timer: class{ constructor(second) { this.interval = second * 1000; this.nextTiming(); } get isDue(){ return new Date().getTime() - this.date.getTime() >= this.interval; } nextTiming(){ this.date = new Date(); } tryNextTiming(){ if(!this.isDue){ return false; } this.nextTiming(); return true; } }, FixedTimer:class{ constructor(fps) { this.fps = fps; this.updateInterval = 1000.0/fps; this.remainder = 0; this.nextTiming(); } nextTiming(){ this.date = new Date(); } fixedUpdateTimes(){ var newTime = new Date(); var interval = newTime.getTime() - this.date.getTime() + this.remainder; this.date = newTime; this.remainder = interval % this.updateInterval; return parseInt(interval / this.updateInterval); } }, FixedTimerDT:class{ constructor(fps) { this.fps = fps; this.updateInterval = 1000.0/fps; this.remainder = 0; } fixedUpdateTimes(dt){//time in second var interval = dt*1000 + this.remainder; this.remainder = interval % this.updateInterval; //cc.log(parseInt(interval / this.updateInterval)); return parseInt(interval / this.updateInterval); } }, QuadraticEquation: class{ constructor(x1,y1,x2,y2,x3,y3){ this.a = y1 / (x1 - x2) / (x1 - x3) + y2 / (x2 - x1) / (x2 - x3) + y3 / (x3 - x1) / (x3 - x2); this.b = -y1 * (x2 + x3) / (x1 - x2) / (x1 - x3) - y2 * (x1 + x3) / (x2 - x1) / (x2 - x3) - y3 * (x1 + x2) / (x3 - x1) / (x3 - x2); this.c = y1 * x2 * x3 / (x1 - x2) / (x1 - x3) + y2 * x1 * x3 / (x2 - x1) / (x2 - x3) + y3 * x1 * x2 / (x3 - x1) / (x3 - x2); } y(x){ //console.log(this.a+" "+this.b+" "+this.c); return this.a*x*x +this.b*x +this.c; } }, Vector2: class{ constructor() { switch(arguments.length) { default:    case 1:       this.x = arguments[0].x;       this.y = arguments[0].y;      break;    case 2:       this.x = arguments[0];       this.y = arguments[1];      break; } } get length(){ if(this.x == 0 && this.y == 0) return 0; return Math.sqrt(this.x*this.x+this.y*this.y); }/** */ get mod(){ var length = this.length; return new this.constructor(this.x/length,this.y/length); }/**/ radian(anotherVector){//都必须是长度为1的vector return Math.asin(Math.sqrt(Math.pow(this.x - anotherVector.x,2)+Math.pow(this.y - anotherVector.y,2))/2)*2; } angle(anotherModVector){ return this.radian(anotherModVector)/Math.PI*180; } rotate(radian){ var cosRadian = Math.cos(radian); var sinRadian = Math.sin(radian); return new this.constructor(this.x * cosRadian + this.y * sinRadian, this.y * cosRadian - this.x * sinRadian); } rotateAngle(angle){ return this.rotate(angle / 180 * Math.PI); } plus(anotherVector){ return new this.constructor(this.x + anotherVector.x, this.y + anotherVector.y); } minus(anotherVector){ return new this.constructor(this.x - anotherVector.x, this.y - anotherVector.y); } multiply(num){ return new this.constructor(this.x * num, this.y * num); } toLength(length){ var mod = this.mod; return new this.constructor(mod.x * length, mod.y * length); } }, Line2:class{ constructor() { switch(arguments.length) { default:    case 1:       this.a = arguments[0].a;       this.b = arguments[0].b;      break;    case 2:       this.a = arguments[0];       this.b = arguments[1];      break;    case 4:       this.a = new module.exports.Vector2(arguments[0],arguments[1]);       this.b = new module.exports.Vector2(arguments[2],arguments[3]);      break; } } vertex(index){ switch(index){ default: case 0: return this.a; case 1: return this.b; } } get vector(){ return this.b.minus(this.a); } get length(){ return this.vector.length; } }, Rect:class{ constructor() { switch(arguments.length) { default:    case 1:       this.position = arguments[0].position;       this.size = arguments[0].size;      break;    case 2:       this.position = arguments[0];       this.size = arguments[1];      break;    case 4:       this.position = new module.exports.Vector2(arguments[0],arguments[1]);       this.size = new module.exports.Vector2(arguments[2],arguments[3]);      break; } } vertex(index){ switch(index){ default: case 0: return this.position; case 1: return new module.exports.Vector2(this.position.x,this.position.y+this.size.y); case 2: return this.position.plus(this.size); case 3: return new module.exports.Vector2(this.position.x+this.size.x,this.position.y); } }//Clockwise edge(index){ switch(index){ default: case 0: return new module.exports.Line2(this.vertex(0),this.vertex(1)); case 1: return new module.exports.Line2(this.vertex(1),this.vertex(2)); case 2: return new module.exports.Line2(this.vertex(2),this.vertex(3)); case 3: return new module.exports.Line2(this.vertex(3),this.vertex(0)); } }//Clockwise get vertexs(){ var edges = []; for(var i = 0;i<4;++i){ edges.push(this.vertex(i)); } return edges; } get edges(){ var edges = []; for(var i = 0;i<4;++i){ edges.push(this.edge(i)); } return edges; } get pos(){ return this.position; } set pos(value){ this.position = value; } get x(){ return this.position.x; } set x(value){ this.position.x = value; } get y(){ return this.position.y; } set y(value){ this.position.y = value; } get width(){ return this.size.x; } set width(value){ this.size.x = value; } get height(){ return this.size.y; } set height(value){ this.size.y = value; } }, Vector3: class{ constructor() { switch(arguments.length) { default: case 1: this.x = arguments[0].x; this.y = arguments[0].y; this.z = arguments[0].z; break; case 3: this.x = arguments[0]; this.y = arguments[1]; this.z = arguments[2]; break; } } get length(){ if(this.x == 0 && this.y == 0 && this.z == 0) return 0; return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z); }/** */ get mod(){ var length = this.length; return new this.constructor(this.x/length,this.y/length,this.z/length); } plus(anotherVector){ return new this.constructor(this.x + anotherVector.x, this.y + anotherVector.y, this.z + anotherVector.z); } minus(anotherVector){ return new this.constructor(this.x - anotherVector.x, this.y - anotherVector.y, this.z - anotherVector.z); } multiply(num){ return new this.constructor(this.x * num, this.y * num, this.z * num); } toLength(length){ var mod = this.mod; return new this.constructor(mod.x * length, mod.y * length, mod.z * length); } }, isSameSign:function(a,b){ if((a>=0&&b>=0)||(a<=0&&b<=0)){ return true; } return false; }, distance2:function(a,b){ var distance = Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2)); switch(arguments.length) { default: case 2: return distance; case 3: var vector = arguments[2];//vector must be in same line with a b if(module.exports.isSameSign(b.x - a.x,vector.x)&&module.exports.isSameSign(b.y - a.y,vector.y)){ return distance; }else{ return -distance; } } }, maxLengthLine2:function(vertexs){ if(vertexs.length==0){ return null; } if(vertexs.length==1){ return new module.exports.Line2(vertexs[0],vertexs[0]); } var maxLengthLine = null; var maxLength = -1; for(var i = 0;i=acceptableError&&v2.length>=acceptableError){//存在计算误差 return false; } return true; }, lineSegmentInRect(rect,line){ var edge = rect.edges; var ip = []; for(var i = 0;i module.exports.distance2(ip[1],ip[3])){ ip = [ip[0],ip[2],ip[1],ip[3]];//verticalBegin;verticalEnd;horizontalBegin;horizontalEnd; }else{ ip = [ip[1],ip[3],ip[0],ip[2]];//verticalBegin;verticalEnd;horizontalBegin;horizontalEnd; } var pos = []; var verticalPoints = module.exports.arrangeInLine2(ip[0],ip[1],origin,verticalVector); for(var i = 0; i