Подтвердить что ты не робот

Единицы из трех. JS, расчет вращательности и скорости орбит

Я пытаюсь построить масштабную модель солнечной системы. Я хотел посмотреть, сможет ли кто-нибудь объяснить мне, как работает скорость вращения. Здесь важная часть:

objects[index].rotation.y += calculateRotationSpeed(value.radius,value.revolution) * delta;

Как скорость вращения связана с фактическим временем? Итак, если у вас скорость 1, это движение 1 px за миллисекунду? Или, если у вас скорость 0,1, это меньше, чем a px в секунду?

В основном я пытаюсь вычислить правильную скорость вращения для планет с учетом их радиуса и количества часов в день. Поэтому, если бы вы были на земле, он завершил бы 1 поворот за 24 часа. Здесь функция, которую я написал, что сейчас делает расчет:

/* In a day */
function calculateRotationSpeed(radius,hrs,delta) {
    var cir = findCircumference(radius);
    if(delta) {
        var d = delta;
    } else {
        var d = 1;
    }
    var ms = hrs2ms(hrs) * d;
    var pxPerMS = km2px(cir) / ms;
    return pxPerMS;
}

Я попробовал, и он все еще кажется слишком быстрым. Мне также нужно что-то подобное для вычисления скорости орбиты.

4b9b3361

Ответ 1

Вращение и единицы измерения

Вращение в три. JS измеряется в радианах. Для тех, кто совершенно незнакомо с радианами (небольшая выдержка из старой моей бумаги):

Как и математическая константа Pi, радиан (примерно 57,3 градуса) получается из соотношения между радиусом окружности (или диаметром) и его окружностью. Один радиан - это угол, который всегда будет охватывать дугу по окружности круга, равную по длине радиусу того же круга (истина для любого круга, независимо от размера). Аналогично, Pi - отношение окружности по диаметру, так что окружность единичной окружности - это точно Pi. Радианцы и градусы на самом деле не являются истинными единицами, фактически углы вообще безразличны (например, проценты и фракции, мы не используем фактические единицы для их описания).

Однако, в отличие от степени, радиан не определялся произвольно, делая его более естественным выбором в большинстве случаев; часто времена были намного проще и гораздо более изящными, ясными и краткими, чем использование степеней в математических формулах. Вероятно, вавилоняне дали нам степень, разделив их круг на 6 равных частей (используя угол равностороннего треугольника). каждый из этих 6 разделов, вероятно, был далее разделен на 60 равных частей, учитывая их числовую систему sexagesimal (базовая 60). Это также позволило бы им использовать такую ​​систему для астрономии, потому что расчетное количество дней в году было намного менее точным в течение их времени и часто считалось 360.

Основное вращение в три раза. JS

Итак, зная, что вы работаете в радианах, если вы увеличиваете с помощью first следующих операторов один раз в вашей функции anim (обратный вызов requestAnimFrame), вы увеличиваете вращение mesh по оси x на один радиан

mesh.rotation.x += 1;                      // Rotates   1 radian  per frame
mesh.rotation.x += Math.PI / 180;          // Rotates   1 degree  per frame
mesh.rotation.x += 45 * Math.PI / 180      // Rotates  45 degrees per frame

Как показывают последние два из приведенных выше утверждений, мы можем использовать Math.PI / 180, чтобы легко преобразовать значение в градусах в радианы перед назначением, если мы хотим вместо этого использовать градусы.

Ввод данных в учетную запись

В вашем случае вам нужно учитывать, сколько времени проходит с каждым фреймом. Это ваша дельта. Вы должны думать об этом так: Сколько FPS мы бегаем? Мы объявим глобальную переменную clock, которая сохранит объект THREE.Clock, который имеет интерфейс к требуемой информации. Нам нужна глобальная переменная, которую мы будем называть clock (должна быть доступна в других функциях, в частности anim):

Внутри init создайте экземпляр THREE.Clock; сохраняя его в переменной, объявленной вне init (с большим объемом):

clock = new THREE.Clock();

Затем в вашей функции anim вы сделаете два вызова, которые будут обновлять две переменные, связанные с clock:

  • time (общее истекшее время в миллисекундах с момента создания часов)
  • delta (время в миллисекундах между каждым фреймом) в двух других глобальных переменных:
 time = clock.getElapsedTime();
 delta = clock.getDelta();

Обратите внимание, что delta предназначен для возврата количества времени между каждым кадром; однако это будет верно тогда и только тогда, когда clock.getDelta последовательно вызывается внутри anim/render

  • Только один раз каждый цикл анимации/рендеринга
  • В том же месте каждый цикл анимации (начало или конец, что не имеет значения, насколько я знаю)

Вышеуказанные условия являются результатом реализации THREE.Clock. getDelta изначально возвращает количество времени с момента создания часов, а затем время, которое он возвращает, просто время, прошедшее с момента последнего вызова). Если это каким-то образом называется ошибочно или непоследовательно, он собирается повредить вещи.

Вращение с дельта-фактором

Теперь, если ваша сцена не запустит процессор или графический процессор, Three.JS и он включил requestAnimationFrame shim, попробует (работает с доступными ресурсами) для обеспечения бесперебойной работы 60 кадров в секунду. Это означает, что в идеале у нас будет примерно 1/60 = .016666 секунд между кадром, это ваше значение delta, которое вы можете читать из clock каждого кадра и использовать его для нормализации скорости на основе частоты кадров путем умножения, как показано ниже. Таким образом, вы можете получить значение в секундах, независимо от небольших изменений частоты кадров, которые вы можете умножать каждый раз, чтобы получить значение в секундах.

Итак, основываясь на том, что у нас было в начале в вашей функции anim, вы можете использовать его так:

mesh.rotation.x += delta * 1;                     // Rotates  1 radian  per second
mesh.rotation.x += delta * Math.PI / 180;         // Rotates  1 degree  per second
mesh.rotation.x += delta * 45 * Math.PI / 180;    // Rotates 45 degrees per second

Частота вращения и единицы измерения

Поскольку наши измерения углов, радианов и градусов на самом деле не являются единицами, тогда, когда мы смотрим на наши единицы для скорости angular, мы увидим, что она будет функционировать только по времени (а не как функция расстояния и времени как в вашем коде).

Вычисление скорости вращения на основе времени

Что касается вашего конкретного случая, вам не нужен радиус для вычисления скорости вращения (скорость angular), вместо этого вы можете использовать количество часов в день (количество времени, которое требуется для полной революции, т.е. 2 * Math.PI радиан вращения на его оси). Если у вас есть переменная с именем revolutionTime, вы можете рассчитать ее так.

secondsInAnHour = 3600;
rotationalSpeed = (2 * Math.PI) / revolutionTime;

Если вы предполагаете, что Земля имеет 24 hours = 24 * 60 * 60 = 86,400 в день (это не так). Затем мы получим rotationalSpeed = 2 * PI / 86,400 или грубо 0.0000727 радиан в секунду. Вы должны уметь находить значения учебников, которые могут быть более точными, чем это (с учетом более точного измерения, чем наша 24-часовая плоская цифра за время, необходимое Земле для завершения революции.

Учитывая ваше дело особенно

Однако я бы не стал беспокоиться о том, чтобы убедиться, что все скорости angular для планет точно верны. Вместо этого лучшей идеей было бы выяснить, каковы соотношения между каждой из скоростей angular (планет) и использовать их. Это будет работать лучше по нескольким причинам: вам, скорее всего, понадобится более высокая скорость вращения, это позволит вам использовать любую скорость вращения, которая работает хорошо; важно, как и любая модель (особенно когда речь заходит об астрономических моделях), заключается в том, что вы держите ее в масштабе.