MathUtils.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { _decorator, Component, Node, Vec2, Vec3 } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. export class MathUtils{
  4. /**
  5. * 随机范围值
  6. * @param min
  7. * @param max
  8. */
  9. static RandomRange(min:number,max:number):number{
  10. return min+Math.random()*(max-min);
  11. }
  12. /**
  13. * 获取速度分量 从2个点及速度计算
  14. * @param currentPoint
  15. * @param targetPoint
  16. * @param speed
  17. * @param result
  18. */
  19. static getSpeed2dByPoint(currentPoint:Vec2,targetPoint:Vec2,speed:number,result?:Vec2):Vec2{
  20. if(result==null){
  21. result=new Vec2();
  22. }
  23. let angle:number=this.getRadian(targetPoint.x,targetPoint.y,currentPoint.x,currentPoint.y);
  24. this.getSpeed2DR(angle,speed,result);
  25. return result;
  26. }
  27. /**
  28. * 速度转2维速度
  29. * @param angle 角度
  30. * @param speed 速度
  31. * @param result 结果
  32. */
  33. public static getSpeed2D(angle:number,speed:number,result:Vec2=null):Vec2{
  34. //角度转弧度
  35. let radian:number= angle * (Math.PI /180);
  36. return this.getSpeed2DR(radian,speed,result);
  37. }
  38. public static getSpeed2DR(radian:number,speed:number,result:Vec2=null):Vec2{
  39. if(result==null){
  40. result=new Vec2();
  41. }
  42. result.x=Math.cos(radian)*speed;
  43. result.y=Math.sin(radian)*speed;
  44. return result;
  45. }
  46. /**
  47. * 根据角度和X轴计算Y轴速度
  48. * @param angle
  49. * @param speedX
  50. * @param result
  51. */
  52. public static getSpeed2DByX(angle:number,speedX:number,result:Vec2=null):Vec2{
  53. if(result==null){
  54. result=new Vec2();
  55. }
  56. //角度转弧度
  57. let radian:number= angle * (Math.PI /180);
  58. //求出斜边的长度
  59. let leg:number=speedX/Math.cos(radian);
  60. result.x=speedX;
  61. result.y=Math.sin(radian)*leg;
  62. return result;
  63. }
  64. /**
  65. * 求旋转后的点坐标
  66. * @param angle 角度
  67. * @param point 旋转前的坐标点
  68. * @param result
  69. */
  70. public static rotationPoint(angle:number,point:Vec2,result:Vec2):Vec2{
  71. //角度转弧度
  72. angle=angle*(Math.PI/180);
  73. if(result==null){
  74. result=new Vec2();
  75. }
  76. result.x = Math.cos(angle) * point.x - Math.sin(angle) * point.y;
  77. result.y = Math.cos(angle) * point.y + Math.sin(angle) * point.x;
  78. return result;
  79. }
  80. public static getAngle(a:Vec2,b:Vec2):number{
  81. return this.getRadianByPoint(a,b)*(180/Math.PI);
  82. }
  83. public static getRadianByPoint(a:Vec2,b:Vec2):number{
  84. return Math.atan2((a.y-b.y), (a.x-b.x));
  85. }
  86. public static getRadian(ax:number,ay:number,bx:number,by:number):number{
  87. return Math.atan2(ay-by, ax-bx);
  88. }
  89. static angle2Radian(angle:number):number{
  90. return angle*(Math.PI/180);
  91. }
  92. static radian2Angle(radian:number):number{
  93. return radian*(180/Math.PI);
  94. }
  95. /**
  96. * 计算两线段相交点坐标
  97. * @param line1Point1
  98. * @param line1Point2
  99. * @param line2Point1
  100. * @param line2Point2
  101. * @return 返回该点
  102. */
  103. static getIntersectionPoint(line1Point1:Vec2, line1Point2:Vec2, line2Point1:Vec2, line2Point2:Vec2,result?:Vec2):Vec2{
  104. if(!result){
  105. result=new Vec2();
  106. }
  107. let x1:number,y1:number,x2:number,y2:number,x3:number,y3:number,x4:number,y4:number;
  108. x1 = line1Point1.x;
  109. y1 = line1Point1.y;
  110. x2 = line1Point2.x;
  111. y2 = line1Point2.y;
  112. x3 = line2Point1.x;
  113. y3 = line2Point1.y;
  114. x4 = line2Point2.x;
  115. y4 = line2Point2.y;
  116. result.x=Math.ceil((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1)) / ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
  117. result.y=Math.ceil((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4)) / ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
  118. return result;
  119. }
  120. /**
  121. * 判断点是否在线段内
  122. * @param Pi
  123. * @param Pj
  124. * @param Q
  125. */
  126. static onSegment(Pi:Vec2 , Pj:Vec2 , Q:Vec2):boolean
  127. {
  128. Q.x=Math.round(Q.x);
  129. Q.y=Math.round(Q.y);
  130. let xValue:number=(Q.x - Pi.x) * (Pj.y - Pi.y) - (Pj.x - Pi.x) * (Q.y - Pi.y);
  131. if(Math.floor(xValue)==0
  132. //保证Q点坐标在pi,pj之间
  133. && Math.min(Pi.x , Pj.x) <= Q.x && Q.x <= Math.max(Pi.x , Pj.x)
  134. && Math.min(Pi.y , Pj.y) <= Q.y && Q.y <= Math.max(Pi.y , Pj.y)){
  135. return true;
  136. }
  137. return false;
  138. }
  139. /**
  140. * 求两个向量之间的夹角
  141. * @param av 单位向量
  142. * @param bv 单位向量
  143. */
  144. static calculateAngle(av:Vec3,bv:Vec3):number{
  145. //cos=a.b/(|a||b|);
  146. return Math.acos(Vec3.dot(av,bv)/(av.length()*bv.length()));
  147. }
  148. static calculateAngleByPoints(a:Vec3,b:Vec3,c:Vec3){
  149. let av:Vec3=new Vec3();
  150. let bv:Vec3=new Vec3();
  151. Vec3.subtract(b,a,av);
  152. Vec3.subtract(b,c,bv);
  153. return this.calculateAngle(av,bv);
  154. }
  155. }