不知道還有什麼地方可以問這個。我在HTML中使用了一個,並希望繪製從畫布左下角開始的彈丸軌跡,以一定的速度(如45degrees
,位於10ms
)以一定角度拍攝。到目前爲止,我已經看到使用在javascript中繪製軌跡?
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo((180), 180);
ctx.stroke();
但是,只繪製一條直線?
不知道還有什麼地方可以問這個。我在HTML中使用了一個,並希望繪製從畫布左下角開始的彈丸軌跡,以一定的速度(如45degrees
,位於10ms
)以一定角度拍攝。到目前爲止,我已經看到使用在javascript中繪製軌跡?
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo((180), 180);
ctx.stroke();
但是,只繪製一條直線?
你想要的是一個在X和Y方向都有速度的物體。對於每次迭代,您都會因重力而降低Y的速度。對於每次迭代,您可以繪製一條線,請參閱下面的示例。
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>
有一些準確的[X,Y]軌跡計算在維基百科:
http://en.wikipedia.org/wiki/Trajectory_of_a_projectile
但如果你只是想你的拋射形成電弧到目標你可以這樣做:
如果你想沿着二次曲線,你可以使用德卡斯特里奧算法,然後繪製你的彈丸沿着繪製的點積點:
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.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Change Curve: <input id=myslider type=range>
<br>
<button id=plot>Plot the curve</button>
<br>
<canvas id="canvas" width=300 height=250></canvas>
添加一個你想要的工作代碼示例(在JSbin中爲例子e)以及你期待的更詳細的信息 – Sirikon
這個問題過於寬泛,如果問題是......繪製一個軌跡,首先應該確定是否存在重力,如果計算拋射體的質量,是否存在空氣阻力。你應該使用物理引擎來簡化你的生活。 – SharpEdge