MathUtils.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. export default class MathUtils{
  2. /**
  3. * 环形映射
  4. * @param value
  5. * @param min
  6. * @param max
  7. */
  8. static CircularMapping(value:number,max:number,min:number=0):number{
  9. value=value-min;
  10. let dis:number=max-min;
  11. if(value<0){
  12. return dis+value%dis;
  13. }
  14. return value%dis;
  15. }
  16. /**
  17. * 绕点旋转
  18. * @param angle
  19. * @param point
  20. * @param origin
  21. * @param out
  22. */
  23. static RotationFormOrigin(angle:number,point:cc.Vec3,origin:cc.Vec3,out:cc.Vec3):void{
  24. //旋转
  25. let q:cc.Quat=new cc.Quat();
  26. cc.Quat.fromEuler(q,0,0,angle);
  27. let m:cc.Mat4=new cc.Mat4();
  28. cc.Mat4.fromRTSOrigin(m,q,cc.Vec3.ZERO,new cc.Vec3(1,1,1),origin);
  29. //应用矩阵
  30. cc.Vec3.transformMat4(out,point,m);
  31. }
  32. /**
  33. * 求圆内多边形的中心点的高度
  34. * @param l 边长
  35. * @param n 内角
  36. */
  37. static InCirclePolygonCentre(l:number,n:number):number{
  38. let hl:number=l*0.5;
  39. let angle:number=n*0.5;
  40. //角度转弧度
  41. let radian:number=this.angle2Radian(angle);
  42. let value:number=hl/Math.tanh(radian);
  43. return value;
  44. }
  45. static InCircle
  46. /**
  47. * 随机范围值
  48. * @param min
  49. * @param max
  50. */
  51. static RandomRange(min:number,max:number):number{
  52. return min+Math.random()*(max-min);
  53. }
  54. /**
  55. * 获取速度分量 从2个点及速度计算
  56. * @param currentPoint
  57. * @param targetPoint
  58. * @param speed
  59. * @param result
  60. */
  61. static getSpeed2dByPoint(currentPoint:cc.Vec2,targetPoint:cc.Vec2,speed:number,result?:cc.Vec2):cc.Vec2{
  62. if(result==null){
  63. result=new cc.Vec2();
  64. }
  65. let angle:number=this.getRadian(targetPoint.x,targetPoint.y,currentPoint.x,currentPoint.y);
  66. this.getSpeed2DR(angle,speed,result);
  67. return result;
  68. }
  69. /**
  70. * 速度转2维速度
  71. * @param angle 角度
  72. * @param speed 速度
  73. * @param result 结果
  74. */
  75. public static getSpeed2D(angle:number,speed:number,result:cc.Vec2=null):cc.Vec2{
  76. //角度转弧度
  77. let radian:number= angle * (Math.PI /180);
  78. return this.getSpeed2DR(radian,speed,result);
  79. }
  80. public static getSpeed2DR(radian:number,speed:number,result:cc.Vec2=null):cc.Vec2{
  81. if(result==null){
  82. result=new cc.Vec2();
  83. }
  84. result.x=Math.cos(radian)*speed;
  85. result.y=Math.sin(radian)*speed;
  86. return result;
  87. }
  88. /**
  89. * 根据角度和X轴计算Y轴速度
  90. * @param angle
  91. * @param speedX
  92. * @param result
  93. */
  94. public static getSpeed2DByX(angle:number,speedX:number,result:cc.Vec2=null):cc.Vec2{
  95. if(result==null){
  96. result=new cc.Vec2();
  97. }
  98. //角度转弧度
  99. let radian:number= angle * (Math.PI /180);
  100. //求出斜边的长度
  101. let leg:number=speedX/Math.cos(radian);
  102. result.x=speedX;
  103. result.y=Math.sin(radian)*leg;
  104. return result;
  105. }
  106. /**
  107. * 求旋转后的点坐标
  108. * @param angle 角度
  109. * @param point 旋转前的坐标点
  110. * @param result
  111. */
  112. public static rotationPoint(angle:number,point:{x:number,y:number},result:{x:number,y:number}):void{
  113. //角度转弧度
  114. angle=angle*(Math.PI/180);
  115. result.x = Math.cos(angle) * point.x - Math.sin(angle) * point.y;
  116. result.y = Math.cos(angle) * point.y + Math.sin(angle) * point.x;
  117. }
  118. public static getAngle(a:cc.Vec2,b:cc.Vec2):number{
  119. return this.getRadianByPoint(a,b)*(180/Math.PI);
  120. }
  121. public static getRadianByPoint(a:cc.Vec2,b:cc.Vec2):number{
  122. return Math.atan2((a.y-b.y), (a.x-b.x));
  123. }
  124. public static getRadian(ax:number,ay:number,bx:number,by:number):number{
  125. return Math.atan2(ay-by, ax-bx);
  126. }
  127. static angle2Radian(angle:number):number{
  128. return angle*(Math.PI/180);
  129. }
  130. static radian2Angle(radian:number):number{
  131. return radian*(180/Math.PI);
  132. }
  133. /**
  134. * 计算两线段相交点坐标
  135. * @param line1Point1
  136. * @param line1Point2
  137. * @param line2Point1
  138. * @param line2Point2
  139. * @return 返回该点
  140. */
  141. static getIntersectionPoint(line1Point1:cc.Vec2, line1Point2:cc.Vec2, line2Point1:cc.Vec2, line2Point2:cc.Vec2,result?:cc.Vec2):cc.Vec2{
  142. if(!result){
  143. result=new cc.Vec2();
  144. }
  145. let x1:number,y1:number,x2:number,y2:number,x3:number,y3:number,x4:number,y4:number;
  146. x1 = line1Point1.x;
  147. y1 = line1Point1.y;
  148. x2 = line1Point2.x;
  149. y2 = line1Point2.y;
  150. x3 = line2Point1.x;
  151. y3 = line2Point1.y;
  152. x4 = line2Point2.x;
  153. y4 = line2Point2.y;
  154. result.x=Math.ceil((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1)) / ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
  155. result.y=Math.ceil((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4)) / ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
  156. return result;
  157. }
  158. /**
  159. * 判断点是否在线段内
  160. * @param Pi
  161. * @param Pj
  162. * @param Q
  163. */
  164. static onSegment(Pi:cc.Vec2 , Pj:cc.Vec2 , Q:cc.Vec2):boolean
  165. {
  166. Q.x=Math.round(Q.x);
  167. Q.y=Math.round(Q.y);
  168. let xValue:number=(Q.x - Pi.x) * (Pj.y - Pi.y) - (Pj.x - Pi.x) * (Q.y - Pi.y);
  169. if(Math.floor(xValue)==0
  170. //保证Q点坐标在pi,pj之间
  171. && Math.min(Pi.x , Pj.x) <= Q.x && Q.x <= Math.max(Pi.x , Pj.x)
  172. && Math.min(Pi.y , Pj.y) <= Q.y && Q.y <= Math.max(Pi.y , Pj.y)){
  173. return true;
  174. }
  175. return false;
  176. }
  177. /**
  178. * 求两个向量之间的夹角
  179. * @param av 单位向量
  180. * @param bv 单位向量
  181. */
  182. static calculateAngle(av:cc.Vec3,bv:cc.Vec3):number{
  183. //cos=a.b/(|a||b|);
  184. return Math.acos(cc.Vec3.dot(av,bv)/(av.len()*bv.len()));
  185. }
  186. static calculateAngleByPoints(a:cc.Vec3,b:cc.Vec3,c:cc.Vec3){
  187. let av:cc.Vec3=new cc.Vec3();
  188. let bv:cc.Vec3=new cc.Vec3();
  189. cc.Vec3.subtract(b,a,av);
  190. cc.Vec3.subtract(b,c,bv);
  191. return this.calculateAngle(av,bv);
  192. }
  193. }