o0ProjectRelease0.1.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. import o0 from "./o0.js"
  2. module.exports = {
  3. SandbagAlgorithm: class {
  4. constructor(option) {
  5. let {
  6. frameHitCapacity,
  7. slopeArr
  8. } = option;
  9. this.stableAcc = new o0.Vector2(0, 0);
  10. this.stableGyr = new o0.Vector2(0, 0);
  11. this.stableCount = 0;
  12. this.stableCountMax = 3000;
  13. this.frameCapacity = 6;
  14. this.frame = [];
  15. this.frameLength = 5;
  16. this.frameOffset = 0;
  17. // this.frameHitCapacity = 11;
  18. this.frameHitCapacity = frameHitCapacity;
  19. this.slopeArr = slopeArr;
  20. console.log("init frameHitCapacity:" + this.frameHitCapacity + ",slopeArr:" + this
  21. .slopeArr);
  22. this.frameHit = []; //打击后的n帧
  23. for (var i = 0; i < this.frameCapacity; ++i) {
  24. var o = new Object();
  25. o.acc = new o0.Vector2(0, 0);
  26. o.gyr = new o0.Vector2(0, 0);
  27. o.timeGap = 20;
  28. o.accFixed = 0;
  29. o.accSlope = 0;
  30. o.pos = new o0.Vector2(0, 0);
  31. o.predict = new o0.Vector2(0, 0);
  32. o.shake = 0;
  33. o.shakeFixed = 0;
  34. o.shakeSlope = 0;
  35. o.hit = 0;
  36. this.frame.push(o);
  37. }
  38. this.quitHitCount = 0;
  39. }
  40. //这个函数不建议外部调用
  41. GetDirection() {
  42. var direction = new o0.Vector2(0, 0);
  43. var directionDistance = 0.0;
  44. for (var fi = 0; fi < this.frameHit.length - 1; ++fi) {
  45. for (var li = fi + 1; li < this.frameHit.length; ++li) {
  46. var newDirection = this.frameHit[li].gyr.minus(this.frameHit[fi].gyr);
  47. var newDirectionDistance = newDirection.length;
  48. if (directionDistance < newDirectionDistance) {
  49. directionDistance = newDirectionDistance;
  50. direction = newDirection.multiply(this.frameHit[this.frameHit.length - 1].time -
  51. this.frameHit[0].time);
  52. } else {
  53. //cout << "false" << endl;
  54. }
  55. }
  56. }
  57. return direction;
  58. }
  59. // 输入俯视的平面坐标系下的xy轴坐标 的 加速计向量/陀螺仪向量。
  60. // timeGap 代表当前帧读取传感器与上一帧读取传感器 之间的时间差
  61. Update(accX, accY, gyrX, gyrY, timeGap) {
  62. var rawAcc = new o0.Vector2(accX, accY);
  63. var rawGyr = new o0.Vector2(gyrX, gyrY);
  64. let lastFrame = this.frame[(this.frameOffset + this.frameLength - 1) % this.frameCapacity];
  65. let last2Frame = this.frame[(this.frameOffset + this.frameLength - 2) % this.frameCapacity];
  66. let last3Frame = this.frame[(this.frameOffset + this.frameLength - 3) % this.frameCapacity];
  67. let last4Frame = this.frame[(this.frameOffset + this.frameLength - 4) % this.frameCapacity];
  68. let last5Frame = this.frame[(this.frameOffset + this.frameLength - 5) % this.frameCapacity];
  69. var newFrame = this.frame[(this.frameOffset + this.frameLength) % this.frameCapacity];
  70. newFrame.timeGap = timeGap;
  71. newFrame.acc = rawAcc.minus(this.stableAcc);
  72. newFrame.gyr = rawGyr.minus(this.stableGyr);
  73. if (this.stableCount < this.stableCountMax) {
  74. this.stableCount += 1;
  75. }
  76. this.stableAcc = this.stableAcc.multiply((this.stableCount - 1.0) / this.stableCount).plus(
  77. rawAcc.multiply(1 / this.stableCount));
  78. this.stableGyr = this.stableGyr.multiply((this.stableCount - 1.0) / this.stableCount).plus(
  79. rawGyr.multiply(1 / this.stableCount));
  80. //////////////////////////////////////////////////////////////////////////////////
  81. newFrame.accFixed = newFrame.acc.length * 100;
  82. if (newFrame.accFixed < lastFrame.accFixed * 0.85) {
  83. newFrame.accFixed = lastFrame.accFixed * 0.85;
  84. }
  85. lastFrame.accFixed = Math.max(lastFrame.accFixed, Math.min(newFrame.accFixed, last2Frame
  86. .accFixed), Math.min(newFrame.accFixed, last3Frame.accFixed));
  87. ///////////////////////////////////////////////////////////////////////
  88. //newFrame.pos = lastFrame.pos.plus(lastFrame.acc.plus(newFrame.acc).multiply(timeGap/60)).multiply(Math.max(1-timeGap/200,0));
  89. newFrame.pos = lastFrame.pos.plus(newFrame.acc.multiply(timeGap / 30)).multiply(Math.max(1 -
  90. timeGap / 1000, 0));
  91. ////////////////////////////////////////////
  92. newFrame.accSlope = Math.max(newFrame.accFixed - lastFrame.accFixed, 0);
  93. var lastI = this.frame.length - 1;
  94. var t2 = this.frame[lastI - 1].timeGap;
  95. var t3 = this.frame[lastI].timeGap + t2;
  96. var t4 = newFrame.timeGap + t3;
  97. newFrame.predict = new o0.Vector2(
  98. new o0.QuadraticEquation(0, this.frame[lastI - 2].pos.x, t2, this.frame[lastI - 1].pos
  99. .x, t3, this.frame[lastI].pos.x).y(t4),
  100. new o0.QuadraticEquation(0, this.frame[lastI - 2].pos.y, t2, this.frame[lastI - 1].pos
  101. .y, t3, this.frame[lastI].pos.y).y(t4)); /** */
  102. newFrame.shake = o0.distance2(newFrame.predict, newFrame.pos) * 100;
  103. if (isNaN(newFrame.shake)) {
  104. newFrame.shake = 0.0;
  105. }
  106. newFrame.shakeFixed = lastFrame.shakeFixed * 0.85;
  107. if (newFrame.shake > newFrame.shakeFixed) {
  108. newFrame.shakeFixed = newFrame.shake;
  109. } /* */
  110. lastFrame.shakeFixed = Math.max(lastFrame.shakeFixed, Math.min(newFrame.shakeFixed, last2Frame
  111. .shakeFixed), Math.min(newFrame.shakeFixed, last3Frame.shakeFixed));
  112. ////////////////////////////////////////////////////////////////
  113. newFrame.shakeSlope = Math.max(newFrame.shakeFixed - lastFrame.shakeFixed, 0);
  114. ///////////////////////////////////////////////////////////////
  115. var direction = undefined;
  116. //15 20 20 40 , 13 17 17 35
  117. // let slopeArr = [15, 20, 20, 40];
  118. // let slopeArr = this.slopeArr;// [13, 17, 17, 35];
  119. if (lastFrame.hit == 0 &&
  120. last2Frame.hit == 0 &&
  121. last3Frame.hit == 0 &&
  122. last4Frame.hit == 0 &&
  123. last5Frame.hit == 0 &&
  124. (newFrame.accSlope >= this.slopeArr[0] || lastFrame.accSlope >= this.slopeArr[1]) &&
  125. (newFrame.shakeSlope >= this.slopeArr[2] || lastFrame.shakeSlope >= this.slopeArr[3])) {
  126. newFrame.hit = 1;
  127. if (this.frameHit.length < this.frameHitCapacity && this.frameHit.length !=
  128. 0) { //判断到第二次hit,但还未输出第一次hit的方向,强制输出方向
  129. direction = this.GetDirection();
  130. } /**/
  131. this.frameHit = [];
  132. /*
  133. var o3 = new Object();
  134. o3.time = 0;
  135. o3.gyr = lastFrame3.gyr;
  136. this.frameHit.push(o3);/* */
  137. var o2 = new Object();
  138. o2.time = last2Frame.timeGap;
  139. o2.gyr = last2Frame.gyr;
  140. this.frameHit.push(o2);
  141. var o = new Object();
  142. o.time = last2Frame.timeGap + lastFrame.timeGap;
  143. o.gyr = lastFrame.gyr;
  144. this.frameHit.push(o);
  145. } else {
  146. newFrame.hit = 0;
  147. }
  148. if (this.frameHit.length < this.frameHitCapacity && this.frameHit.length != 0) {
  149. var o = new Object();
  150. o.time = this.frameHit[this.frameHit.length - 1].time + newFrame.timeGap;
  151. //o.gyr = this.frameHit[this.frameHit.length-1].gyr.plus(newFrame.gyr);
  152. o.gyr = newFrame.gyr;
  153. this.frameHit.push(o);
  154. if (this.frameHit.length == this.frameHitCapacity) { //累计达到设定的延迟帧数,输出方向
  155. direction = this.GetDirection();
  156. }
  157. }
  158. if ((this.frameOffset += 1) >= this.frameCapacity) {
  159. this.frameOffset -= this.frameCapacity;
  160. }
  161. return [newFrame.hit, direction];
  162. }
  163. getTempValue(curDirection) {
  164. let result = Math.atan2(curDirection.y, curDirection.x) * 180 / (Math.PI);
  165. result = Math.round(result);
  166. let curAngle = result > 0 ? result : (360 + result);
  167. let directionPunch = "all",
  168. name = "击中",
  169. ename = "hit";
  170. let positiveMidSlope = [70, 110]; //min max
  171. let negativeMidSlope = [250, 290]; //min max
  172. if (curAngle < positiveMidSlope[1] && curAngle >= positiveMidSlope[0]) {
  173. directionPunch = "straightPunch";
  174. name = "正向的直拳";
  175. ename = "front-straight";
  176. } else if (curAngle < positiveMidSlope[0] && curAngle >= 0) {
  177. directionPunch = "rightPunch";
  178. name = "正向的右拳";
  179. ename = "front-right";
  180. } else if (curAngle <= 180 && curAngle >= positiveMidSlope[1]) {
  181. directionPunch = "leftPunch";
  182. name = "正向的左拳";
  183. ename = "front-left";
  184. }
  185. //相反方向击打
  186. //正方向
  187. else if (curAngle <= negativeMidSlope[1] && curAngle > negativeMidSlope[0]) {
  188. directionPunch = "straightPunch";
  189. name = "负向的直拳";
  190. ename = "back-straight";
  191. } else if (curAngle <= negativeMidSlope[0] && curAngle > 180) {
  192. directionPunch = "rightPunch";
  193. name = "负向的右拳";
  194. ename = "back-right";
  195. } else if (curAngle <= 360 && curAngle > negativeMidSlope[1]) {
  196. directionPunch = "leftPunch";
  197. name = "负向的左拳";
  198. ename = "back-left";
  199. }
  200. this.quitHitCount++;
  201. let temp = {
  202. type: 'hit',
  203. hit: curDirection.length,
  204. hitCount: this.quitHitCount,
  205. direction: directionPunch,
  206. directionVect: {
  207. 'x': curDirection.x,
  208. 'y': curDirection.y
  209. },
  210. angle: curAngle,
  211. name: name,
  212. ename: ename
  213. }
  214. return temp;
  215. }
  216. }
  217. };