Hello! I have a bad math, so I ask for your help. How to make the movement of an object from point to point, at the same time, so that it moves along a parabola? enter image description here

One solution looks like this:

var dist1 = dot2.y - dot1.y, dist2 = dot2.y - player.y, percent = dist2 / dist1; percent = percent > 0.5 ? 1 - percent : percent; player.x = player.constX - (100 * percent); 

What is happening here: dist1 is all the way, dist2 - how much is left to the second point, percent - what percentage of the way the character passed. We shift the character to the left by a certain percentage multiplied by 100. We need the character to go out and go in, so we check: if the player has traveled 50% of the way, we start reducing the percentages. Therefore, the maximum protrusion of the character to the left is 50, because 100 * 0.5 = 50. Something like that. Your suggestions?

  • An endless number of different parabolas can pass through 2 points. Which one of them interests you? - Yaant
  • @Yaant Imagine that the orange points are the points of intersection of the parabola with the abscissa, and the straight line along which the cube moves is the parabola. - Reaget
  • @Reaget, a small example of what Yaant meant: parabol charts going through two identical points - Grundy
  • @Grundy thanks :) Now I understood what he meant. - Reaget
  • @Reaget, now it’s worth clarifying the question: which parabola should all move on - Grundy

1 answer 1

You can apply the quadratic equation of a bezier curve, since a parabola is, generally speaking, a special case of a second-order curve, which in particular is also a bezier curve with 3 three control points.

All that needs to be done is to determine the bending point p1 which in the case of a parabola should be equidistant from the initial and final points p0, p2 .

To generate motion points, you must apply the Bezier curve equation.

An example in jsfiddle :

 var cnv = document.getElementById("cnv"); var ctx = cnv.getContext("2d"); var path = [], id = 0, speed = 1; var point = { x: 0, y: 0, draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, 10, 0, 2*Math.PI, true); ctx.fill(); ctx.closePath(); } }; function getCurvePath(x0, y0, x1, y1, xdepth, ydepth) { var p0 = {x: x0, y: y0}, p2 = {x: x1, y: y1}, p1 = {x: xdepth + (p0.x + p2.x) * 0.5, y: ydepth + (p0.y + p2.y) * 0.5}, x, y, t = 0, path = []; for (; t <= 1; t += 0.01) { x = (1 - t)*(1 - t)*p0.x + 2*t*(1 - t)*p1.x + t*t*p2.x; y = (1 - t)*(1 - t)*p0.y + 2*t*(1 - t)*p1.y + t*t*p2.y; path.push({x: x, y: y}); } return path; } function drawCurve(path) { ctx.beginPath(); for (var i = 0; i < path.length; i++) { ctx.lineTo(path[i].x, path[i].y); } ctx.stroke(); ctx.closePath(); } path = getCurvePath(250, 350, 250, 20, 450, 0); var i = 0; function render() { ctx.clearRect(0, 0, cnv.width, cnv.height); drawCurve(path); if (i < path.length) point.x = path[i].x, point.y = path[i].y; else { i = 0; } i += speed; point.draw(); id = requestAnimationFrame(render); } render(); 
 <canvas id="cnv" width="800" height="800"></canvas> 

Actually, by changing the points p0, p1, p2 you can get any parabola whose director is parallel to one of the axes, but you should pay attention to the xdepth and ydepth one of which must be zero, otherwise the parabola will not work