Fonction pour le mouvement du soleil?

9

Donc, étant donné un sprite solaire fixé à l'horizon (x = 0, y = worldheight / 2), j'essaie de concevoir une fonction pour faire lever, puis tomber le soleil.

La meilleure façon de le faire serait la fonction sin, mais je ne sais pas comment l'utiliser.

si vous utilisez y = sin (x), alors x devra être compris entre 0 et pi pour une courbe complète, tout en ayant une vitesse constante pour X.

Des pensées ou des suggestions?

Edit: Merci les gars!

Le soleil travaille!

Ross
la source

Réponses:

7

En ce qui concerne le problème de 0 à pi, en général tout ce que vous avez à faire est de mettre à l'échelle le X par un multiplicateur. Exemple:

y = sin(x * pi / worldWidth)

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

Cependant, cela n'obtient pas tout à fait la courbe que vous recherchez probablement. Vous devez utiliser la forme paramétrique:

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

Cette combinaison de sin pour Y et cos pour X tracera une ellipse.

Jimmy
la source
Merci, c'est génial. Je ne suis pas très mathématique. Mes compétences en mathématiques sont à peu près du calcul rudimentaire.
Ross
12

Comme Jimmy l'a dit, une ellipse est probablement mieux adaptée à ce mouvement. Voici quelques idées sur la façon de l'implémenter avec un peu plus de détails pour les personnes intéressées.

Prendre du temps

Pour commencer, vous avez besoin d'une variable pour garder une trace du temps dans le monde du jeu. Vous pouvez l'implémenter comme bon vous semble, mais voici un exemple. J'utiliserai une variable appelée hoursqui varie de 0 à 24 (bien que lorsqu'elle atteint 24, elle revient à 0).

Contrairement à la vraie vie, je considérerai simplement que la journée commence à 0 heure et que la nuit commence à 12 heures. Cela facilitera certains calculs.

Je définirai également la vitesse à laquelle le temps de jeu change par rapport au temps réel. Dans cet exemple, toutes les deux minutes de temps réel correspondront à une heure de jeu.

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
}

Configuration

Maintenant, avant de régler le mouvement de notre soleil, nous devons spécifier quelques-uns de ses paramètres. En particulier, à quelle valeur X monte-t-elle de l'horizon et à quelle valeur X tombe-t-elle à l'horizon. De plus, ce que Y correspond à l'horizon et à quelle hauteur est-il censé s'élever au-dessus de cette ligne.

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

Calcul des coordonnées du soleil

Il est maintenant temps de calculer la position de notre soleil pour une heure donnée de la journée. J'utiliserai à la place la même fonction paramétrique utilisée par Jimmy mais avec un domaine allant de [0..2PI] (afin de ramener le soleil à sa position d'origine au lever du jour):

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

y = sin (t)

C'est une bonne fonction car la valeur X varie de 0 à 1, puis de nouveau à 0 (que nous allons mapper aux valeurs X de début et de fin de notre soleil) et la valeur Y commence à 0 et monte à 1 et retour à 0 à nouveau (ce qui serait notre portion de jour ), puis répète exactement la même chose du côté négatif avant de revenir à la position d'origine (qui serait notre nuit bien que le soleil ne soit pas attiré à ce stade).

La première étape consiste à mettre à l'échelle les heures de la plage [0..24) à la plage de notre fonction qui est [0..2PI):

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

Ensuite, nous appliquons les fonctions pour récupérer les valeurs entre 0 et 1 dont j'ai parlé ci-dessus:

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

Et enfin, nous mettons à l'échelle ces valeurs en utilisant les paramètres du soleil:

float sunX = startX + (endX - startX) * horizontal;    // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical;         // Up and down around horizonY
David Gouveia
la source
+1 pour l'étonnement, mon seul regret est que je ne puisse pas marquer deux réponses!
Ross
Pas de problème, j'ai quand même utilisé les mêmes formules de base que Jimmy. :)
David Gouveia