Función para el movimiento del sol?

9

Entonces, dado un sprite solar establecido en el horizonte (x = 0, y = altura mundial / 2) estoy tratando de idear una función para hacer que el sol salga y luego caiga.

La mejor manera de hacerlo sería la función pecado, pero no tengo idea de cómo usarla.

si usa y = sin (x), entonces x tendría que oscilar entre 0 y pi para una curva completa, mientras que tiene una velocidad constante para X.

¿Alguna idea o sugerencia?

Editar: Gracias chicos!

Sol trabajando!

Ross
fuente

Respuestas:

7

Con respecto al problema de 0 a pi, en general todo lo que tiene que hacer es escalar la X por un multiplicador. Ejemplo:

y = sin(x * pi / worldWidth)

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

Sin embargo, esto no tiene la curva que probablemente estás buscando. Debe usar la forma paramétrica:

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

Esta combinación de pecado para Y y cos para X trazará una elipse.

Palanqueta
fuente
Gracias, esto es asombroso. No estoy muy centrado en las matemáticas. Mis habilidades en matemáticas son prácticamente cálculos rudimentarios.
Ross
12

Como Jimmy dijo, una elipse es probablemente una mejor opción para este movimiento. Aquí hay algunas ideas sobre cómo implementarlo realmente con un poco más de detalle para los interesados.

Tomando tiempo

Para empezar, necesitas una variable para hacer un seguimiento del tiempo en el mundo del juego. Puede implementarlo de la manera que desee, pero aquí hay un ejemplo. Usaré una variable llamada hoursque varía de 0 a 24 (aunque cuando llega a 24 vuelve a 0).

Sin embargo, a diferencia de la vida real, consideraré que el día comienza a las 0 horas y la noche comienza a las 12 horas. Esto facilitará algunos de los cálculos.

También definiré la velocidad a la que cambia el tiempo del juego en relación con el tiempo real. En este ejemplo, cada dos minutos de tiempo real corresponderá a una hora en el juego.

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
}

Configuración

Ahora, antes de configurar el movimiento de nuestro sol, necesitamos especificar algunos de sus parámetros. En particular, a qué valor X sube del horizonte, y a qué valor X cae en el horizonte. Además, lo que Y corresponde al horizonte, y qué tan alto se supone que debe elevarse por encima de esa línea.

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

Cálculo de las coordenadas del sol

Ahora es el momento de calcular la posición de nuestro sol para un momento determinado del día. Usaré la misma función paramétrica utilizada por Jimmy pero con el dominio que va desde [0..2PI] en su lugar (para que el sol vuelva a su posición original al amanecer):

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

y = sin (t)

Esta es una buena función porque el valor X varía de 0 a 1 y luego nuevamente a 0 (que asignaremos a los valores X iniciales y finales de nuestro sol) y el valor Y comienza en 0 y sube a 1 y regresa a 0 nuevamente (que sería nuestra porción del día ) y luego repite exactamente lo mismo en el lado negativo antes de volver a la posición original (que sería nuestra noche, aunque el sol no se dibujará en este punto).

El primer paso es escalar las horas desde el rango [0..24) al rango de nuestra función que es [0..2PI):

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

A continuación, aplicamos las funciones para recuperar los valores entre 0 y 1 que mencioné anteriormente:

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

Y finalmente escalamos esos valores usando los parámetros del sol:

float sunX = startX + (endX - startX) * horizontal;    // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical;         // Up and down around horizonY
David Gouveia
fuente
¡+1 por asombro, lo único que lamento es que no puedo marcar dos respuestas!
Ross
No hay problema, de todos modos utilicé las mismas fórmulas base que Jimmy. :)
David Gouveia