Güneş hareketi için fonksiyon?


9

Yani, ufukta ayarlanmış bir güneş perdesi verildiğinde (x = 0, y = worldheight / 2) Güneşi doğduracak, sonra düşecek bir işlev tasarlamaya çalışıyorum.

Bunu yapmanın en iyi yolu günah işlevi olacaktır, ancak nasıl kullanılacağına dair hiçbir fikrim yok.

y = sin (x) kullanılıyorsa, x, X için sabit bir hıza sahipken, tam bir eğri için 0 ile pi arasında değişmelidir.

Herhangi bir düşünce veya öneriniz var mı?

Düzenleme: Teşekkürler çocuklar!

Güneş çalışıyor!

Yanıtlar:


7

0 - pi sayısı ile ilgili olarak, genel olarak tek yapmanız gereken X'i bir çarpanla ölçeklendirmektir. Misal:

y = sin(x * pi / worldWidth)

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

Ancak, bu muhtemelen aradığınız eğriyi elde etmez. Parametrik formu kullanmalısınız:

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 için sin ve X için cos'un bu kombinasyonu bir elips izleyecektir.


Teşekkürler, bu harika. Ben matematik merkezli değilim. Matematikteki becerilerim hemen hemen temel matematiktir.
Ross

12

Jimmy'nin dediği gibi bir elips muhtemelen bu harekete daha iyi uyuyor. İlgilenenler için gerçekte nasıl uygulanacağı konusunda bazı fikirler.

Zaman Alma

Yeni başlayanlar için, oyun dünyasındaki zamanı takip etmek için bir değişkene ihtiyacınız var. İstediğiniz gibi uygulayabilirsiniz, ancak işte bir örnek. hours(24'e ulaştığında 0'a geri dönmesine rağmen) 0 ile 24 arasında değişen bir değişken kullanacağım .

Ancak gerçek hayatın aksine, o günün 0 saatte başladığını ve gece 12 saatte başladığını düşüneceğim. Bu bazı hesaplamaları kolaylaştıracaktır.

Ayrıca oyun zamanının gerçek zamana göre değişme hızını da tanımlayacağım. Bu örnekte, gerçek zamanlı her iki dakikada bir oyunda bir saate karşılık gelecektir.

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
}

Yapılandırma

Şimdi güneşimizin hareketini ayarlamadan önce birkaç parametresini belirtmemiz gerekiyor. Özellikle, hangi X değerinde ufuktan yükselir ve hangi X değerinde ufukta düşer. Ayrıca, Y'nin ufka karşılık geldiği şey ve o çizginin üstüne ne kadar yükselmesi gerekiyordu.

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

Güneş'in Koordinatlarını Hesaplama

Şimdi günün belirli bir zamanı için güneşimizin konumunu hesaplamanın zamanı geldi. Jimmy tarafından kullanılan aynı parametrik işlevi kullanacağım ancak bunun yerine [0..2PI] alanından (güneşi gün batımına kadar orijinal konumuna geri getirmek için) kullanacağım:

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

y = günah (t)

Bu iyi bir işlevdir, çünkü X değeri 0'dan 1'e ve sonra tekrar 0'a (güneşimizin başlangıç ​​ve bitiş X değerleriyle eşleştireceğiz) ve Y değeri 0'dan başlar ve 1'e ve geriye gider 0 (tekrar bizim gün bölümü olurdu ) ve daha sonra orijinal konuma geri dönmeden önce negatif tarafında tam olarak aynı şeyi tekrarlar ( güneş bu noktada çizilmez rağmen bu bizim gece olurdu ).

İlk adım, saatleri [0..24) aralığından [0..2PI) fonksiyonumuzun aralığına ölçeklendirmektir:

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

Daha sonra yukarıda bahsettiğim 0 ile 1 arasındaki değerleri geri almak için fonksiyonları uyguluyoruz:

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

Ve son olarak bu değerleri güneşin parametrelerini kullanarak ölçeklendiririz:

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

İnanç için +1, tek pişmanlığım iki cevabı işaretleyemem!
Ross

Sorun değil, yine de Jimmy ile aynı temel formülleri kullandım. :)
David Gouveia
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.