C#を用いたアプリケーション開発において、数学的な計算は避けて通れない要素の一つです。
特にゲーム開発、データ可視化、画像処理、さらには物理シミュレーションといった分野では、三角関数(Trigonometric Functions)の活用が不可欠となります。
C#には標準ライブラリとして System.Math クラスが用意されており、これを利用することで複雑な数式を記述することなく、高度な計算を容易に実装できます。
本記事では、C#における三角関数の基本となる Math.Sin、Math.Cos、Math.Tan の使い方を詳しく解説します。
特に初心者の方が躓きやすい「ラジアン(弧度法)」と「度(度数法)」の変換や、実務で役立つ逆三角関数の利用方法、さらにはパフォーマンスを意識した MathF クラスの使い分けまで、網羅的に説明していきます。
この記事を通じて、数学が少し苦手な方でも、C#で三角関数を自在に操れるようになることを目指します。
C#における三角関数の基本: Mathクラスの役割
C#で数学計算を行うための心臓部とも言えるのが System.Math クラスです。
このクラスは静的クラスとして定義されているため、インスタンスを生成することなく、どこからでも直接メソッドを呼び出すことが可能です。
System.Mathクラスとは
System.Math クラスは、基本的な算術演算、対数、指数、そして今回解説する三角関数など、幅広い数学メソッドを提供しています。
C#の初期バージョンから存在する信頼性の高いクラスであり、double型の高精度な計算をサポートしているのが特徴です。
三角関数に関連する代表的なメソッドには以下のものがあります。
Math.Sin(double a): 指定された角度(ラジアン)の正弦(サイン)を返します。Math.Cos(double a): 指定された角度(ラジアン)の余弦(コサイン)を返します。Math.Tan(double a): 指定された角度(ラジアン)の正接(タンジェント)を返します。
これらのメソッドはすべて引数として double 型を受け取り、戻り値も double 型となります。
ここで注意が必要なのは、引数に渡す「角度」の単位です。
Math.Sin, Cos, Tan のシグネチャ
プログラミング初心者の方が最初によく起こすミスは、「度数(0度〜360度)」をそのままメソッドに渡してしまうことです。
しかし、C#の Math クラスが期待しているのは「ラジアン」という単位です。
// 誤った例: 90度を求めたいつもりで 90 を渡す
double wrongValue = Math.Sin(90);
このコードを実行しても、数学的な「sin 90° = 1」という結果は得られません。
なぜなら、メソッド内部では「90ラジアン」として処理されてしまうからです。
避けては通れない「ラジアン」と「度」の変換
三角関数を使いこなすための第一歩は、度数法から弧度法への変換をマスターすることです。
なぜ度数法(Degree)では計算できないのか
私たちが日常生活で慣れ親しんでいるのは、1回転を360度とする「度数法(Degree)」です。
しかし、コンピュータサイエンスや高度な数学の世界では、円の半径に基づいた「弧度法(Radian)」が標準として採用されています。
1ラジアンは、「円の半径の長さと、その円弧の長さが等しくなる時の角度」と定義されています。
円周の長さは 2 \* π \* 半径 であるため、360度は 2π ラジアン、180度は π ラジアンに相当します。
この π (円周率) を基準とした計算体系の方が、微積分や級数展開において非常に扱いやすいため、C#を含むほぼすべてのプログラミング言語の数学ライブラリはラジアンを採用しています。
ラジアンと度の変換公式
変換の基本となる関係式は以下の通りです。
- 180度 = πラジアン
- 1度 = π / 180 ラジアン
- 1ラジアン = 180 / π 度
これを踏まえると、C#での変換式は以下のようになります。
// 度からラジアンへ
double radian = degree * (Math.PI / 180.0);
// ラジアンから度へ
double degree = radian * (180.0 / Math.PI);
C#での変換メソッドの実装
再利用性を高めるために、独自のユーティリティメソッドを作成しておくのが実戦的です。
using System;
public static class MathHelper
{
// 度をラジアンに変換する
public static double ToRadians(double degrees)
{
return degrees * (Math.PI / 180.0);
}
// ラジアンを度に変換する
public static double ToDegrees(double radians)
{
return radians * (180.0 / Math.PI);
}
}
このように定義しておけば、Math.Sin(MathHelper.ToRadians(90)) と記述することで、直感的に計算を行うことができます。
各関数の具体的な使い方とコード例
それでは、主要な3つの関数の性質と具体的な実装方法を見ていきましょう。
Math.Sin(正弦): 垂直方向の動きや波の表現
Math.Sin は、単位円上における Y座標(垂直方向の値) に相当します。
角度が0から増加するにつれて、0 → 1 → 0 → -1 → 0 と周期的に変化します。
この特性は、ゲームにおけるキャラクターのジャンプ、浮遊するエフェクト、あるいは音波や電気信号といった「波」のシミュレーションに多用されます。
using System;
class Program
{
static void Main()
{
double degrees = 30.0;
double radians = degrees * (Math.PI / 180.0);
double result = Math.Sin(radians);
Console.WriteLine($"Sin({degrees}°) = {result}");
}
}
Sin(30°) = 0.5
Math.Cos(余弦): 水平方向の動きや円運動
Math.Cos は、単位円上における X座標(水平方向の値) に相当します。
角度が0のときに最大値の1をとり、90度で0、180度で-1となります。
Math.Sin と組み合わせることで、物体を円周上に配置したり、回転させたりすることが可能になります。
using System;
class Program
{
static void Main()
{
double degrees = 60.0;
double radians = degrees * (Math.PI / 180.0);
double result = Math.Cos(radians);
Console.WriteLine($"Cos({degrees}°) = {result}");
}
}
Cos(60°) = 0.5000000000000001
※コンピュータの浮動小数点計算の性質上、微小な誤差が含まれることがありますが、実用上はほぼ 0.5 と見なせます。
Math.Tan(正接): 傾きやアスペクト比の計算
Math.Tan は、Sin / Cos で求められる値であり、直角三角形における「底辺に対する対辺の比率」、つまり 「傾き(スロープ)」 を表します。
用途としては、カメラの画角(FOV)計算や、特定の傾斜角を持つ坂道の高さを求める際などに使用されます。
ただし、90度や270度において値が無限大(または定義不可)になるため、エラーや極端な数値に注意が必要です。
using System;
class Program
{
static void Main()
{
double degrees = 45.0;
double radians = degrees * (Math.PI / 180.0);
double result = Math.Tan(radians);
Console.WriteLine($"Tan({degrees}°) = {result}");
}
}
Tan(45°) = 1
逆三角関数の活用: Math.Asin, Math.Acos, Math.Atan2
三角関数が「角度から比率(座標)」を求めるのに対し、その逆である 「比率(座標)から角度」を求める のが逆三角関数です。
角度を求めるための逆三角関数
Math.Asin(double d): アークサイン。戻り値は -π/2 〜 π/2。Math.Acos(double d): アークコサイン。戻り値は 0 〜 π。Math.Atan(double d): アークタンジェント。戻り値は -π/2 〜 π/2。
これらは、特定の比率から元の角度を割り出したいときに便利です。
Atan2が重要な理由(座標から角度を求める)
プログラミングにおいて最も頻繁に使用されるのが Math.Atan2(double y, double x) です。
通常の Atan は引数が1つですが、Atan2 は Y座標と X座標の2つを引数に取ります。
なぜこれが重要かというと、「どの象限に位置しているか」を自動的に判定してくれるから です。
例えば、(1, 1) という座標と (-1, -1) という座標では、単純な比率 y/x はどちらも 1 ですが、角度は異なります。
Atan2 を使えば、これらを正しく 45度と -135度(または225度)として識別できます。
double y = 1.0;
double x = 1.0;
double angleRad = Math.Atan2(y, x);
double angleDeg = angleRad * (180.0 / Math.PI);
Console.WriteLine($"角度: {angleDeg}°"); // 出力: 45°
実戦的な応用例
ここからは、学んだ三角関数を実際のプログラムでどのように応用するかを見ていきましょう。
オブジェクトの円周移動(2Dゲームの回転など)
特定の中心点 (centerX, centerY) の周りを、半径 radius を保ちながら回転するオブジェクトの座標を計算します。
using System;
class CircleMovement
{
public static void CalculatePosition(double centerX, double centerY, double radius, double angleInDegrees)
{
double radians = angleInDegrees * (Math.PI / 180.0);
// X = 中心X + 半径 * cos(θ)
// Y = 中心Y + 半径 * sin(θ)
double x = centerX + radius * Math.Cos(radians);
double y = centerY + radius * Math.Sin(radians);
Console.WriteLine($"{angleInDegrees}度の時の座標: ({x:F2}, {y:F2})");
}
}
この計算式は、時計の針の動きや、プレイヤーの周りを回るオプションの挙動など、あらゆる回転表現の基礎となります。
2点間の距離と角度の算出
敵キャラクターがプレイヤーの方向を向く(回転する)処理を実装する場合、2点間の相対座標から角度を求める必要があります。
double targetX = 10, targetY = 10;
double playerX = 0, playerY = 0;
double diffX = targetX - playerX;
double diffY = targetY - playerY;
// ターゲットの方向を向くための角度を計算
double rotationRad = Math.Atan2(diffY, diffX);
double rotationDeg = rotationRad * (180.0 / Math.PI);
サイン波を用いたアニメーション
UI要素をやんわりと上下に揺らしたり、透明度をふわふわと変化させたりする(フェードイン・アウトの繰り返し)には、サイン波が最適です。
// 時間経過(秒)に基づいた不透明度の計算 (0.0 ~ 1.0)
double time = 1.5; // 経過時間
double speed = 2.0;
double opacity = (Math.Sin(time * speed) + 1.0) / 2.0;
Math.Sin の結果は -1.0 〜 1.0 なので、それに 1.0 を足して 2.0 で割ることで、0.0 〜 1.0 の範囲に正規化できます。
これは実務で非常に多用されるテクニックです。
パフォーマンスと精度の最適化
モダンなC#開発(特に .NET 6 以降や Unity 環境)では、精度の double だけでなく、パフォーマンスに優れた float(単精度浮動小数点数)を扱う機会が増えています。
Math(double)と MathF(float)の使い分け
System.Math は基本的に double を扱います。
しかし、3Dグラフィックスやゲームエンジン(Unityなど)では、計算負荷を抑えるために float が標準的に使用されます。
C#では、float型に特化した System.MathF クラス も提供されています。
float angle = 45.0f;
float rad = angle * (MathF.PI / 180.0f);
float result = MathF.Sin(rad); // 戻り値も float
Math.Sin を使って結果を (float) でキャストすることも可能ですが、MathF を直接使用した方が、特に大量の計算(数万個のパーティクルの計算など)を行う際に CPU負荷を軽減できる可能性 があります。
数値計算における精度の限界と浮動小数点
コンピュータ上での数学計算には、常に「丸め誤差」がつきまといます。
例えば、数学的には Math.Cos(Math.PI / 2.0) (cos 90°)は厳密に 0 です。
しかし、C#で実行すると 6.123233995736766E-17 といった非常に小さな値が返されることがあります。
これを if (result == 0) のように厳密に比較すると、期待通りに動作しないことがあります。
// 悪い例
if (Math.Cos(angle) == 0) { ... }
// 良い例(許容誤差を設定する)
if (Math.Abs(Math.Cos(angle)) < 0.000001) { ... }
このように、微小な差分を許容する比較方法を採用するのが、プログラミングにおける数学処理の鉄則です。
高度な数学計算:Generic Mathの活用(C# 11以降)
2026年現在のモダンなC#開発において、三角関数に関連するもう一つの重要なトピックが Generic Math(ジェネリック数学) です。
C# 11から導入された INumber<T> などのインターフェースにより、型(float, double, decimalなど)に依存しない汎用的な数学ロジックを記述できるようになりました。
三角関数についても ITrigonometricFunctions<TSelf> インターフェースを通じてアクセス可能です。
public T CalculateSomething<T>(T angle) where T : ITrigonometricFunctions<T>
{
return T.Sin(angle);
}
これにより、ライブラリ開発者は float 用と double 用のメソッドを別々に作成する必要がなくなり、コードの保守性が飛躍的に向上しました。
まとめ
C#で三角関数を扱うための基本から応用までを解説してきました。
重要なポイントを改めて整理しましょう。
- 単位の変換: C#の
Math.Sin / Cos / Tanはすべて「ラジアン」を引数に取ります。「度数 × (π / 180)」の公式を常に意識しましょう。 - メソッドの選択: 高精度が必要な場合は
Math(double)、ゲームやリアルタイム処理で速度を優先する場合はMathF(float) を選択します。 - Atan2の活用: 座標から角度を求める際は、象限を考慮してくれる
Math.Atan2が最も安全で便利です。 - 誤差の考慮: 浮動小数点数の計算には微小な誤差が含まれるため、値の比較には注意が必要です。
三角関数は一見難しそうに思えますが、C#の標準ライブラリを適切に使用すれば、非常に強力な武器になります。
まずは単純な円運動や波の表現から実装してみて、徐々に複雑な物理演算や座標変換へと応用範囲を広げていってください。
数学を味方につけることで、あなたのプログラミングの幅は間違いなく大きく広がることでしょう。
