空の記録-Gallery of Atmospheric Optics

三重県で空を撮っています ときどきビーチコーミングも

大気光学現象のシミュレーション作成#3-5 視直径を考慮したシミュレーション

2023/03/16

 

Unityで大気光学現象のシミュレーションはできるのか気になったので挑戦してみる7

 

カラム配向の現象がとても難しかったので、先に太陽の視直径を対応させようと思います。

 

グローバル変数 ApparentzDiameter(視直径)をpublicで宣言して、太陽の視直径である0.5を代入します。

public float ApparentzDiameter = 0.5f;

 

Startメソッドに太陽のプレハブのサイズを視直径の値に変更するコードを書きます。

視直径が5°になるように太陽のオブジェクトのサイズを変更するとと直径は0.88になりました。なので太陽のサイズは

0.88\times \dfrac{ApparentzDiameter}{0.5}

=1.76\times ApparentzDiameter

コードはこのようになりました。

 

void Start()
{
        GameObject Sun = Instantiate(SunPrefab);
        Sun.transform.position = new Vector3(0, 0, 0);
        Sun.transform.Rotate(-h, 0, 0);
        Sun.transform.localScale = new Vector3(1.76f * ApparentzDiameter, 1.76f * ApparentzDiameter, 1.76f * ApparentzDiameter);
}

 

次に太陽のどの位置からの光かをランダムで決めるコードを書きます。

円の式はx^{2}+y^{2}≦rで、yについて解くとy\leqq \sqrt{r-x^{2}}になったと思いましたが関数グラフに数式を入力してみると何やらおかしなことに。まだ二次関数習ってないので式の変形がよく分からない…。ただyが正の数の時は正しいのでこの式を利用します。

 

まず変数ApparentzDiameter_Xを-1から1までの値でランダムにとるようにします。

次に変数Sq_rXXに上の式を代入して、floatに変換し、ApparentzDiameter_Yを0からSq_rXXまでの値でランダムにとるようにします。

そして二分の一の確率でYの符号を反転させます。

そのあと

ApparentzDiameter_X ÷ (2 ÷ ApparentzDiameter)

ApparentzDiameter_Y ÷ (2 ÷ ApparentzDiameter)

これで光源のどの位置からの光かをランダムで取得できるようになります。

void ApparentzDiameter_Method()
{ ApparentzDiameter_X = UnityEngine.Random.Range(-1f, 1f); double Sq_rXX = Math.Sqrt(1 - (ApparentzDiameter_X * ApparentzDiameter_X)); float floatSq_rXX = (float)Sq_rXX; ApparentzDiameter_Y = UnityEngine.Random.Range(0, floatSq_rXX); int Random = UnityEngine.Random.Range(0, 2); if (Random == 0) ApparentzDiameter_Y *= -1; ApparentzDiameter_X /= 2 / ApparentzDiameter; ApparentzDiameter_Y /= 2 / ApparentzDiameter;
}

 

しかし問題が発生、返り値は一つだけのようなのでApparentzDiameter_XかApparentzDiameter_Yのどちらかしか渡せません。

結局この二つをグローバル変数にするという方法で解決しました。

 

そして今までの現象の屈折角を計算するメソッドの最初にApparentzDiameter_Methodを実行させてから、計算に出てくるいくつかの式にApparentzDiameter_XかApparentzDiameter_Yを足しました。

実行してみるといいかんじ。太陽高度5°

 

太陽高度60°

 

ひし形の幻日も再現されています。太陽高度50°