ゲーム制作に使う数学を学習しよう
ユニティ・テクノロジーズ・ジャパン
安原 祐二
Part 1
数式とグラフ
10 =
2
10 =
1
2
10 =
−2
指数のおさらい
?
?
?
指数のおさらい
いずれにせよゼロより大きい
10010 =
2
10 =
1
2
10 =
10
1
100
−2
・・・と、言われましても。
y = sin x
y
x
= siny x
入力
出力y
x
= siny x
f( ) = sin
= siny x
xx
ってなんなの
入力と出力が明らか
= siny x
y
f( ) = sinxx
入力
出力
x
f( )x
f( ) = sinxx
入力
出力
突然この値が欲しい
例1
x
f( )x
f( ) = sinxx
入力
出力
単純な増加(等間隔など)
でしか入力を得られない
・・・
例2
x
f( ) = sinxx
f( )x
プログレスバーの工夫 動画
1
1
x
f( ) = 2x x
プログレスバーの工夫
f( ) =x x
f( ) = 2x x
動画
逆関数
f( ) =
f−1
( ) = ?
2x x
x
逆関数
(x > 0)
y x= 2
yx =
逆関数
y x= 2
yx =
f( ) =
f−1
( ) =
2x x
x x
逆関数
= sin
= ???
y x
x
逆関数
= sin−1
= arcsin
= asin
x y
x
x
y
y
= siny x
逆関数
f−1
( ) = asin
f( ) = sin= siny x
= asinx y
x
x
x
x
逆関数
f( ) = sin
y
x
x x
逆関数 y
x
x xf( ) = sin
f(x) = asin(x)
逆関数
x
x xf( ) = sin
逆関数
1
-1
f(x) = asin(x)
x
x xf( ) = sin
まとめ
•  という表記に慣れよう
•グラフは入力と出力の関係
•逆関数を意識しよう
Part 1
数式とグラフ
f(x)
Part 2
式の読みかた
ϵ0
∮
E ⋅ dA = Σq
∮
B ⋅ ds = μ0
∫
J ⋅ dA + μ0ϵ0
d
dt ∫
E ⋅ dA
∮
E ⋅ ds = −
d
dt ∫
B ⋅ dA
∮
B ⋅ dA = 0
足し算と引き算は似たようなもの
a b = c+
 がどこかで定義されてる以上、
+もーもその定義次第
b
a b = c−
掛け算と割り算はカタマリ
ab = c
a
b
= c
ab +
cd
e
= fg
掛け算
割り算
足し算
引き算
と には境界がある
カタマリは混ざらない
等号の左右で単位は等しい
a b
が秒なら も秒
=
a b
が距離なら も距離a b
足し算と引き算と等号は似たようなもの
a b c+ =
足し算と引き算と等号は似たようなもの
a b c+
等号で結ばれているものは結局
足し算や引き算で結ばれている
=
a b c 0+ − =
足し算引き算および等号で
区切られたカタマリの単位は全部同じ
単位の異なるものを足すことは
ありえない
ab +
cd
e
= fg
掛け算か割り算かは
カタマリに対する影響を示す
ab +
cd
e
= fg
d eが増えれば増える が増えれば減る
f( )
例えば  だけが変化するなら  の値は
固定値はどれか?
ab +
c
e
=
d
という関数に従う
d
fg
fg
= ab +
c
e
x x
電流 が増加すれば
∮
B ⋅ ds = μ0
∫
J ⋅ dA + μ0ϵ0
d
dt ∫
E ⋅ dA
磁束密度 が増加する・・・っぽい?B
J
少しは読める(?)
漸化式
= f( )
ひとつ前の値が式の中にある
・ は自然数が基本n
例
an+1 an
a0= 0
・初期値がある
= + 2 + 1an+1 an n
漸化式はプログラミングでおなじみ
= + 1
int a = 0;
void Update() {
a += 1;
}
an+1 an
= + 2× +1 = + =
= + 2 + 1an+1 an
a0= 0
・・・
1
3
5
1
4
9
n
a1 a0 0 a0
= + 2× +1 = + =a2 a1 1 a1
= + 2× +1 = + =a3 a2 2 a2
一般項(前回の値を使わない式)
= + 2× +1 = + =
= + 2 + 1an+1 an
a0= 0
・・・
1
3
5
=
1
4
9
n2an
n
a1 a0 0 a0
= + 2× +1 = + =a2 a1 1 a1
= + 2× +1 = + =a3 a2 2 a2
= + 2× +1 = + =
= + 2 + 1an+1 an
a0= 0
・・・
1
3
5
1
4
9
n
a1 a0 0 a0
= + 2× +1 = + =a2 a1 a1
= + 2× +1 = + =a3 a2 2 a2
1
=n2an
まとめ
•数式を見たら足し算、引き算、等号に注目
•単位を意識しよう(物理の場合)
•漸化式を理解しよう
Part 2
式の読みかた
Part 3
対数
指数関数
f( ) = ≥ 0x xa a
> 1
1
x
f( ) =x xa
a
指数関数の逆関数
=
f( ) =x xa
xay
= ?x
指数関数の逆関数
=
f( ) =x xa
xay
= log yax
指数関数の逆関数
= log
=
f( ) =x xa
xay
x ya
f−1
( ) = logaxx
対数
1 x
f( ) = logaxx
> 1a
f( ) =x xa
ablog
の何乗が なのかab
ablog
の何乗が なのかab
162log = 4
10010log = 2
10100log = 1
2
1
2 = =100 100 10
底の交換
log =
log
log
超便利公式
log
底 を別の底 にしたいa b
a
a
a
b
b
x
x
x
底の交換
log =
log
log
=
1
2
log
公式より
log
底 を別の底 にしたい4 2
4
4
42
2
2
=
2
x
x
x
x
対数のキモ
log = log
交換したい底が定数なら
定数倍になる
4 2
底はどうでもいい
あとで定数倍して調整可能
xx
1
2
応用例:
=
二進数と十進数の桁の数は
比例関係にある
a b
と は比例関係にあるa b
2 10
と は比例関係にあるa b
log = 3.321928094887362
log = 0.301029995663981
ざっくり言えば3倍と1/3倍の関係
32bitは232なので10進数だと10桁程度
=a b
2 10
210
10 2
あ い う え お ま み む め も や ゆ
か き く け こ ら り る れ ろ よ わ
さ し す せ そ が ぎ ぐ げ ご
た ち つ て と ざ じ ず ぜ ぞ
な に ぬ ね の ば び ぶ べ ぼ
は ひ ふ へ ほ ぱ ぴ ぷ ぺ ぽ
文字64種、52文字で表現できるバイト数は?
1byte(256種)は256進数 例:4byteで  の情報量2564
1byte(256種)は256進数 例:4byteで  の情報量2564
64進数の数値を256進数で表現すると何桁か?
文字64種、52文字で表現できるバイト数は?
あ い う え お ま み む め も や ゆ
か き く け こ ら り る れ ろ よ わ
さ し す せ そ が ぎ ぐ げ ご
た ち つ て と ざ じ ず ぜ ぞ
な に ぬ ね の ば び ぶ べ ぼ
は ひ ふ へ ほ ぱ ぴ ぷ ぺ ぽ
log256 64 = 3
4
52 × 3
4
= 39文字 bytes
文字64種、52文字で表現できるバイト数は?
あ い う え お ま み む め も や ゆ
か き く け こ ら り る れ ろ よ わ
さ し す せ そ が ぎ ぐ げ ご
た ち つ て と ざ じ ず ぜ ぞ
な に ぬ ね の ば び ぶ べ ぼ
は ひ ふ へ ほ ぱ ぴ ぷ ぺ ぽ
まとめ
•対数の底の交換は定数倍
Part 3
対数
Part 4
浮動小数点数
問題
問題
float a = 1f;
Debug.Log(a);
Consoleに出力されるのは?
問題
float a = 1f;
Debug.Log(a);
Consoleに出力されるのは?
正解
1
問題
float a = 1/3;
Debug.Log(a);
Consoleに出力されるのは?
問題
Consoleに出力されるのは?
正解
0
float a = 1f/3f;
で0.33333になる
float a = 1/3;
Debug.Log(a);
問題
float a = 3e-1f;
Debug.Log(a);
Consoleに出力されるのは?
問題
Consoleに出力されるのは?
正解
0.3
float a = 3e-1f;
Debug.Log(a);
float a = 3e-1f;
3 10−1
0.3
×
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
符号 指数部(8bits) 仮数部(23bits)
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
符号 指数部(8bits) 仮数部(23bits)
×2(仮数部)
(指数部)
±
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
符号 指数部(8bits) 仮数部(23bits)
×2(仮数部+1.0)
(指数部-127)
±
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
符号 指数部(8bits) 仮数部(23bits)
指数部 [-126, 127]
2 = 1.701411834604692 38127
e
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
符号 指数部(8bits) 仮数部(23bits)
2 = 1.175494350822288 − 38
超絶広い
指数部 [-126, 127]
127
−126
2 = 1.701411834604692 38e
e
億 おく 108
兆 ちょう 1012
京 けい 1016
垓 がい 1020
𥝱 じょ 1024
穣 じょう 1028
溝 こう 1032
澗 かん 1036
正 せい 1040
127
2 = 1.701411834604692 38e
億 おく 108
兆 ちょう 1012
京 けい 1016
垓 がい 1020
𥝱 じょ 1024
穣 じょう 1028
溝 こう 1032
澗 かん 1036
正 せい 1040
涅槃寂静(ねはんじゃくじょう) 10−24
ℏ = 1.054571817e − 34ディラック定数
127
2 = 1.701411834604692 38e
2 = 1.175494350822288 − 38
−126
e
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
符号 指数部(8bits) 仮数部(23bits)
仮数 23bits
ここに限界がある
大きな数値の小さな桁がヤバイ
例:10000000.00000001
2−23
= (
1
2
)23
= 0.00000011920928955078125
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
符号 指数部(8bits) 仮数部(23bits)
1.00000011920928955078125
7桁
2−23
= (
1
2
)23
= 0.00000011920928955078125
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
符号 指数部(8bits) 仮数部(23bits)
1.00000011920928955078125
7桁
log10 2 = 0.301029995663981
2進数の23桁は10進数の6.9桁
23 × log10 2 = 6.923689900271563
0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
10.00000095367431640625
0 1 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
100.00000762939453125
0 1 0 0 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1000.00006103515625
0 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
10000.0009765625
0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
10.00000095367431640625
0 1 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
100.00000762939453125
0 1 0 0 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1000.00006103515625
0 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
10000.0009765625
原点から10km離れた地点では
約1mmの分解能が限界
0 1 0 0 0 1 1 1 1 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
86400.0078125
60秒×60分×24時間=86400
7.8125ミリ秒が限界
16.6666ミリ秒を加算しても
15.625ミリ秒しか加算されない
time += Time.deltaTime;
24時間後には・・・
動画
動画
86400.0000000000145519...
24時間後でも0.014ナノ秒の分解能
doubleなら
31536000.000000003725290...
365日後でも3.7ナノ秒の分解能!
仮数部は52bit
まとめ
•floatの限界を具体的に知ろう
•2進数と10進数の桁の関係を理解しよう
Part 4
浮動小数点数
https://qiita.com/yuji_yasuhara/private/0f94f3b60b4525dd1e74
ブログ:浮動小数点数の限界を把握する
Part 5
RPGで数列
Lv.5
Lv.4
Lv.5
Lv.6
余裕
いい勝負
キビシイ
適切な経験値は?
レベルアップ条件
レベル5
レベル6
同じレベルの
敵を5体倒す Lv.5
レベルアップ条件
レベル5
レベル6
同じレベルの
敵を5体倒す
低いレベルの
敵を8体倒す
高いレベルの
敵を3体倒す
Lv.4
Lv.5
Lv.6
レベルアップ条件
レベル5
レベル6
同じレベルの
敵を5体倒す
レベル31
レベル32
同じレベルの
敵を5体倒す
敵ごとに得られる経験値は固定とする
レベル1 レベル2
10
レベル3
15
レベル31 レベル32
1917511
レベル33
2876266
等比数列
1.5倍
1.5倍
初項10・公比1.5
= × 1.510
N
等比数列
=10
=
=Nn
N
1
2 15
−1n
初項10・公比1.5
N
等比数列
=
初項 ・公比
I
=
= −1
N aI n
n
N
1
2 Ia
I a
レベル1 レベル2
100
レベル3
150
レベル31 レベル32
1917511
レベル33
2876266
1.5倍
1.5倍
100 25
等比数列の和累積経験値は?
等比数列
− 1
−1
=
∑
k=1
k−1 =Mn
等比数列の和:
= −1
N aI n
n
初項 ・公比I a
I
n
a I
an
a
(公式より)
表1
レベル レベルアップ経験値 累積レベルアップ経験値
1 0 0
2 10 10
3 15 25
4 23 48
5 34 81
6 51 132
7 76 208
8 114 322
9 171 493
10 256 749
11 384 1133
12 577 1710
13 865 2575
14 1297 3872
15 1946 5819
… … …
38 21841644 65524912
39 32762466 98287378
40 49143699 147431078
初項10・公比1.5
等比数列
=
∑
k=1
k−1 =Mn
等比数列の和:
= −1
N aI n
n
初項 ・公比I a
I
n
a I
− 1
−1
an
a
x2
− 1 = (x − 1)(x + 1)
x2
− 1 = (x − 1)(x + 1)
x3
− 1 = (x − 1)(x2
+ x + 1)
x4
− 1 = (x − 1)(x3
+ x2
+ x + 1)
= ( )( )xn
− 1 x − 1 xn−1
+ . . . + x2
+ x + 1
x2
− 1 = (x − 1)(x + 1)
x3
− 1 = (x − 1)(x2
+ x + 1)
x4
− 1 = (x − 1)(x3
+ x2
+ x + 1)
= ( )( )
=
xn
− 1 x − 1 xn−1
+ . . . + x2
+ x + 1
xn
− 1
x − 1xn−1
+ . . . + x2
+ x + 1
n
∑
k=1
xk−1
= ( )( )
=
xn
− 1 x − 1 xn−1
+ . . . + x2
+ x + 1
xn
− 1
x − 1xn−1
+ . . . + x2
+ x + 1
=
xn
− 1
x − 1
等比数列
=
∑
k=1
k−1 =Mn
等比数列の和:
= −1
N aI n
n
初項 ・公比I a
I
n
a I
− 1
−1
an
a
= I
a − 1
a − 1
経験値からレベルを逆算
Mn
n
= ?n
経験値からレベルを逆算
(a − 1) = I(a − 1)
a =
I
(a − 1) + 1
= loga{
I
(a − 1) + 1}
= I
a − 1
a − 1
Mn
n
Mn
n
Mnn
n
Mn
まとめ
•経験値が指数関数になる例
•等比数列を扱えるようになろう
•経験値からレベルを知るには対数が必要
Part 5
RPGで数列
ブログ:浮動小数点数の限界を把握する
https://qiita.com/yuji_yasuhara/private/83a67a784d4d6152a2de
Part 6
easing解析
動画
p = Mathf.Lerp(p, T, 0.1f);
p = Mathf.Lerp(p, T, 0.1f);
p = Vector2.Lerp(p, T, 0.1f);
p = Vector3.Lerp(p, T, 0.1f);
a
b
(1− ) +
Lerp (Linear Interpolation)
線形補間
のとき に一致
b
a
のとき に一致
= 0
= 1
a bt t
t
t
float Lerp(float a, float b, float t) {
return (1f - t)*a + t*b;
}
void Update() {
p = Mathf.Lerp(p, T, 0.1f);
}
※最適化の余地あり
p = Mathf.Lerp(p, T, 0.1f);
漸化式
p = func(n, T, 0.1f);
一般項
= (1− ) +
f
pn+1 0.1pn T0.1
= ( )pn n
の一般項を求めよ。ただし    とする。= 0
問題
T, を定数とし、漸化式
= (1− ) +pn+1 pn Tα α
p0
α
= (1− ) +α Tpn+1 pn α
= (1− ) + を満たす を考える
= (1− ) +
s
α Tpn+1 pn
α Tss
α
α
= (1− ) + を満たす を考える
− = ( − )(1− )
= (1− ) +
s
α Tpn+1 pn
α Tss
pn+1 s pn s α
α
α
2式の差を取って
= (1− ) + を満たす を考える
− = ( − )(1− )
= −
= (1− )
とおくと
= (1− ) +
s
α Tpn+1 pn
α Tss
pn+1 s pn s α
qn pn sqn+1 qn α
α
α
2式の差を取って
= (1− ) + を満たす を考える
− = ( − )(1− )
= −
= (1− )
とおくと
= (1− ) +
s
= − = −
= − (1− )
α Tpn+1 pn
α Tss
pn+1 s pn s α
qn pn sqn+1 qn q0 p0 s s
qn s
α
α
α
α
2式の差を取って
の等比数列なので
初項
n
= (1− ) + を満たす を考える
− = ( − )(1− )
= −
= (1− )
とおくと
= (1− ) +
s
= − = −
= − (1− )
α Tpn+1 pn
α Tss
pn+1 s pn s α
qn pn sqn+1 qn q0 p0 s s
qn s
α
α
α
α
− = − (1− )pn s s α
2式の差を取って
の等比数列なので
= − よりqn pn s
初項
n
n
= (1− ) + を満たす を考える
− = ( − )(1− )
= −
= (1− )
とおくと
= (1− ) +
s
= − = −
= − (1− )
=
α Tpn+1 pn
α Tss
pn+1 s pn s α
qn pn sqn+1 qn q0 p0 s s
qn s
α
α
s T
α
α
− = − (1− )
− = − (1− )
pn s s α
pn T T α
2式の差を取って
の等比数列なので
= − よりqn pn s
初項
より
n
n
n
= (1− ) + を満たす を考える
− = ( − )(1− )
= −
= (1− )
とおくと
= (1− ) +
s
= − = −
= − (1− )
=
= {1 − (1− ) }
α Tpn+1 pn
α Tss
pn+1 s pn s α
qn pn sqn+1 qn q0 p0 s s
qn s
α
α
s T
α
α
− = − (1− )
− = − (1− )
pn s s α
pn T T α
pn T α
2式の差を取って
の等比数列なので
= − よりqn pn s
初項
より
n
n
n
n
= {1 − (1− ) }pn T α
T
n
60
n
動的なターゲット変更 動画
Lerpの係数を一般化したい
void Update() {
p = Mathf.Lerp(p, T, 0.1f);
}
60fps版
void Update() {
p = Mathf.Lerp(p, T, ?);
}
30fps版
60fpsのときの係数を とするα
一般項
1秒後
30fpsのときの係数を とするβ
1秒後
= {1 − (1− ) }pn T α
= {1 − (1− ) }p60 T α
= {1 − (1− ) }q30 T β
n
60
30
(1− ) = (1− )
(1− ) = (1− )
= 1 − (1− )
1 − = (1− )
一般化して
α β
α β
αβ
β α
n
m
フレームレートの比 の関数をゲット
3060
n m
n
m
n
m
60fps版 void Update() {
p = Mathf.Lerp(p, T, 0.1f);
}
60fps版 void Update() {
p = Mathf.Lerp(p, T, 0.1f);
}
void Update() {
var beta = 1f - Mathf.Pow(1f-0.1f, 60f/30f);
p = Mathf.Lerp(p, T, beta);
}
30fps版
60fps版 void Update() {
p = Mathf.Lerp(p, T, 0.1f);
}
void Update() {
var beta = 1f - Mathf.Pow(1f-0.1f, 60f/30f);
p = Mathf.Lerp(p, T, beta);
}
30fps版
void Update() {
var beta = 1f - Mathf.Pow(1f-0.1f, 60f*Time.deltaTime);
p = Mathf.Lerp(p, T, beta);
}
汎用版
結果
60fps 30fps
動画
まとめ
•Lerpの動きは等比数列で解ける
•フレームレートの異なる環境に対応可能
Part 6
easing解析
ブログ:Lerpで作るアニメーション(easing)を解析する
https://qiita.com/yuji_yasuhara/private/117b8559beed1a8d8377
Part 7
複素数
虚数単位
i
虚数単位
2
= − 1
意味不明
= −1i
i
複素数
実部
+
= +
虚部
複素数 z
a bi
a biz
+ = ( + ) + ( + )
= +z0 a0 b0 = +z1 a1 b1
z0 z1 a0 a1 b0 b1
i i
i
足し算
+ = ( + ) + ( + )
= +
= ( + )( + )
= + + +
= ( − ) + ( + )
足し算
掛け算
z0 a0 b0 = +z1 a1 b1
z0 z1 a0 a1 b0 b1
i i
i
z0z1 a0 a1b0i b1i
a0a1 a0i b1 ia1b0 i b1b0
a0a1 b1b0 a0b1 a1b0
2
i
public class Complex {
float re;
float im;
複素数の実装
public class Complex {
float re;
float im;
static Complex Add(Complex z0, Complex z1) {
return new Complex() {
re = z0.re + z1.re,
im = z0.im + z1.im,
};
}
複素数の足し算の実装
public class Complex {
float re;
float im;
static Complex Mul(Complex z0, Complex z1) {
return new Complex() {
re = z0.re*z1.re - z0.im*z1.im,
im = z0.re*z1.im + z0.im*z1.re,
};
}
複素数の掛け算の実装
public class Complex {
float re;
float im;
static Complex Mul(Complex z0, Complex z1) {
return new Complex() {
re = z0.re*z1.re - z0.im*z1.im,
im = z0.re*z1.im + z0.im*z1.re,
};
}
複素数の掛け算の実装
iは登場しない! 「作用」と考える
= +z
複素平面
実軸
虚軸
a bib
a
実軸
虚軸
z1
〜足し算〜
= +z0 a0 b0i
z0
実軸
虚軸〜足し算〜
z1
実軸
虚軸
(z0 + z1)
z0
足し算は平行移動
〜足し算〜
z1
実軸
虚軸
z0
〜掛け算〜
z1
実軸
虚軸
z0
〜掛け算〜
1
単位円
z1
実軸
虚軸〜掛け算〜
θ0
r0
z0
z1
実軸
虚軸〜掛け算〜
θ1
r1
z0
z1
実軸
虚軸
z0z1
〜掛け算〜
角度は加算
長さは乗算
z0
z1
参考:クォータニオンの解説動画
https://youtu.be/uKWLPU8gfIY?t=1294
クォータニオン完全マスター
行列・複素数の解説あり
クォータニオンは複素数の拡張
複素数と同じ性質を持つ
拡大縮小も可能
が、Unityでは回転に限定している
var z = new Complex(1f, 0f);
[repeat]
z += z * new Complex(0.01f, 0.25f);
極小コードでジェネラティブアート
マンデルブロ集合(Mandelbrot set)
, は複素数zn c
zn+1 zn c= +2
マンデルブロ集合(Mandelbrot set)
= 0
によって発散したり収束したりする
zn+1 zn c= +2
z0
c
, は複素数zn c
収束
収束収束
収束
発散
収束
収束
発散 発散
発散
発散
発散
発散
画素数ぜんぶチェックする
zn+1 zn c= +2
収束
収束収束
収束
発散
収束
収束
すぐ発散 すぐ発散
発散
すぐ発散
発散
発散
発散はループでチェック
zn+1 zn c= +2
int mandelblot(Complex c) {
var z = new Complex(0f, 0f);
int cnt = 0;
for (var i = 0; i < 100; ++i) {
z = z * z + c;
if (z.sqrMagnitude() > 100f)
return cnt;
++cnt;
}
return 0;
}
zn+1 zn c= +2 動画
Part 8
複素数列
自由研究:らせん状にマスを埋める
一般項はどうなる?
番号を振る
複素平面
実軸
虚軸
複素平面
実軸
虚軸 2 + 2i
−i
f(13) = 2 + 2i
f(6) = − i
・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
第1群 第2群 第3群
1項 2項x4 4項x4
群数列で考える
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
第1群 第2群 第3群
1項 2項x4 4項x4
第15項は第3群の
15-9=6番目
群の中で何番目なのか
l
t
r=0
r=1
r=2
r=3
1
2-i
3-2i
実軸
虚軸
90度
90度
そんな感じで地道に
係数を確定していく・・
an = [N − 1] +
[(
2 − N + (n − (2N − 3)2
− 1))
mod 2(N − 1)
]
i ifloor( n − (2N − 3)2 − 1
2(N − 1) )
N = ceil(
n + 1
2
)ただし
結果
動画
1 8 9
第1群
1項
2 3 4 5 6 7
第2群
1項x6
10 11 12 13 14 15 16 17 18 19
2項x6
第3群
20 21 22 23 24 25 26 27 28 29 30 31
第4群
3項x6
an = s + td
d = (1
2
+
3
2
i)r+1
s = (N − 1)(1
2
+
3
2
i)r
t = m mod l
r = floor(
m
l
)
m = n − 3N2
+ 9N − 8
l = N − 1
N = ceil(1
2
+
3
6
4n − 1)
ただし
結果
動画
まとめ
Part 8
複素数列
ブログ:らせん状にマスを埋める複素数数列と戯れる
https://qiita.com/yuji_yasuhara/private/23088d82a5c0ed8551bc
おしまい

【Unity道場】ゲーム制作に使う数学を学習しよう