🔺
Goで三角関数を使った進行方向の処理で詰まったのでまとめてみた
Goで三角関数を使った進行方向の処理に詰まったのでまとめます。
いわゆるレトロなRPGゲームのキャラ移動のイメージです。
コードはこちら。
詰まったポイントは以下の2点でした。
- sin、cos算定用の関数は90度、180度のようないわゆる角度ではなく、ラジアンを指定する必要があるがGoには角度からラジアンを直接算定する標準パッケージがない。
ラジアン(英: radian, 記号: rad)は、国際単位系 (SI) における角度(平面角)の単位である。
円周上でその円の半径と同じ長さの弧を切り取る2本の半径が成す角の値と定義される。
- 処理上端数が出てしまうが、切り捨てや切り上げではなく四捨五入を使う必要がありました。
var angle float64
angle = 90
var radian float64
// ラジアン変換
radian = angle * math.Pi / 180
math.Cos(radian)
math.Sin(radian))
出力結果:
角度90度の場合 Cos: 6.123233995736757e-17 Sin: 1
角度270度の場合 Cos: -1.8369701987210272e-16 Sin: -1
無理数の π を使ってラジアンを算定しているせいか、cos90°、cos270° に端数が生じてしまいました。
math.Floor(math.Cos(radian))
math.Floor(math.Sin(radian))
出力結果:
角度90度の場合 Cos: 0 Sin: 1
角度270度の場合 Cos: -1 Sin: -1
切り捨ての結果、-0.000000..の cos270° が 0 ではなく -1 になってしまいました。
math.Ceil(math.Cos(radian))
math.Ceil(math.Sin(radian)))
出力結果:
角度90度の場合 Cos: 1 Sin: 1
角度270度の場合 Cos: -0 Sin: -1
切り上げの結果、0.0000... の cos90° が 0 ではなく 1 になってしまいました。
math.Round(math.Cos(radian))
math.Round(math.Sin(radian))
出力結果:
角度90度の場合 Cos: 0 Sin: 1
角度270度の場合 Cos: -0 Sin: -1
-0 は気になるものの、ちゃんと cos、sin が計算されています。
進行方向の処理
こんな感じで 角度を変えてやれば x軸方向、y軸方向の移動を処理できます。
for i:=0; i<4; i++{
radian = angle * math.Pi / 180
x = x + math.Round(math.Cos(radian))*10
y = y + math.Round(math.Sin(radian))*10
angle = angle + 90
}
以上になります、最後までお読みいただきありがとうございました。
コード全体
package main
import (
"fmt"
"math"
)
func main() {
var angle float64
angle = 90
var radian float64
var x, y float64
for i := 0; i < 8; i++ {
radian = angle * math.Pi / 180
fmt.Println("そのまま 角度:", angle, " Cos:", math.Cos(radian), " Sin:", math.Sin(radian))
fmt.Println("切り捨て 角度:", angle, " Cos:", math.Floor(math.Cos(radian)), " Sin:", math.Floor(math.Sin(radian)))
fmt.Println("切り上げ 角度:", angle, " Cos:", math.Ceil(math.Cos(radian)), " Sin:", math.Ceil(math.Sin(radian)))
fmt.Println("四捨五入 角度:", angle, " Cos:", math.Round(math.Cos(radian)), " Sin:", math.Round(math.Sin(radian)))
x = x + math.Cos(radian)
y = y + math.Sin(radian)
angle = angle + 90.0
}
fmt.Println("そのまま")
x, y = 5, -5
angle = 90
for i := 0; i < 8; i++ {
radian = angle * math.Pi / 180
x = x + math.Cos(radian)*10
y = y + math.Sin(radian)*10
fmt.Println("角度:", angle, x, y)
angle = angle + 90.0
}
fmt.Println("切り捨て")
x, y = 5, -5
angle = 90
for i := 0; i < 8; i++ {
radian = angle * math.Pi / 180
x = x + math.Floor(math.Cos(radian))*10
y = y + math.Floor(math.Sin(radian))*10
fmt.Println("角度:", angle, x, y)
angle = angle + 90.0
}
fmt.Println("切り上げ")
x, y = 5, -5
angle = 90
for i := 0; i < 8; i++ {
radian = angle * math.Pi / 180
x = x + math.Ceil(math.Cos(radian))*10
y = y + math.Ceil(math.Sin(radian))*10
fmt.Println("角度:", angle, x, y)
fmt.Println("角度:", angle, x, y)
angle = angle + 90.0
}
fmt.Println("四捨五入")
x, y = 5, -5
angle = 90
for i := 0; i < 8; i++ {
radian = angle * math.Pi / 180
x = x + math.Round(math.Cos(radian))*10
y = y + math.Round(math.Sin(radian))*10
fmt.Println("角度:", angle, x, y)
angle = angle + 90.0
}
}
出力結果
のまま 角度: 90 Cos: 6.123233995736757e-17 Sin: 1
切り捨て 角度: 90 Cos: 0 Sin: 1
切り上げ 角度: 90 Cos: 1 Sin: 1
四捨五入 角度: 90 Cos: 0 Sin: 1
そのまま 角度: 180 Cos: -1 Sin: 1.2246467991473515e-16
切り捨て 角度: 180 Cos: -1 Sin: 0
切り上げ 角度: 180 Cos: -1 Sin: 1
四捨五入 角度: 180 Cos: -1 Sin: 0
そのまま 角度: 270 Cos: -1.8369701987210272e-16 Sin: -1
切り捨て 角度: 270 Cos: -1 Sin: -1
切り上げ 角度: 270 Cos: -0 Sin: -1
四捨五入 角度: 270 Cos: -0 Sin: -1
そのまま 角度: 360 Cos: 1 Sin: -2.449293598294703e-16
切り捨て 角度: 360 Cos: 1 Sin: -1
切り上げ 角度: 360 Cos: 1 Sin: -0
四捨五入 角度: 360 Cos: 1 Sin: -0
そのまま 角度: 450 Cos: 3.0616169978683787e-16 Sin: 1
切り捨て 角度: 450 Cos: 0 Sin: 1
切り上げ 角度: 450 Cos: 1 Sin: 1
四捨五入 角度: 450 Cos: 0 Sin: 1
そのまま 角度: 540 Cos: -1 Sin: 3.6739403974420544e-16
切り捨て 角度: 540 Cos: -1 Sin: 0
切り上げ 角度: 540 Cos: -1 Sin: 1
四捨五入 角度: 540 Cos: -1 Sin: 0
そのまま 角度: 630 Cos: -4.28626379701573e-16 Sin: -1
切り捨て 角度: 630 Cos: -1 Sin: -1
切り上げ 角度: 630 Cos: -0 Sin: -1
四捨五入 角度: 630 Cos: -0 Sin: -1
そのまま 角度: 720 Cos: 1 Sin: -4.898587196589406e-16
切り捨て 角度: 720 Cos: 1 Sin: -1
切り上げ 角度: 720 Cos: 1 Sin: -0
四捨五入 角度: 720 Cos: 1 Sin: -0
そのまま
角度: 90 5.000000000000001 5
角度: 180 -4.999999999999999 5.000000000000001
角度: 270 -5.000000000000001 -4.999999999999999
角度: 360 4.999999999999999 -5.000000000000002
角度: 450 5.000000000000002 4.999999999999998
角度: 540 -4.999999999999998 5.000000000000002
角度: 630 -5.000000000000003 -4.999999999999998
角度: 720 4.999999999999997 -5.0000000000000036
切り捨て
角度: 90 5 5
角度: 180 -5 5
角度: 270 -15 -5
角度: 360 -5 -15
角度: 450 -5 -5
角度: 540 -15 -5
角度: 630 -25 -15
角度: 720 -15 -25
切り上げ
角度: 90 15 5
角度: 90 15 5
角度: 180 5 15
角度: 180 5 15
角度: 270 5 5
角度: 270 5 5
角度: 360 15 5
角度: 360 15 5
角度: 450 25 15
角度: 450 25 15
角度: 540 15 25
角度: 540 15 25
角度: 630 15 15
角度: 630 15 15
角度: 720 25 15
角度: 720 25 15
四捨五入
角度: 90 5 5
角度: 180 -5 5
角度: 270 -5 -5
角度: 360 5 -5
角度: 450 5 5
角度: 540 -5 5
角度: 630 -5 -5
角度: 720 5 -5
Discussion