Я использую следующий подход для анимации поля звезды по экрану, но я придерживаюсь следующей части.
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;
}
То, что он делает прямо сейчас, представляет собой анимацию каждой звезды с дельта X, которая считает непрозрачность и размер звезды, поэтому самые маленькие из них, как представляется, движутся медленнее.
Используйте p = t;
, чтобы все звезды двигались с одинаковой скоростью.
ВОПРОС
Я ищу четко определенную модель, где скорости дают иллюзию звезд, вращающихся вокруг счетчика, определяемых в терминах центра вращения cX, cY
, и угла зрения v
, что и есть может быть видна доля 2π (если центр круга не является центром экрана, радиус должен быть как минимум самой большой частью). Я изо всех сил пытаюсь найти способ, который применяет этот косинус к скорости движения звезды, даже для центрированного круга с вращением π.
Эти диаграммы могут объяснить, что мне нужно:
Центрированный круг:
Non-центрированный:
Разный угол обзора:
Я действительно потерял, как двигаться вперед. Я уже немного растянулся, чтобы добраться сюда. Не могли бы вы помочь мне с некоторыми первыми шагами?
Спасибо
UPDATE
Я сделал некоторый прогресс с этим кодом:
// 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
- скорость angular, но это создает эффект маятника. Я не уверен, как изменить эти уравнения, чтобы создать иллюзию, что вместо этого поворачивается наблюдатель.
ОБНОВЛЕНИЕ 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
выводятся из нее. Код существенно отличается и более длинным, поэтому я не размещаю его, но это может быть шаг в правильном направлении. Я не могу заставить это вращаться непрерывно. Использование матричных операций для каждого кадра кажется дорогостоящим с точки зрения производительности.