速度变化图.html 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>速度变化图</title>
  6. </head>
  7. <body>
  8. <canvas style="position: fixed; top: 0px; left: 0px;"></canvas>
  9. </body>
  10. <script>
  11. var canvas = document.querySelector("canvas")
  12. var ctx = canvas.getContext("2d");
  13. ctx.clearRect(0, 0, canvas.width, canvas.height);
  14. canvas.width = innerWidth;
  15. canvas.height = innerHeight;
  16. ctx.fillStyle = "rgb(0,0,0)";
  17. ctx.fillRect(0,0,canvas.width,canvas.height);
  18. ctx.lineWidth = 1;
  19. ctx.strokeStyle = "rgb(255,0,0)";
  20. ctx.beginPath();
  21. ctx.moveTo(0, innerHeight - 100);
  22. ctx.lineTo(innerWidth, innerHeight - 100);
  23. ctx.moveTo(100, 0);
  24. ctx.lineTo(100, innerHeight);
  25. ctx.closePath();
  26. ctx.stroke();
  27. ctx.fillStyle = "rgb(255,0,0)";
  28. ctx.textBaseline = "top";
  29. ctx.textAlign = "center";
  30. ctx.font = "40px Arial"
  31. ctx.fillText("v", 130, 100);
  32. ctx.fillText("t", 350, innerHeight - 85);
  33. //积分求变加速直线运动位移
  34. function seekDistance(acc, time, draw) {
  35. let dt = 0.001;
  36. let v0 = 0;
  37. let sum = 0;
  38. for (let t = dt; t <= time; t += dt) {
  39. let dv = 1 / 2 * acc * dt;
  40. sum += v0 * dt + dv * dt;
  41. v0 += dv;
  42. //提高加速度
  43. acc += dt * acc * 3;
  44. if (draw) {
  45. ctx.moveTo(100 + (t / 5 * 1000) << 0, innerHeight - 100);
  46. ctx.lineTo (100 + (t / 5 * 1000) << 0, innerHeight - 100 - v0 / 5);
  47. ctx.stroke();
  48. }
  49. }
  50. return sum;
  51. }
  52. //寻找最佳的加速度
  53. function findBestAcc(distance, time) {
  54. //为了后面减少运算量,先粗略找到比较接近的区间
  55. let accRangeMin = null;
  56. let accRangeMax = null;
  57. for (let acc = 0; acc < 10000; acc += 10) {
  58. let result = seekDistance(acc, time);
  59. let dx = result - distance;
  60. if (dx < 0) {
  61. accRangeMin = acc;
  62. } else if (dx > 0) {
  63. accRangeMax = acc;
  64. break;
  65. } else {
  66. return acc;
  67. }
  68. }
  69. if (accRangeMin == null || accRangeMax == null) {
  70. throw "寻找区间失败"
  71. }
  72. //在指定区间寻找最佳结果
  73. for (let acc = accRangeMin; acc <= accRangeMax; acc += 0.001) {
  74. let result = seekDistance(acc, time);
  75. let dx = result - distance;
  76. if (Math.abs(dx) < 0.1) {
  77. return acc;
  78. }
  79. }
  80. throw "找不到最佳加速度";
  81. }
  82. let acc = findBestAcc(640, 1);
  83. seekDistance(acc, 1, true);
  84. </script>
  85. </html>