【发布时间】:2015-10-31 14:15:24
【问题描述】:
我正在采用以下方法在屏幕上为星域设置动画,但我被困在下一部分。
JS
var c = document.getElementById('stars'),
ctx = c.getContext("2d"),
t = 0; // time
c.width = 300;
c.height = 300;
var w = c.width,
h = c.height,
z = c.height,
v = Math.PI; // angle of vision
(function animate() {
Math.seedrandom('bg');
ctx.globalAlpha = 1;
for (var i = 0; i <= 100; i++) {
var x = Math.floor(Math.random() * w), // pos x
y = Math.floor(Math.random() * h), // pos y
r = Math.random()*2 + 1, // radius
a = Math.random()*0.5 + 0.5, // alpha
// linear
d = (r*a), // depth
p = t*d; // pixels per t
x = x - p; // movement
x = x - w * Math.floor(x / w); // go around when x < 0
(function draw(x,y) {
var gradient = ctx.createRadialGradient(x, y, 0, x + r, y + r, r * 2);
gradient.addColorStop(0, 'rgba(255, 255, 255, ' + a + ')');
gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.beginPath();
ctx.arc(x, y, r, 0, 2*Math.PI);
ctx.fillStyle = gradient;
ctx.fill();
return draw;
})(x, y);
}
ctx.restore();
t += 1;
requestAnimationFrame(function() {
ctx.clearRect(0, 0, c.width, c.height);
animate();
});
})();
HTML
<canvas id="stars"></canvas>
CSS
canvas {
background: black;
}
它现在所做的是使用 delta X 为每颗恒星设置动画,该 delta X 考虑了恒星的不透明度和大小,因此最小的那些看起来移动得更慢。
使用p = t; 让所有星星以相同的速度移动。
问题
我正在寻找一个定义明确的模型,其中速度给出了恒星围绕期望者旋转的错觉,根据旋转中心cX, cY 和角度定义视觉v 可以看到2π的几分之一(如果圆心不是屏幕的中心,那么半径应该至少是最大的部分)。我正在努力寻找一种将余弦应用于恒星运动速度的方法,即使对于旋转为 π 的中心圆也是如此。
这些图表可能会进一步解释我所追求的:
中心圆:
非居中:
不同的视角:
我真的不知道如何前进。我已经伸了个懒腰才到这里。你能帮我做一些第一步吗?
谢谢
更新
我在这段代码上取得了一些进展:
// linear
d = (r*a)*z, // depth
v = (2*Math.PI)/w,
p = Math.floor( d * Math.cos( t * v ) ); // pixels per t
x = x + p; // movement
x = x - w * Math.floor(x / w); // go around when x < 0
其中p 是匀速圆周运动粒子的 x 坐标,v 是角速度,但这会产生钟摆效应。我不知道如何改变这些方程来创造观察者正在转动的错觉。
更新 2:
差不多了。 ##Math freenode 频道的一位用户非常友好地建议了以下计算:
// linear
d = (r*a), // depth
p = t*d; // pixels per t
x = x - p; // movement
x = x - w * Math.floor(x / w); // go around when x < 0
x = (x / w) - 0.5;
y = (y / h) - 0.5;
y /= Math.cos(x);
x = (x + 0.5) * w;
y = (y + 0.5) * h;
这在视觉上实现了效果,但在变量方面没有遵循明确定义的模型(它只是“破解”效果)所以我看不到一个直接的方法来做不同的实现(改变中心,视角)。真实模型可能与这个非常相似。
更新 3
根据 Iftah 的回复,我能够使用 Sylvester 将旋转矩阵应用于需要先保存在数组中的星星。现在还确定了每颗星的z 坐标,而半径r 和不透明度a 是从它派生的。代码有很大的不同和更长,所以我没有发布它,但这可能是朝着正确方向迈出的一步。我还不能让它连续旋转。在每帧上使用矩阵运算在性能方面似乎代价高昂。
【问题讨论】:
-
把你的星空想象成天空,想象你的观众从窗外看星星。使您的星空大于视口(大于用户窗口)。然后,例如,随着 cY 向下移动,您将显示更多的顶部和更少的底部您的星空。你没有提到 cZ (就像在你的第二个插图中,人们将眼睛压在视口上观看)。当 cZ 接近视口时,您会在各个方向显示更多的星空。星星是如此遥远,以至于它们各自的速度不需要改变——除非你处于曲速!
-
虽然没有必要在画布上画星星。我认为我们正在寻找的是
p = f(d),它使用余弦来模拟 x 在v的圆圈中的变化。不过,正如您所指出的,有一个 cZ 变量我没有为第一个示例添加,我将添加它。 -
正确,画布元素是您的视口,它显示了较大的星空的一部分(好像超出了画布“窗口”)。您只需要显示位于 canvas 元素内的星空部分。
标签: javascript graphics html5-canvas game-physics trigonometry