はじめに
直角三角形で隣辺 (底辺) と角度 (θ) がわかる時に対辺 (高さ) を求めたいといったアレです。
アプリ内で図形のお絵描きをする際によく忘れるのでまとめます。
開発環境 Xcode 13.2 / Swift 5.5.2
定義
名称の確認。
コード
Playgroundで動かせます。
下の方にある point〜という関数は、各値から円周上の座標 (CGPoint) を一度に取得したい時用です。
import UIKit
/// Convert Degree to Radian
func radian(_ degree: CGFloat) -> CGFloat {
degree * .pi / 180
}
/// Convert Radian to Degree
func degree(_ radian: CGFloat) -> CGFloat {
radian * 180 / .pi
}
/// Find the Angle by using the given Adjacent and Hypotenuse
func angle(adjacent: CGFloat, hypotenuse: CGFloat) -> CGFloat {
acos(adjacent / hypotenuse)
}
/// Find the Angle by using the given Opposite and Hypotenuse
func angle(opposite: CGFloat, hypotenuse: CGFloat) -> CGFloat {
asin(opposite / hypotenuse)
}
/// Find the Angle by using the given Adjacent and Opposite
func angle(adjacent: CGFloat, opposite: CGFloat) -> CGFloat {
atan2(opposite, adjacent)
}
/// Find the Adjacent by using the given Opposite and Angle
func adjacent(opposite: CGFloat, angle: CGFloat) -> CGFloat {
opposite / tan(angle)
}
/// Find the Adjacent using by the given Hypotenuse and Angle
func adjacent(hypotenuse: CGFloat, angle: CGFloat) -> CGFloat {
hypotenuse * cos(angle)
}
/// Find the Opposite by using the given Adjacent and Angle
func opposite(adjacent: CGFloat, angle: CGFloat) -> CGFloat {
adjacent * tan(angle)
}
/// Find the Opposite by using the given Hypotenuse and Angle
func opposite(hypotenuse: CGFloat, angle: CGFloat) -> CGFloat {
hypotenuse * sin(angle)
}
/// Find the Hypotenuse by using the given Adjacent and Angle
func hypotenuse(adjacent: CGFloat, angle: CGFloat) -> CGFloat {
adjacent / cos(angle)
}
/// Find the Hypotenuse by using the given Opposite and Angle
func hypotenuse(opposite: CGFloat, angle: CGFloat) -> CGFloat {
opposite / sin(angle)
}
/// Find the point by using the given Adjacent and Angle
func point(adjacent: CGFloat, angle: CGFloat) -> CGPoint {
let y = opposite(adjacent: adjacent, angle: angle)
return CGPoint(x: adjacent, y: y)
}
/// Find the point by using the given Opposite and Angle
func point(opposite: CGFloat, angle: CGFloat) -> CGPoint {
let x = adjacent(opposite: opposite, angle: angle)
return CGPoint(x: x, y: opposite)
}
/// Find the point by using the given Hypotenuse and Angle
func point(hypotenuse: CGFloat, angle: CGFloat) -> CGPoint {
let x = adjacent(hypotenuse: hypotenuse, angle: angle)
let y = opposite(hypotenuse: hypotenuse, angle: angle)
return CGPoint(x: x, y: y)
}
/// Find the point by using the given Adjacent and Hypotenuse
func point(adjacent: CGFloat, hypotenuse: CGFloat) -> CGPoint {
let angle = angle(adjacent: adjacent, hypotenuse: hypotenuse)
let y = opposite(adjacent: adjacent, angle: angle)
return CGPoint(x: adjacent, y: y)
}
/// Find the point by using the given Opposite and Hypotenuse
func point(opposite: CGFloat, hypotenuse: CGFloat) -> CGPoint {
let angle = angle(opposite: opposite, hypotenuse: hypotenuse)
let x = adjacent(opposite: opposite, angle: angle)
return CGPoint(x: x, y: opposite)
}
検証
Playgroundに引き続き以下を書いて動かしてみます。
値は角度60°、隣辺 : 斜辺 : 対辺 = 1 : 2 : √3 の直角三角形。
let adjacent: CGFloat = 1
let opposite: CGFloat = sqrt(3)
let hypotenuse: CGFloat = 2
let angle: CGFloat = radian(60)
print("adjacent = \(adjacent)")
print("opposite = \(opposite)")
print("hypotenuse = \(hypotenuse)")
print("60 deg = \(angle) rad")
print("angle(adjacent, opposite) = \(angle(adjacent: adjacent, opposite: opposite))")
print("angle(adjacent, hypotenuse) = \(angle(adjacent: adjacent, hypotenuse: hypotenuse))")
print("angle(opposite, hypotenuse) = \(angle(opposite: opposite, hypotenuse: hypotenuse))")
print("adjacent(opposite, angle) = \(adjacent(opposite: opposite, angle: angle))")
print("adjacent(hypotenuse, angle) = \(adjacent(hypotenuse: hypotenuse, angle: angle))")
print("opposite(adjacent, angle) = \(opposite(adjacent: adjacent, angle: angle))")
print("opposite(hypotenuse, angle) = \(opposite(hypotenuse: hypotenuse, angle: angle))")
print("hypotenuse(adjacent, angle) = \(hypotenuse(adjacent: adjacent, angle: angle))")
print("hypotenuse(opposite, angle) = \(hypotenuse(opposite: opposite, angle: angle))")
print("point(adjacent, angle) = \(point(adjacent: adjacent, angle: angle))")
print("point(opposite, angle) = \(point(opposite: opposite, angle: angle))")
print("point(hypotenuse, angle) = \(point(hypotenuse: hypotenuse, angle: angle))")
print("point(adjacent, hypotenuse) = \(point(adjacent: adjacent, hypotenuse: hypotenuse))")
print("point(opposite, hypotenuse) = \(point(opposite: opposite, hypotenuse: hypotenuse))")
これを実行すると以下のような結果が出力されました。
adjacent = 1.0
opposite = 1.7320508075688772
hypotenuse = 2.0
60 deg = 1.0471975511965976 rad
angle(adjacent, opposite) = 1.0471975511965976
angle(adjacent, hypotenuse) = 1.0471975511965976
angle(opposite, hypotenuse) = 1.0471975511965976
adjacent(opposite, angle) = 1.0000000000000002
adjacent(hypotenuse, angle) = 1.0000000000000002
opposite(adjacent, angle) = 1.7320508075688767
opposite(hypotenuse, angle) = 1.7320508075688772
hypotenuse(adjacent, angle) = 1.9999999999999996
hypotenuse(opposite, angle) = 2.0
point(adjacent, angle) = (1.0, 1.7320508075688767)
point(opposite, angle) = (1.0000000000000002, 1.7320508075688772)
point(hypotenuse, angle) = (1.0000000000000002, 1.7320508075688772)
point(adjacent, hypotenuse) = (1.0, 1.7320508075688767)
point(opposite, hypotenuse) = (1.0000000000000002, 1.7320508075688772)
👈 ヨシッ!
参考リンク
・三角関数 – ウィキペディア
https://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0
おわりに
過去を振り返ると、何年かごとにお絵描きが必要なアプリをやることになり、そのたびに今回のようなことを調べてコードを書いていた気がします。
もっと早くブログをやって自分用にまとめていたらと思いました。
同じような誰かのご参考になれば幸いです。