こんにちは!今回は、PHPの標準関数であるsin()について詳しく解説していきます。三角関数の一つで、角度のサイン(正弦)を計算する数学関数です!
sin関数とは?
sin()関数は、指定された角度のサイン(正弦)を計算する関数です。
引数はラジアン単位で指定し、-1から1の範囲の値を返します。数学、物理、グラフィックス、波形処理など、様々な分野で使用されます!
基本的な構文
sin(float $num): float
- $num: ラジアン単位の角度
- 戻り値: サイン値(-1.0から1.0の範囲)
基本的な使用例
シンプルな計算
// 0ラジアン(0度)のサイン
echo sin(0); // 0
// π/2ラジアン(90度)のサイン
echo sin(M_PI / 2); // 1
// πラジアン(180度)のサイン
echo sin(M_PI); // 1.2246467991474E-16(ほぼ0)
// 3π/2ラジアン(270度)のサイン
echo sin(3 * M_PI / 2); // -1
// 2πラジアン(360度)のサイン
echo sin(2 * M_PI); // -2.4492935982947E-16(ほぼ0)
度数法からラジアンへの変換
// 度数法をラジアンに変換
function degToRad($degrees) {
return $degrees * M_PI / 180;
}
// 30度のサイン
echo sin(degToRad(30)); // 0.5
// 45度のサイン
echo sin(degToRad(45)); // 0.70710678118655
// 60度のサイン
echo sin(degToRad(60)); // 0.86602540378444
// 90度のサイン
echo sin(degToRad(90)); // 1
deg2rad()関数を使用
// PHPの組み込み関数を使用
echo sin(deg2rad(30)); // 0.5
echo sin(deg2rad(45)); // 0.70710678118655
echo sin(deg2rad(60)); // 0.86602540378444
echo sin(deg2rad(90)); // 1
主要な角度のサイン値
// 主要な角度
$angles = [0, 30, 45, 60, 90, 120, 135, 150, 180, 270, 360];
echo "角度\tサイン値\n";
foreach ($angles as $angle) {
$sinValue = sin(deg2rad($angle));
echo sprintf("%d°\t%.4f\n", $angle, $sinValue);
}
/*
角度 サイン値
0° 0.0000
30° 0.5000
45° 0.7071
60° 0.8660
90° 1.0000
120° 0.8660
135° 0.7071
150° 0.5000
180° 0.0000
270° -1.0000
360° -0.0000
*/
実践的な使用例
例1: 三角関数計算機
class TrigCalculator {
/**
* サイン(度数法)
*/
public static function sinDeg($degrees) {
return sin(deg2rad($degrees));
}
/**
* コサイン(度数法)
*/
public static function cosDeg($degrees) {
return cos(deg2rad($degrees));
}
/**
* タンジェント(度数法)
*/
public static function tanDeg($degrees) {
return tan(deg2rad($degrees));
}
/**
* すべての三角関数値を取得
*/
public static function getAllTrig($degrees) {
$radians = deg2rad($degrees);
return [
'angle_deg' => $degrees,
'angle_rad' => $radians,
'sin' => sin($radians),
'cos' => cos($radians),
'tan' => tan($radians)
];
}
/**
* サイン値から角度を求める(アークサイン)
*/
public static function arcsinDeg($value) {
if ($value < -1 || $value > 1) {
return null;
}
return rad2deg(asin($value));
}
/**
* 三角関数の表を生成
*/
public static function generateTable($start = 0, $end = 360, $step = 15) {
$table = [];
for ($angle = $start; $angle <= $end; $angle += $step) {
$table[] = self::getAllTrig($angle);
}
return $table;
}
/**
* 単位円上の座標を計算
*/
public static function getUnitCirclePoint($degrees, $radius = 1) {
$radians = deg2rad($degrees);
return [
'x' => $radius * cos($radians),
'y' => $radius * sin($radians)
];
}
}
// 使用例
echo "=== 三角関数計算機 ===\n";
// 特定角度の計算
$angle = 45;
echo "{$angle}度の三角関数:\n";
$trig = TrigCalculator::getAllTrig($angle);
echo " sin: " . round($trig['sin'], 4) . "\n";
echo " cos: " . round($trig['cos'], 4) . "\n";
echo " tan: " . round($trig['tan'], 4) . "\n";
// アークサイン
echo "\n=== アークサイン ===\n";
$sinValue = 0.5;
$angle = TrigCalculator::arcsinDeg($sinValue);
echo "sin⁻¹({$sinValue}) = {$angle}度\n";
// 三角関数の表
echo "\n=== 三角関数表(15度刻み) ===\n";
echo "角度\tsin\t\tcos\t\ttan\n";
$table = TrigCalculator::generateTable(0, 90, 15);
foreach ($table as $row) {
echo sprintf(
"%d°\t%.4f\t\t%.4f\t\t%.4f\n",
$row['angle_deg'],
$row['sin'],
$row['cos'],
$row['tan']
);
}
// 単位円上の点
echo "\n=== 単位円上の点 ===\n";
$point = TrigCalculator::getUnitCirclePoint(60);
echo "60度の位置: (" . round($point['x'], 4) . ", " . round($point['y'], 4) . ")\n";
例2: 波形生成器
class WaveGenerator {
/**
* サイン波を生成
*/
public static function generateSineWave($samples, $frequency = 1, $amplitude = 1, $phase = 0) {
$wave = [];
for ($i = 0; $i < $samples; $i++) {
$t = $i / $samples;
$value = $amplitude * sin(2 * M_PI * $frequency * $t + $phase);
$wave[] = $value;
}
return $wave;
}
/**
* 複数の波を合成
*/
public static function combineSineWaves($samples, $waves) {
$combined = array_fill(0, $samples, 0);
foreach ($waves as $wave) {
$sineWave = self::generateSineWave(
$samples,
$wave['frequency'] ?? 1,
$wave['amplitude'] ?? 1,
$wave['phase'] ?? 0
);
for ($i = 0; $i < $samples; $i++) {
$combined[$i] += $sineWave[$i];
}
}
return $combined;
}
/**
* ASCIIアートで波形を表示
*/
public static function visualizeWave($wave, $height = 20) {
$min = min($wave);
$max = max($wave);
$range = $max - $min;
if ($range == 0) {
return;
}
$output = [];
foreach ($wave as $value) {
$normalized = ($value - $min) / $range;
$row = (int)round($normalized * ($height - 1));
$output[] = $height - 1 - $row;
}
for ($y = 0; $y < $height; $y++) {
$line = '';
foreach ($output as $x => $rowIndex) {
if ($rowIndex === $y) {
$line .= '*';
} else {
$line .= ' ';
}
}
echo $line . "\n";
}
}
/**
* 波形の統計情報
*/
public static function getWaveStats($wave) {
return [
'min' => min($wave),
'max' => max($wave),
'average' => array_sum($wave) / count($wave),
'amplitude' => (max($wave) - min($wave)) / 2,
'samples' => count($wave)
];
}
}
// 使用例
echo "=== 波形生成 ===\n";
// 単純なサイン波
$sineWave = WaveGenerator::generateSineWave(50, 1, 1, 0);
echo "サイン波(最初の10サンプル):\n";
for ($i = 0; $i < 10; $i++) {
echo sprintf("Sample %2d: %+.4f\n", $i, $sineWave[$i]);
}
// 波形の統計
echo "\n=== 波形統計 ===\n";
$stats = WaveGenerator::getWaveStats($sineWave);
print_r($stats);
// ASCIIアート表示
echo "\n=== サイン波の可視化 ===\n";
WaveGenerator::visualizeWave($sineWave, 15);
// 複数波の合成
echo "\n=== 複数波の合成 ===\n";
$waves = [
['frequency' => 1, 'amplitude' => 1],
['frequency' => 2, 'amplitude' => 0.5],
['frequency' => 3, 'amplitude' => 0.3]
];
$combined = WaveGenerator::combineSineWaves(50, $waves);
WaveGenerator::visualizeWave($combined, 15);
例3: 円運動シミュレーター
class CircularMotion {
/**
* 円運動の位置を計算
*/
public static function getPosition($angle, $radius, $centerX = 0, $centerY = 0) {
$radians = deg2rad($angle);
return [
'x' => $centerX + $radius * cos($radians),
'y' => $centerY + $radius * sin($radians),
'angle' => $angle
];
}
/**
* 円運動の軌跡を生成
*/
public static function generateTrajectory($radius, $steps = 360, $centerX = 0, $centerY = 0) {
$trajectory = [];
$angleStep = 360 / $steps;
for ($i = 0; $i <= $steps; $i++) {
$angle = $i * $angleStep;
$trajectory[] = self::getPosition($angle, $radius, $centerX, $centerY);
}
return $trajectory;
}
/**
* 速度ベクトルを計算
*/
public static function getVelocity($angle, $radius, $angularVelocity) {
$radians = deg2rad($angle);
// 速度 = 半径 × 角速度
$speed = $radius * $angularVelocity;
return [
'vx' => -$speed * sin($radians),
'vy' => $speed * cos($radians),
'speed' => $speed
];
}
/**
* リサージュ図形を生成
*/
public static function generateLissajous($a, $b, $delta, $samples = 1000) {
$points = [];
for ($i = 0; $i <= $samples; $i++) {
$t = $i / $samples * 2 * M_PI;
$x = sin($a * $t + $delta);
$y = sin($b * $t);
$points[] = ['x' => $x, 'y' => $y];
}
return $points;
}
/**
* 楕円運動を生成
*/
public static function generateEllipse($radiusX, $radiusY, $steps = 360) {
$points = [];
$angleStep = 360 / $steps;
for ($i = 0; $i <= $steps; $i++) {
$angle = deg2rad($i * $angleStep);
$points[] = [
'x' => $radiusX * cos($angle),
'y' => $radiusY * sin($angle)
];
}
return $points;
}
}
// 使用例
echo "=== 円運動シミュレーション ===\n";
// 円上の位置
$position = CircularMotion::getPosition(45, 10);
echo "45度の位置:\n";
echo " x: " . round($position['x'], 2) . "\n";
echo " y: " . round($position['y'], 2) . "\n";
// 速度ベクトル
echo "\n=== 速度ベクトル ===\n";
$velocity = CircularMotion::getVelocity(45, 10, 2);
echo "45度での速度:\n";
echo " vx: " . round($velocity['vx'], 2) . "\n";
echo " vy: " . round($velocity['vy'], 2) . "\n";
echo " 速さ: " . round($velocity['speed'], 2) . "\n";
// 軌跡(8点のみ表示)
echo "\n=== 円運動の軌跡(8点) ===\n";
$trajectory = CircularMotion::generateTrajectory(5, 8);
foreach ($trajectory as $i => $point) {
echo sprintf(
"点%d: (%+.2f, %+.2f) at %d度\n",
$i + 1,
$point['x'],
$point['y'],
$point['angle']
);
}
// 楕円運動
echo "\n=== 楕円運動(主要8点) ===\n";
$ellipse = CircularMotion::generateEllipse(10, 5, 8);
foreach ($ellipse as $i => $point) {
echo sprintf(
"点%d: (%+.2f, %+.2f)\n",
$i + 1,
$point['x'],
$point['y']
);
}
例4: アニメーション計算
class AnimationHelper {
/**
* イージング関数(サインイーズ)
*/
public static function easeInSine($t) {
return 1 - cos(($t * M_PI) / 2);
}
public static function easeOutSine($t) {
return sin(($t * M_PI) / 2);
}
public static function easeInOutSine($t) {
return -(cos(M_PI * $t) - 1) / 2;
}
/**
* 振動アニメーション
*/
public static function oscillate($t, $frequency = 1, $amplitude = 1) {
return $amplitude * sin(2 * M_PI * $frequency * $t);
}
/**
* フェードイン/アウト
*/
public static function fade($t, $type = 'in') {
if ($type === 'in') {
return self::easeInSine($t);
} else {
return self::easeOutSine($t);
}
}
/**
* バウンス効果
*/
public static function bounce($t, $bounces = 3) {
return abs(sin($t * M_PI * $bounces));
}
/**
* 波打つ動き
*/
public static function wave($position, $time, $wavelength = 1, $amplitude = 1) {
return $amplitude * sin(2 * M_PI * ($position / $wavelength - $time));
}
/**
* アニメーションフレームを生成
*/
public static function generateFrames($duration, $fps, $callback) {
$frames = [];
$totalFrames = $duration * $fps;
for ($frame = 0; $frame <= $totalFrames; $frame++) {
$t = $frame / $totalFrames;
$frames[] = [
'frame' => $frame,
'time' => $t,
'value' => $callback($t)
];
}
return $frames;
}
}
// 使用例
echo "=== アニメーション計算 ===\n";
// イージング比較
echo "イージング比較(0.0から1.0まで0.25刻み):\n";
echo "t\tLinear\tEaseIn\tEaseOut\tEaseInOut\n";
for ($t = 0; $t <= 1; $t += 0.25) {
echo sprintf(
"%.2f\t%.4f\t%.4f\t%.4f\t%.4f\n",
$t,
$t,
AnimationHelper::easeInSine($t),
AnimationHelper::easeOutSine($t),
AnimationHelper::easeInOutSine($t)
);
}
// 振動アニメーション
echo "\n=== 振動アニメーション ===\n";
$frames = AnimationHelper::generateFrames(1, 10, function($t) {
return AnimationHelper::oscillate($t, 2, 100);
});
foreach ($frames as $frame) {
echo sprintf(
"Frame %2d (t=%.2f): %+.2f\n",
$frame['frame'],
$frame['time'],
$frame['value']
);
}
// バウンス効果
echo "\n=== バウンス効果 ===\n";
for ($t = 0; $t <= 1; $t += 0.1) {
$value = AnimationHelper::bounce($t, 3);
echo sprintf("t=%.1f: %.4f\n", $t, $value);
}
例5: 物理シミュレーション
class PhysicsSimulator {
/**
* 単振動(バネの運動)
*/
public static function simpleHarmonicMotion($time, $amplitude, $frequency, $phase = 0) {
$omega = 2 * M_PI * $frequency;
return $amplitude * sin($omega * $time + $phase);
}
/**
* 振り子の運動
*/
public static function pendulumMotion($time, $length, $angle0, $g = 9.8) {
// 小角度近似
$omega = sqrt($g / $length);
return $angle0 * sin($omega * $time);
}
/**
* 減衰振動
*/
public static function dampedOscillation($time, $amplitude, $frequency, $damping) {
return $amplitude * exp(-$damping * $time) * sin(2 * M_PI * $frequency * $time);
}
/**
* 投射運動の軌跡
*/
public static function projectileMotion($velocity, $angle, $time, $g = 9.8) {
$radians = deg2rad($angle);
$vx = $velocity * cos($radians);
$vy = $velocity * sin($radians);
return [
'x' => $vx * $time,
'y' => $vy * $time - 0.5 * $g * $time * $time,
'vx' => $vx,
'vy' => $vy - $g * $time
];
}
/**
* 波の干渉
*/
public static function waveInterference($x, $t, $sources) {
$amplitude = 0;
foreach ($sources as $source) {
$distance = abs($x - $source['position']);
$phase = 2 * M_PI * ($source['frequency'] * $t - $distance / $source['wavelength']);
$amplitude += $source['amplitude'] * sin($phase);
}
return $amplitude;
}
}
// 使用例
echo "=== 物理シミュレーション ===\n";
// 単振動
echo "単振動(振幅10、周波数1Hz):\n";
for ($t = 0; $t <= 1; $t += 0.1) {
$position = PhysicsSimulator::simpleHarmonicMotion($t, 10, 1);
echo sprintf("t=%.1fs: 位置=%.2fcm\n", $t, $position);
}
// 振り子
echo "\n=== 振り子運動 ===\n";
echo "長さ1m、初期角度30度:\n";
for ($t = 0; $t <= 2; $t += 0.2) {
$angle = PhysicsSimulator::pendulumMotion($t, 1, deg2rad(30));
echo sprintf("t=%.1fs: 角度=%.2f度\n", $t, rad2deg($angle));
}
// 投射運動
echo "\n=== 投射運動 ===\n";
echo "初速20m/s、角度45度:\n";
for ($t = 0; $t <= 2; $t += 0.5) {
$pos = PhysicsSimulator::projectileMotion(20, 45, $t);
if ($pos['y'] >= 0) {
echo sprintf(
"t=%.1fs: x=%.2fm, y=%.2fm\n",
$t,
$pos['x'],
$pos['y']
);
}
}
// 減衰振動
echo "\n=== 減衰振動 ===\n";
echo "振幅10、周波数1Hz、減衰係数0.5:\n";
for ($t = 0; $t <= 3; $t += 0.5) {
$amplitude = PhysicsSimulator::dampedOscillation($t, 10, 1, 0.5);
echo sprintf("t=%.1fs: 振幅=%.2f\n", $t, $amplitude);
}
例6: SVGグラフ生成
class SVGGraphGenerator {
/**
* サイン波のSVGを生成
*/
public static function generateSineWaveSVG($width = 800, $height = 400, $periods = 2) {
$svg = "<svg width='{$width}' height='{$height}' xmlns='http://www.w3.org/2000/svg'>\n";
// 背景
$svg .= "<rect width='{$width}' height='{$height}' fill='white' stroke='black'/>\n";
// 中心線
$centerY = $height / 2;
$svg .= "<line x1='0' y1='{$centerY}' x2='{$width}' y2='{$centerY}' stroke='gray' stroke-dasharray='5,5'/>\n";
// サイン波
$points = [];
$amplitude = $height / 2 * 0.8;
for ($x = 0; $x <= $width; $x++) {
$t = ($x / $width) * $periods * 2 * M_PI;
$y = $centerY - $amplitude * sin($t);
$points[] = "{$x},{$y}";
}
$pathData = "M " . implode(" L ", $points);
$svg .= "<path d='{$pathData}' fill='none' stroke='blue' stroke-width='2'/>\n";
$svg .= "</svg>";
return $svg;
}
/**
* 複数の波を重ねたSVGを生成
*/
public static function generateMultiWaveSVG($width = 800, $height = 400) {
$svg = "<svg width='{$width}' height='{$height}' xmlns='http://www.w3.org/2000/svg'>\n";
$svg .= "<rect width='{$width}' height='{$height}' fill='white' stroke='black'/>\n";
$centerY = $height / 2;
$colors = ['red', 'blue', 'green'];
$frequencies = [1, 2, 3];
foreach ($frequencies as $i => $freq) {
$points = [];
$amplitude = $height / 2 * 0.3;
for ($x = 0; $x <= $width; $x++) {
$t = ($x / $width) * 2 * M_PI;
$y = $centerY - $amplitude * sin($freq * $t);
$points[] = "{$x},{$y}";
}
$pathData = "M " . implode(" L ", $points);
$svg .= "<path d='{$pathData}' fill='none' stroke='{$colors[$i]}' stroke-width='2'/>\n";
}
$svg .= "</svg>";
return $svg;
}
}
// 使用例
echo "=== SVGグラフ生成 ===\n";
$svgSine = SVGGraphGenerator::generateSineWaveSVG();
file_put_contents('/tmp/sine_wave.svg', $svgSine);
echo "サイン波SVGを生成: /tmp/sine_wave.svg\n";
$svgMulti = SVGGraphGenerator::generateMultiWaveSVG();
file_put_contents('/tmp/multi_wave.svg', $svgMulti);
echo "複数波SVGを生成: /tmp/multi_wave.svg\n";
関連する三角関数
$angle = deg2rad(45);
// サイン
echo "sin(45°) = " . sin($angle) . "\n";
// コサイン
echo "cos(45°) = " . cos($angle) . "\n";
// タンジェント
echo "tan(45°) = " . tan($angle) . "\n";
// 逆三角関数
echo "asin(0.5) = " . rad2deg(asin(0.5)) . "°\n";
echo "acos(0.5) = " . rad2deg(acos(0.5)) . "°\n";
echo "atan(1) = " . rad2deg(atan(1)) . "°\n";
まとめ
sin()関数の特徴をまとめると:
できること:
- サイン(正弦)の計算
- 波形生成
- 円運動・振動の計算
- アニメーション
引数と戻り値:
- 引数: ラジアン単位の角度
- 戻り値: -1.0から1.0の範囲
推奨される使用場面:
- 数学計算
- 物理シミュレーション
- グラフィックス
- 波形処理
- アニメーション
- ゲーム開発
重要な定数:
M_PI: 円周率π(約3.14159)M_PI_2: π/2M_PI_4: π/4
単位変換:
// 度→ラジアン
$rad = deg2rad($deg);
// ラジアン→度
$deg = rad2deg($rad);
関連関数:
cos(): コサインtan(): タンジェントasin(): アークサインsinh(): 双曲線サインdeg2rad(): 度をラジアンに変換rad2deg(): ラジアンを度に変換
よく使うパターン:
// 単位円上の点
$x = cos($angle);
$y = sin($angle);
// サイン波
$value = $amplitude * sin($frequency * $time);
// イージング
$eased = sin(($t * M_PI) / 2);
sin()は、数学や物理計算の基本となる重要な関数です。グラフィックス、アニメーション、シミュレーションなど、様々な場面で活躍します!
