o0.js 16 KB

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