gpt4 book ai didi

javascript - 使用动态坐标在 Canvas 上定位

转载 作者:行者123 更新时间:2023-12-03 07:15:52 25 4
gpt4 key购买 nike

我正在使用 HTML5 Canvas 制作交互式太阳系 Canvas 。我希望能够在页面加载时将行星定位在 Canvas 上的特定坐标处。现在我把它们都排在一条水平线上,所以我知道它们各自的距离有多远。正如您在小图中看到的那样。

enter image description here

但是这是我的问题,因为 x 和 y 坐标根据使它们旋转的函数不断变化,我不知道如何在 Canvas 上准确定位这些行星,以便它们彼此分散,并且不像它们那样位于图像上,同时仍然将它们定位,以便它们在旋转时不会彼此直接接触。我认为这里涉及到一些数学知识。

另外:我意识到不同的动画间隔可能是解决此问题的方法,但我遇到了麻烦。当我为每个行星创建新的动画功能时,行星绘图并不像一个动画所带来的那么流畅。我意识到这本身就是一个独立的问题!

以下是大部分相关代码:

function initCanvas(){
var ctx = document.getElementById('my_canvas').getContext('2d');
var dynamicSunW = 25;
var dynamicSunH = 0;
var dynamicSunX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5); //dynamicSun is always at dead center of canvas
var dynamicSunY = (ctx.canvas.height * .5) - (dynamicSunH * .5);
var angleOfSun = 0;


var posMercuryX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posMercuryY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 20;
var gravityMercury = {x: posMercuryX, y: posMercuryY };
var posVenusX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posVenusY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 46;
var gravityVenus = {x: posVenusX, y: posVenusY };
var posEarthX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posEarthY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 80;
var gravityEarth = {x: posEarthX, y: posEarthY};
var posMarsX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posMarsY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 116;
var gravityMars = {x: posMarsX, y: posMarsY };
var posJupiterX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posJupiterY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 157;
var gravityJupiter = {x: posJupiterX, y: posJupiterY };
var posSaturnX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posSaturnY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 208;
var gravitySaturn = {x: posSaturnX, y: posSaturnY };
var posUranusX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posUranusY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 250;
var gravityUranus = {x: posUranusX, y: posUranusY };
var posNeptuneX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50;
var posNeptuneY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 283.9;
var gravityNeptune = {x: posNeptuneX, y: posNeptuneY };




function rotate_point(pointX, pointY, originX, originY, ang) {
ang = Math.PI / 180.0;
return {
x: Math.cos(ang) * (pointX-originX) - Math.sin(ang) * (pointY-originY) + originX,
y: Math.sin(ang) * (pointX-originX) + Math.cos(ang) * (pointY-originY) + originY
};
}

var Solarsystem = {
Neptune: {
render: function(){
ctx.beginPath();
gravityNeptune = rotate_point(gravityNeptune.x, gravityNeptune.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityNeptune.x,gravityNeptune.y ,10, 0, 2*Math.PI, true);
ctx.fillStyle = "darkblue";
ctx.closePath();
ctx.fill();

}
}
, Uranus: {
render: function(){
ctx.beginPath();
gravityUranus = rotate_point(gravityUranus.x, gravityUranus.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityUranus.x,gravityUranus.y ,6, 0, 2*Math.PI, true);
ctx.fillStyle = "rgb(64,224,208)";
ctx.closePath();
ctx.fill();
}
}
, Saturn: {
render: function(){
ctx.beginPath();
gravitySaturn = rotate_point(gravitySaturn.x, gravitySaturn.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravitySaturn.x,gravitySaturn.y ,15, 0, 2*Math.PI, true);
ctx.fillStyle = "rgb(186,85,211)";
ctx.closePath();
ctx.fill();

}
}
, Jupiter: {
render: function(){
ctx.beginPath();
gravityJupiter = rotate_point(gravityJupiter.x, gravityJupiter.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityJupiter.x,gravityJupiter.y ,18, 0, 2*Math.PI, true);
ctx.fillStyle = "rgb(255,255,153)";
ctx.closePath();
ctx.fill();


}
}
, Mars: {
render: function(){
ctx.beginPath();
gravityMars = rotate_point(gravityMars.x, gravityMars.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityMars.x,gravityMars.y ,7, 0, 2*Math.PI, true);
ctx.fillStyle = "rgb(255,99,71)";
ctx.closePath();
ctx.fill();

}
}
, Earth: {
render: function(){
ctx.beginPath();
gravityEarth = rotate_point(gravityEarth.x, gravityEarth.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityEarth.x,gravityEarth.y ,8, 0, 2*Math.PI);
ctx.fillStyle = "rgba(30,144,255,1)";
ctx.closePath();
ctx.fill();

}
}
, Venus: {
render: function(){
ctx.beginPath();
gravityVenus = rotate_point(gravityVenus.x, gravityVenus.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityVenus.x,gravityVenus.y ,7, 0, 2*Math.PI);
ctx.fillStyle = "rgba(255,165,0,1)";
ctx.closePath();
ctx.fill();
}
}
, Mercury: {
render: function(){
ctx.beginPath();
gravityMercury = rotate_point(gravityMercury.x, gravityMercury.y, dynamicSunX, dynamicSunY, angleOfSun)
ctx.arc(gravityMercury.x,gravityMercury.y ,5, 0, 2*Math.PI);
ctx.fillStyle = "rgba(119,136,153,1)";
ctx.closePath();
ctx.fill();
ctx.stroke();
}
}
, Sun: {
render: function(){
ctx.fillStyle = "rgba(255,255,51,1)";
ctx.save(); //store ctx so it can be later reused
ctx.shadowColor = 'yellow';
ctx.shadowBlur = 70;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.beginPath();
ctx.arc(dynamicSunX, dynamicSunY, dynamicSunW, dynamicSunH, Math.PI*2, true);
ctx.closePath();
ctx.fill();
ctx.restore(); //ctx at time of save
}
}
}




var bg = new Image();
bg.src = "spacedef.png";
function Background(){
this.x = 0, this.y = 0, this.w = bg.width, this.h = bg.height;
this.render = function(){
ctx.drawImage(bg, this.x--, 0);
if(this.x <= -499){
this.x = 0;
}
}
}

var background = new Background();

function animate(){
background.render();
Solarsystem.Neptune.render();
Solarsystem.Uranus.render();
Solarsystem.Saturn.render();
Solarsystem.Jupiter.render();
Solarsystem.Mars.render();
Solarsystem.Earth.render();
Solarsystem.Venus.render();
Solarsystem.Mercury.render();
Solarsystem.Sun.render();
}
var animateInterval = setInterval(animate, 1000/60);

}

最佳答案

也许可以让所有行星绕太阳旋转,而不是使用彼此相对的旋转点。每个行星都有自己距太阳的半径,因此您的数学可以简化为以下内容(对于圆形轨道):

var neptune.x=sun.x+neptune.radius*Math.cos(radianAngle);
var neptune.y=sun.y+neptune.radius*Math.sin(radianAngle);

当然,行星轨道实际上是椭圆形而不是圆形。您可以像这样计算椭圆上的点:

// Calc points on Ellipse
function getPointsOnEllipse(cx,cy,a,b){
var startAngle=-PI/2;
var lastX=cx-(a*Math.cos(startAngle));
var lastY=cy+(b*Math.sin(startAngle));
var points=[];
// change 1000 to your desired count of waypoints along the ellipse
for(var i=0;i<1000;i++){
var angle=startAngle+PI2/1000*i;
var x=cx-(a*Math.cos(angle));
var y=cy+(b*Math.sin(angle));
var dx=x-lastX;
var dy=y-lastY;
var length=parseInt(Math.sqrt(dx*dx+dy*dy));
var eAngle=(Math.atan2(dy,dx)+PI2)%PI2;
if(length>0){
points.push({x:x,y:y,angle:eAngle});
lastX=x;
lastY=y;
}
}
return(points);
}

关于javascript - 使用动态坐标在 Canvas 上定位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36431960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com