canvas - Drawing a trajectory in javascript? - Stack Overflow

Not sure where else to ask about this. I'm using a in HTML and would like to draw a trajectory of

Not sure where else to ask about this. I'm using a in HTML and would like to draw a trajectory of a projectile starting from the bottom left of a canvas, being shot in an angle, with a certain velocity (like 45degrees at 10ms). So far I've mostly seen using the

ctx.beginPath();

ctx.moveTo(0, 0);

ctx.lineTo((180), 180);

ctx.stroke();

But that only draws a straight line?

Not sure where else to ask about this. I'm using a in HTML and would like to draw a trajectory of a projectile starting from the bottom left of a canvas, being shot in an angle, with a certain velocity (like 45degrees at 10ms). So far I've mostly seen using the

ctx.beginPath();

ctx.moveTo(0, 0);

ctx.lineTo((180), 180);

ctx.stroke();

But that only draws a straight line?

Share Improve this question edited Jun 11, 2015 at 11:16 Manashvi Birla 2,8433 gold badges16 silver badges28 bronze badges asked Jun 11, 2015 at 10:59 user242491user242491 232 silver badges9 bronze badges 2
  • Add a working code example with what you want (in JSbin for example) and what you expect in more detail – Sirikon Commented Jun 11, 2015 at 11:02
  • It's too broad as question...to draw a trajectory you should first of all decide if there is gravity, if you count the mass of the projectile, if there is air resistance. You should use a Physics engine to simplify your life. – SharpEdge Commented Jun 11, 2015 at 11:09
Add a ment  | 

2 Answers 2

Reset to default 3

What you want is an object with a velocity in both X and Y directions. For each iteration, you'll reduce the velocity for Y due to gravity. For each iteration, you can draw a line, see example below.

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

c.width = 450;
c.height = 300;

var x = 0;
var y = 300;
var oldX = 0;
var oldY = 300;
var xVel = 10;
var yVel = -20;
var g = 1;


var myInterval = setInterval(function () {
                               x+=xVel;
                               y+=yVel;
                               yVel+=g;
                               ctx.beginPath();
                               ctx.moveTo(oldX,oldY);
                               ctx.lineTo(x,y);
                               ctx.stroke();
                               oldX = x;
                               oldY = y;
  
  if (y>c.height) {clearInterval(myInterval);}
                             },20);
canvas {
    border: 1px solid black;
}
<canvas id="canvas"></canvas>

There are some accurate [x,y] trajectory calculations in Wikipedia:

http://en.wikipedia/wiki/Trajectory_of_a_projectile

But if you just want your projectile to form an arc to a target you can do it like this:

  • Given the starting point (p0) and the target point (p2),
  • Calculate a point perpendicular to the midpoint of p0 & p2 at a specified distance (p1),
  • Draw a quadratic curve from p0 to p2 with p1 as the curves middle control point.

If you want to plot points along that quadratic curve you can use De Casteljau's algorithm and then draw your projectile along the plotted points:

function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
    var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x; 
    var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y; 
    return( {x:x,y:y} );
}

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var p0={x:0,y:ch};
var p2={x:180,y:180};
var distance=25;
var p1;

var nextTime=0;
var delay=1000/60*3;
var pts;
var ptIndex=0;

redraw();

$myslider=$('#myslider');
$myslider.attr({min:0,max:100}).val(distance);
$myslider.on('input change',function(){
  distance=parseInt($(this).val());
  redraw();
});

$('#plot').click(function(){
  pts=plot(p0,p1,p2);
  ptIndex=0;
  requestAnimationFrame(animatePlot);    
});

function animatePlot(time){
  //    if(time<nextTime){requestAnimationFrame(animatePlot);}
  nextTime=time+delay;
  if(ptIndex<pts.length){
    var p=pts[ptIndex];
    ctx.clearRect(0,0,cw,ch);
    ctx.beginPath();
    ctx.arc(p.x,p.y,2,0,Math.PI*2);
    ctx.closePath();
    ctx.fill();
    ctx.beginPath();
    ctx.arc(p2.x,p2.y,4,0,Math.PI*2);
    ctx.closePath();
    ctx.fill();
    ctx.fillText('['+p2.x+','+p2.y+']',p2.x+10,p2.y);        
    ptIndex++;
    requestAnimationFrame(animatePlot);
  }
}

function plot(p0,p1,p2){
  var pts=[];
  var lastX=p0.x;
  var lastY=p0.y;
  for(var T=0;T<500;T++){
    var p=getQuadraticBezierXYatT(p0,p1,p2,T/500);
    var dx=p.x-lastX;
    var dy=p.y-lastY;
    if(dx*dx+dy*dy>1){
      pts.push({x:p.x,y:p.y});
      lastX=p.x;
      lastY=p.y;
    }
  }
  return(pts)
}

function redraw(){
  p1=pointPerpendicularToMidpoint(p0,p2,distance);
  ctx.clearRect(0,0,cw,ch);
  ctx.beginPath();
  ctx.moveTo(p0.x,p0.y);
  ctx.quadraticCurveTo(p1.x,p1.y,p2.x,p2.y);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(p2.x,p2.y,4,0,Math.PI*2);
  ctx.closePath();
  ctx.fill();
  ctx.fillText('['+p2.x+','+p2.y+']',p2.x+10,p2.y);
}


function pointPerpendicularToMidpoint(p0,p2,distance){
  var dx=p2.x-p0.x;
  var dy=p2.y-p0.y;
  var midpoint={ x:p0.x+dx*0.50, y:p0.y+dy*0.50, };
  var angle=Math.atan2(dy,dx);
  var perpendicularPoint={
    x: midpoint.x+distance*Math.cos(angle-Math.PI/2),
    y: midpoint.y+distance*Math.sin(angle-Math.PI/2)        
  };
  return(perpendicularPoint);
}

function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
  var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x; 
  var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y; 
  return( {x:x,y:y} );
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis./ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Change Curve:&nbsp<input id=myslider type=range>
<br>
<button id=plot>Plot the curve</button>
<br>
<canvas id="canvas" width=300 height=250></canvas>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745367113a4624634.html

相关推荐

  • canvas - Drawing a trajectory in javascript? - Stack Overflow

    Not sure where else to ask about this. I'm using a in HTML and would like to draw a trajectory of

    13小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信