Функція для руху сонця?


9

Отже, враховуючи спрайт сонця, встановленого на горизонті (x = 0, y = worldheight / 2), я намагаюся розробити функцію, щоб змусити Сонце піднятися, а потім впасти.

Найкращим способом зробити це була б функція гріха, але я не маю уявлення, як її використовувати.

якщо використовується y = sin (x), то для повної кривої х мав би бути від 0 до pi, маючи при цьому постійну швидкість для X.

Якісь думки чи пропозиції?

Редагувати: Спасибі хлопці!

Сонце працює!

Відповіді:


7

Що стосується питання 0 до pi, загалом все, що вам потрібно зробити, - це масштабувати X на множнику. Приклад:

y = sin(x * pi / worldWidth)

http://www.wolframalpha.com/input/?i=Plot%5BSin%5Bx%5D%2C+%7Bx%2C+0%2C+Pi%7D%5D

Однак, це не зовсім крива, яку ви, мабуть, шукаєте. Ви повинні використовувати параметричну форму:

t = 0 -> pi over the course of a day
y = sin(t)   -> goes from 0 up to 1 at noon, then down to 0 again
x = (1-cos(t))/2 -> starts at 0 goes up to 1 by sundown.

http://www.wolframalpha.com/input/?i=ParametricPlot%5B%7B1+-+Cos%5Bt%5D%2C+Sin%5Bt%5D%7D%2C+%7Bt%2C+0%2C+Pi% 7D% 5D

Це поєднання гріха для Y і cos для X вистежить еліпс.


Дякую, це приголомшливо. Я не дуже орієнтований на математику. Мої навички з математики - це майже просто рудиментарне обчислення.
Росс

12

Як сказав Джиммі, еліпс, мабуть, краще підходить для цього руху. Ось кілька ідей щодо того, як насправді реалізувати його, трохи детальніше для зацікавлених.

Займаючи час

Для початку вам потрібна змінна, щоб слідкувати за часом у ігровому світі. Ви можете реалізовувати його будь-яким способом, але вам приклад. Я буду використовувати змінну, яка називається hours, від 0 до 24 (хоча коли вона досягає 24, вона повертається до 0).

На відміну від реального життя, я просто вважаю, що день починається з 0 годин, а ніч починається з 12 годин. Це полегшить деякі розрахунки.

Я також визначу швидкість, з якою змінюється час гри в залежності від реального часу. У цьому прикладі кожні дві хвилини реального часу відповідають одній годині гри.

float hours = 0.0f;                       // From 0 to 24 wrapping around
const float HoursPerSecond = 1f / 120f;   // E.g. 2 minutes = 1 hour ingame

public void Update(float elapsed)
{
    hours += elapsed * HoursPerSecond;    // Advance clock
    if(hours >= 24f) hours -= 24f;        // Wrap around 24 hours
}

Конфігурація

Тепер перед встановленням руху нашого сонця нам потрібно вказати кілька його параметрів. Зокрема, за якого значення X воно піднімається з горизонту, і за якого значення X воно потрапляє в горизонт. Крім того, що Y відповідає горизонту, і наскільки високий він повинен піднятися над цією лінією.

float startX = 0;
float endX = 1000;
float horizonY = worldHeight/2;
float amplitudeY = 200;

Обчислення координат Сонця

Тепер настав час порахувати положення нашого сонця за заданий час доби. Я буду використовувати ту саму параметричну функцію, яку використовував Джиммі, але з доменним діапазоном від [0..2PI] (щоб повернути Сонце у вихідне положення до світанку):

x = (1-cos (t)) / 2

y = sin (t)

Це хороша функція, тому що значення X змінюється від 0 до 1, а потім знову до 0 (що ми будемо відображати до початку та кінця значення нашого сонця X), а значення Y починається з 0 і рухається до 1 і назад до 0 знову (що було б нашою порцією дня ), а потім повторює абсолютно те саме з негативної сторони, перш ніж повернутися в початкове положення (яке було б нашою ніччю, хоча сонце не буде затягнуте в цій точці).

Перший крок - масштабування годин із діапазону [0..24) до діапазону нашої функції, який становить [0..2PI):

float t = (hours / 24f) * MathHelper.TwoPi;          // Scale: [0..24) to [0..2PI)

Далі ми застосовуємо функції для повернення значень між 0 і 1, про які я говорив вище:

float horizontal = (float)((1-Math.Cos(t)) / 2f);    // Changes: 0 1 0
float vertical = (float)(Math.Sin(t));               // Changes: 0 1 0 -1 0

І нарешті ми масштабуємо ці значення за допомогою параметрів сонця:

float sunX = startX + (endX - startX) * horizontal;    // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical;         // Up and down around horizonY

+1 для дивовижності, єдиний жаль, що я не можу відзначити дві відповіді!
Росс

Немає проблем, я все-таки використовував ті самі базові формули, що і Джиммі. :)
Девід Гувейя
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.