o0.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. module.exports = {
  2. Timer: class{
  3. constructor(second) {
  4. this.interval = second * 1000;
  5. this.nextTiming();
  6. }
  7. get isDue(){
  8. return new Date().getTime() - this.date.getTime() >= this.interval;
  9. }
  10. nextTiming(){
  11. this.date = new Date();
  12. }
  13. tryNextTiming(){
  14. if(!this.isDue){
  15. return false;
  16. }
  17. this.nextTiming();
  18. return true;
  19. }
  20. },
  21. FixedTimer:class{
  22. constructor(fps) {
  23. this.fps = fps;
  24. this.updateInterval = 1000.0/fps;
  25. this.remainder = 0;
  26. this.nextTiming();
  27. }
  28. nextTiming(){
  29. this.date = new Date();
  30. }
  31. fixedUpdateTimes(){
  32. var newTime = new Date();
  33. var interval = newTime.getTime() - this.date.getTime() + this.remainder;
  34. this.date = newTime;
  35. this.remainder = interval % this.updateInterval;
  36. return parseInt(interval / this.updateInterval);
  37. }
  38. },
  39. FixedTimerDT:class{
  40. constructor(fps) {
  41. this.fps = fps;
  42. this.updateInterval = 1000.0/fps;
  43. this.remainder = 0;
  44. }
  45. fixedUpdateTimes(dt){//time in second
  46. var interval = dt*1000 + this.remainder;
  47. this.remainder = interval % this.updateInterval;
  48. //cc.log(parseInt(interval / this.updateInterval));
  49. return parseInt(interval / this.updateInterval);
  50. }
  51. },
  52. QuadraticEquation: class{
  53. constructor(x1,y1,x2,y2,x3,y3){
  54. this.a = y1 / (x1 - x2) / (x1 - x3) + y2 / (x2 - x1) / (x2 - x3) + y3 / (x3 - x1) / (x3 - x2);
  55. this.b = -y1 * (x2 + x3) / (x1 - x2) / (x1 - x3) - y2 * (x1 + x3) / (x2 - x1) / (x2 - x3) - y3 * (x1 + x2) / (x3 - x1) / (x3 - x2);
  56. this.c = y1 * x2 * x3 / (x1 - x2) / (x1 - x3) + y2 * x1 * x3 / (x2 - x1) / (x2 - x3) + y3 * x1 * x2 / (x3 - x1) / (x3 - x2);
  57. }
  58. y(x){
  59. //console.log(this.a+" "+this.b+" "+this.c);
  60. return this.a*x*x +this.b*x +this.c;
  61. }
  62. },
  63. Vector2: class{
  64. constructor() {
  65. switch(arguments.length) {
  66. default:
  67.    case 1:
  68.       this.x = arguments[0].x;
  69.       this.y = arguments[0].y;
  70.      break;
  71.    case 2:
  72.       this.x = arguments[0];
  73.       this.y = arguments[1];
  74.      break;
  75. }
  76. }
  77. get length(){
  78. if(this.x == 0 && this.y == 0)
  79. return 0;
  80. return Math.sqrt(this.x*this.x+this.y*this.y);
  81. }/** */
  82. get mod(){
  83. var length = this.length;
  84. return new this.constructor(this.x/length,this.y/length);
  85. }/**/
  86. radian(anotherVector){//都必须是长度为1的vector
  87. return Math.asin(Math.sqrt(Math.pow(this.x - anotherVector.x,2)+Math.pow(this.y - anotherVector.y,2))/2)*2;
  88. }
  89. angle(anotherModVector){
  90. return this.radian(anotherModVector)/Math.PI*180;
  91. }
  92. rotate(radian){
  93. var cosRadian = Math.cos(radian);
  94. var sinRadian = Math.sin(radian);
  95. return new this.constructor(this.x * cosRadian + this.y * sinRadian, this.y * cosRadian - this.x * sinRadian);
  96. }
  97. rotateAngle(angle){
  98. return this.rotate(angle / 180 * Math.PI);
  99. }
  100. plus(anotherVector){
  101. return new this.constructor(this.x + anotherVector.x, this.y + anotherVector.y);
  102. }
  103. minus(anotherVector){
  104. return new this.constructor(this.x - anotherVector.x, this.y - anotherVector.y);
  105. }
  106. multiply(num){
  107. return new this.constructor(this.x * num, this.y * num);
  108. }
  109. toLength(length){
  110. var mod = this.mod;
  111. return new this.constructor(mod.x * length, mod.y * length);
  112. }
  113. },
  114. Line2:class{
  115. constructor() {
  116. switch(arguments.length) {
  117. default:
  118.    case 1:
  119.       this.a = arguments[0].a;
  120.       this.b = arguments[0].b;
  121.      break;
  122.    case 2:
  123.       this.a = arguments[0];
  124.       this.b = arguments[1];
  125.      break;
  126.    case 4:
  127.       this.a = new module.exports.Vector2(arguments[0],arguments[1]);
  128.       this.b = new module.exports.Vector2(arguments[2],arguments[3]);
  129.      break;
  130. }
  131. }
  132. vertex(index){
  133. switch(index){
  134. default:
  135. case 0:
  136. return this.a;
  137. case 1:
  138. return this.b;
  139. }
  140. }
  141. get vector(){
  142. return this.b.minus(this.a);
  143. }
  144. get length(){
  145. return this.vector.length;
  146. }
  147. },
  148. Rect:class{
  149. constructor() {
  150. switch(arguments.length) {
  151. default:
  152.    case 1:
  153.       this.position = arguments[0].position;
  154.       this.size = arguments[0].size;
  155.      break;
  156.    case 2:
  157.       this.position = arguments[0];
  158.       this.size = arguments[1];
  159.      break;
  160.    case 4:
  161.       this.position = new module.exports.Vector2(arguments[0],arguments[1]);
  162.       this.size = new module.exports.Vector2(arguments[2],arguments[3]);
  163.      break;
  164. }
  165. }
  166. vertex(index){
  167. switch(index){
  168. default:
  169. case 0:
  170. return this.position;
  171. case 1:
  172. return new module.exports.Vector2(this.position.x,this.position.y+this.size.y);
  173. case 2:
  174. return this.position.plus(this.size);
  175. case 3:
  176. return new module.exports.Vector2(this.position.x+this.size.x,this.position.y);
  177. }
  178. }//Clockwise
  179. edge(index){
  180. switch(index){
  181. default:
  182. case 0:
  183. return new module.exports.Line2(this.vertex(0),this.vertex(1));
  184. case 1:
  185. return new module.exports.Line2(this.vertex(1),this.vertex(2));
  186. case 2:
  187. return new module.exports.Line2(this.vertex(2),this.vertex(3));
  188. case 3:
  189. return new module.exports.Line2(this.vertex(3),this.vertex(0));
  190. }
  191. }//Clockwise
  192. get vertexs(){
  193. var edges = [];
  194. for(var i = 0;i<4;++i){
  195. edges.push(this.vertex(i));
  196. }
  197. return edges;
  198. }
  199. get edges(){
  200. var edges = [];
  201. for(var i = 0;i<4;++i){
  202. edges.push(this.edge(i));
  203. }
  204. return edges;
  205. }
  206. get pos(){
  207. return this.position;
  208. }
  209. set pos(value){
  210. this.position = value;
  211. }
  212. get x(){
  213. return this.position.x;
  214. }
  215. set x(value){
  216. this.position.x = value;
  217. }
  218. get y(){
  219. return this.position.y;
  220. }
  221. set y(value){
  222. this.position.y = value;
  223. }
  224. get width(){
  225. return this.size.x;
  226. }
  227. set width(value){
  228. this.size.x = value;
  229. }
  230. get height(){
  231. return this.size.y;
  232. }
  233. set height(value){
  234. this.size.y = value;
  235. }
  236. },
  237. Vector3: class{
  238. constructor() {
  239. switch(arguments.length) {
  240. default:
  241. case 1:
  242. this.x = arguments[0].x;
  243. this.y = arguments[0].y;
  244. this.z = arguments[0].z;
  245. break;
  246. case 3:
  247. this.x = arguments[0];
  248. this.y = arguments[1];
  249. this.z = arguments[2];
  250. break;
  251. }
  252. }
  253. get length(){
  254. if(this.x == 0 && this.y == 0 && this.z == 0)
  255. return 0;
  256. return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);
  257. }/** */
  258. get mod(){
  259. var length = this.length;
  260. return new this.constructor(this.x/length,this.y/length,this.z/length);
  261. }
  262. plus(anotherVector){
  263. return new this.constructor(this.x + anotherVector.x, this.y + anotherVector.y, this.z + anotherVector.z);
  264. }
  265. minus(anotherVector){
  266. return new this.constructor(this.x - anotherVector.x, this.y - anotherVector.y, this.z - anotherVector.z);
  267. }
  268. multiply(num){
  269. return new this.constructor(this.x * num, this.y * num, this.z * num);
  270. }
  271. toLength(length){
  272. var mod = this.mod;
  273. return new this.constructor(mod.x * length, mod.y * length, mod.z * length);
  274. }
  275. },
  276. isSameSign:function(a,b){
  277. if((a>=0&&b>=0)||(a<=0&&b<=0)){
  278. return true;
  279. }
  280. return false;
  281. },
  282. distance2:function(a,b){
  283. var distance = Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2));
  284. switch(arguments.length) {
  285. default:
  286. case 2:
  287. return distance;
  288. case 3:
  289. var vector = arguments[2];//vector must be in same line with a b
  290. if(module.exports.isSameSign(b.x - a.x,vector.x)&&module.exports.isSameSign(b.y - a.y,vector.y)){
  291. return distance;
  292. }else{
  293. return -distance;
  294. }
  295. }
  296. },
  297. maxLengthLine2:function(vertexs){
  298. if(vertexs.length==0){
  299. return null;
  300. }
  301. if(vertexs.length==1){
  302. return new module.exports.Line2(vertexs[0],vertexs[0]);
  303. }
  304. var maxLengthLine = null;
  305. var maxLength = -1;
  306. for(var i = 0;i<vertexs.length-1;++i){
  307. for(var j = i+1;j<vertexs.length;++j){
  308. var newLine = new module.exports.Line2(vertexs[i],vertexs[j]);
  309. var newLength = newLine.length;
  310. if(maxLength < newLength){
  311. maxLength = newLength;
  312. maxLengthLine = newLine;
  313. }
  314. }
  315. }
  316. return maxLengthLine;
  317. },
  318. randomInCircle2:function(){
  319. var center;//diameter
  320. var size;//diameter
  321. switch(arguments.length) {
  322. default:
  323. case 1:
  324. center = new module.exports.Vector2(0,0);
  325. size = arguments[0];
  326. break;
  327. case 2:
  328. center = arguments[0];
  329. size = arguments[1];
  330. break;
  331. }
  332. return new module.exports.Vector2(1,0).rotate(Math.random() * Math.PI*2).toLength(Math.sqrt(Math.random()*Math.pow(size/2,2))).plus(center);
  333. },
  334. intersectionLineLine2:function(){//for 2D //https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
  335. var p11,p12,p21,p22;
  336. switch(arguments.length) {
  337. default:
  338. case 4:
  339. p11 = arguments[0];
  340. p12 = arguments[1];
  341. p21 = arguments[2];
  342. p22 = arguments[3];
  343. break;
  344. case 2:
  345. p11 = arguments[0].a;
  346. p12 = arguments[0].b;
  347. p21 = arguments[1].a;
  348. p22 = arguments[1].b;
  349. break;
  350. }
  351. var denominator = (p11.x-p12.x)*(p21.y-p22.y) - (p11.y-p12.y)*(p21.x-p22.x);
  352. if(denominator == 0){
  353. return null;
  354. }
  355. var t = ((p11.x-p21.x)*(p21.y-p22.y) - (p11.y-p21.y)*(p21.x-p22.x))/denominator;
  356. var u = ((p11.x-p12.x)*(p11.y-p21.y) - (p11.y-p12.y)*(p11.x-p21.x))/denominator;
  357. return new module.exports.Vector2(p11.x+t*(p12.x-p11.x),p11.y+t*(p12.y-p11.y));
  358. },
  359. arrangeInLine1:function(p1, p2, vector){//1维//vector为正,p1小于p2
  360. var values = [];
  361. for(var i = Math.ceil(p1/vector)*vector;i<=p2;i+=vector){
  362. values.push(i);
  363. }
  364. return values;
  365. },
  366. arrangeInLine2:function(){//3点必须在1线
  367. //return [];
  368. var p1, p2, origin, vector;
  369. switch(arguments.length) {
  370. default:
  371. case 4:
  372. p1 = arguments[0];
  373. p2 = arguments[1];
  374. origin = arguments[2];
  375. vector = arguments[3];
  376. break;
  377. case 3:
  378. if(arguments[0] == null){
  379. return [];
  380. }
  381. p1 = arguments[0].a;
  382. p2 = arguments[0].b;
  383. origin = arguments[1];
  384. vector = arguments[2];
  385. break;
  386. }
  387. var begin,end;
  388. if(module.exports.isSameSign(p2.x - p1.x,vector.x)&&module.exports.isSameSign(p2.y - p1.y,vector.y)){
  389. begin = p1;
  390. end = p2;
  391. }else{
  392. begin = p2;
  393. end = p1;
  394. }
  395. if(module.exports.isSameSign(begin.x - origin.x,vector.x)&&module.exports.isSameSign(begin.y - origin.y,vector.y)){
  396. begin = module.exports.distance2(origin,begin);
  397. }else{
  398. begin = -module.exports.distance2(origin,begin);
  399. }
  400. if(module.exports.isSameSign(end.x - origin.x,vector.x)&&module.exports.isSameSign(end.y - origin.y,vector.y)){
  401. end = module.exports.distance2(origin,end);
  402. }else{
  403. end = -module.exports.distance2(origin,end);
  404. }
  405. var points = [];
  406. var modVector = vector.mod;
  407. var values = module.exports.arrangeInLine1(begin, end, vector.length);
  408. for(var i = 0;i<values.length;++i){
  409. points.push(origin.plus(modVector.multiply(values[i])));
  410. }
  411. return points;/** */
  412. },
  413. pointOnLineSegment(line,point){
  414. var acceptableError = line.length / 1000000;//存在计算误差
  415. var v1 = line.a.minus(point);
  416. var v2 = line.b.minus(point);
  417. if(module.exports.isSameSign(v1.x,v2.x)&&module.exports.isSameSign(v1.y,v2.y)&&v1.length>=acceptableError&&v2.length>=acceptableError){//存在计算误差
  418. return false;
  419. }
  420. return true;
  421. },
  422. lineSegmentInRect(rect,line){
  423. var edge = rect.edges;
  424. var ip = [];
  425. for(var i = 0;i<edge.length;++i){
  426. var newIp = module.exports.intersectionLineLine2(edge[i], line);
  427. if(newIp != null &&module.exports.pointOnLineSegment(edge[i],newIp)){
  428. ip.push(newIp);
  429. }
  430. }
  431. return module.exports.maxLengthLine2(ip);/** */
  432. },
  433. arrangeInRect2:function(rect, origin, horizontalVector, verticalVector){
  434. var ip = [];
  435. for(var i = 0; i < 4;++i){
  436. ip.push(module.exports.intersectionLineLine2(origin,origin.plus(verticalVector),rect.vertex(i),rect.vertex(i).plus(horizontalVector)));
  437. }
  438. if(module.exports.distance2(ip[0],ip[2]) > module.exports.distance2(ip[1],ip[3])){
  439. ip = [ip[0],ip[2],ip[1],ip[3]];//verticalBegin;verticalEnd;horizontalBegin;horizontalEnd;
  440. }else{
  441. ip = [ip[1],ip[3],ip[0],ip[2]];//verticalBegin;verticalEnd;horizontalBegin;horizontalEnd;
  442. }
  443. var pos = [];
  444. var verticalPoints = module.exports.arrangeInLine2(ip[0],ip[1],origin,verticalVector);
  445. for(var i = 0; i<verticalPoints.length;++i){
  446. var lineSegmentInRect = module.exports.lineSegmentInRect(rect,new module.exports.Line2(verticalPoints[i],verticalPoints[i].plus(horizontalVector)));//}/*
  447. var horizontalPoints = module.exports.arrangeInLine2(lineSegmentInRect,verticalPoints[i],horizontalVector);
  448. pos = pos.concat(horizontalPoints);
  449. }
  450. return pos;/** */
  451. //return verticalPoints;
  452. }
  453. };