メモ > 技術 > プログラミング言語: JavaScript > 数学
数学
■関数
1つの入力に対して1つの出力を返すもの。値の変換装置
■三角関数
ある直角三角形について、長さと角度の関係を表すことができる
sin cos tan の値は、角度(θ)が定まると一つの値に定まる。つまり、一辺と角度が分かればそれにより他の一辺の長さを求められる
角度に応じたsin cos tanの値がまとめられたものを、三角関数表という
「三角関数」って、何でしたっけ?−sin(サイン)、cos(コサイン)、tan(タンジェント)− |ニッセイ基礎研究所
https://www.nli-research.co.jp/report/detail/id=65396?site=nli
一例として測量に使用され、建築物の高さは
「ある地点から建築物までの距離と、その地点から建築物の頂点への角度」
によって高さを求めることができる
三角比を利用した測量 | 数学に駆ける
https://ss1.xrea.com/mmath.s205.xrea.com/C/C3-2.html
サイン、コサイン、タンジェントの意味と名前の由来は以下のとおり
sin(正弦) ... 正角に対する弦の長さ
sin(サイン)は英語のsinusoid(正弦曲線)から来ている
cos(余弦) ... 余角に対する弦の長さ
cos(コサイン)は「co-sine」で、「sin」に、補足的・補完的(complementary)の意味を有する接頭辞「co」を付したもの
tan(正接) ... 正確に対する接線の長さ
tan(タンジェント)は英語のtangent(接線)から来ている
三角比の正弦余弦正接ってどういう意味?【sin・cos・tanに結びつく覚え方のコツ】 | 遊ぶ数学
https://integraldx.info/sine-cosine-tangent-143
数学記号の由来について(7)−三角関数(sin、cos、tan等)− |ニッセイ基礎研究所
https://www.nli-research.co.jp/report/detail/id=65715?site=nli
■正弦定理と余弦定理
三角形の内角と、その向かい合う辺の関係を表すもの
三角関数は直角三角形に対して適用されるが、正弦定理は直角三角形以外にも適用できる
(ただし三角比も正弦定理も、角度が90度未満の三角形にしか使えない)
正弦定理 ... 三角形の正弦(sinθ)の比は3辺の長さの比に等しいというもの
つまり、△ABCにおいて、「sinA:sinB:sinC = a:b:c」が成り立つ
余弦定理 ... 三角形の2辺と1角が分かっている場合、残りの辺の長さを求めることができる公式
また、3辺が分かっている場合、余弦(cos)を求めることも
正弦定理と余弦定理の公式・証明・例題を数学講師がわかりやすく解説 | お知らせ | 好文館|福岡と熊本の個別指導塾(英語・数学)
https://www.koubunkan-n.jp/news/seigen-yogen/
■単位円
単位円を使えば、X座標をcos、Y座標をsinと表すことができる
この方法は、角度が90度以上の角度でも作用できる
またsin cosにより、波をあらわすことができる
詳細は以下引き続きの内容にて
■角度とラジアン
日常的に角度を表現する場合、「〇度」というように度数を使って表現する
これは「度数法」と呼ばれるもので、角度の状態をイメージしやすく、直観的で分かりやすい
プログラミングの際には、角度を度数法ではなく「弧度法」を用いることが多い
コンピュータで計算を行う上では、計算量を節約できるなどのメリットがある
弧度法では「ラジアン」と呼ばれる尺度で角度を表現する
ラジアンは「円周の長さを基準とした角度の表現」で、「半径が1の円の外周の、その長さを用いて表現されるもの」と言える
度数法の180度は、弧度法では円周率(約3.14)となる
度数法の360度は、弧度法では円周率の2倍(約6.28)となる
つまり、「1ラジアン = 円の半径 = r」となる(円周は「2πr」で表される)
// 角度(30度)
let degrees = 30;
// 角度からラジアンを取得
let radian = degToRad(degrees);
// 結果を出力
console.log(radian); // 0.5235987755982988
// 度数からラジアンへの変換
function degToRad(degrees) {
return degrees * Math.PI / 180;
//return (degrees / 360) * (Math.PI * 2); // 整理前
}
sinとcosを使用すると、
「半径1の円を基準とした、角度に応じた座標」を求めることができる
具体的には、その座標は (x, y) = (cosθ, sinθ)となる
// 角度(30度)
let degrees = 30;
// 角度からラジアンを取得
let radian = degToRad(degrees);
// サインとコサインを求める
let sin = Math.sin(radian);
let cos = Math.cos(radian);
// 結果を出力
console.log(sin); // 0.49999999999999994
console.log(cos); // 0.8660254037844387
// 度数からラジアンへの変換
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
これを利用することで、「任意の角度の方向への移動後の座標」を求めることができる
// 任意の座標A(ここでは仮に原点とする)
let A = [0.0, 0.0];
// 任意の角度(ここでは仮に30度とする)
let degrees = 30;
// 任意の移動量(ここでは仮に1とする)
let speed = 1;
// 角度からラジアンを取得
let radian = degToRad(degrees);
// サインとコサインを求める
let sin = Math.sin(radian);
let cos = Math.cos(radian);
// 移動量
let B = [
A[0] + cos * speed,
A[1] + sin * speed
];
// 結果を出力
console.log(A); // [0, 0]
console.log(B); // [0.8660254037844387, 0.49999999999999994]
// 度数からラジアンへの変換
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
■ベクトル
量を表すことができる概念を「スカラー」や「実数」と呼ぶ
量という概念の他に「向き」の概念が新たに加わったものを「ベクトル」と呼ぶ
例えば2次元の平面にAとBという2つの点がある場合、AとBの距離は単体の値(スカラー)で表すことができる
このとき、AからBに向かう方角(向き)を表現しようとすると単体の数値で表すことはできず、
横方向と縦方向の移動量を組み合わせて (x, y)のように複数の値をひとまとめにして表現する。これがベクトル
ベクトルは「終点 - 始点」という計算を行うことによって求めることができる
// 視点
let A = [-2, 2];
// 終点
let B = [3, -1];
// 任意の角度(ここでは仮に30度とする)
let degrees = 30;
// 2点間を結ぶベクトル
let V = [
B[0] - A[0], // X軸の終点から始点を引く
B[1] - A[1] // Y軸の終点から始点を引く
];
// 結果を出力
console.log(V); // [5, -3]
■単位ベクトル
ベクトルの大きさを「1」に揃えることで、純粋にベクトルの向きだけを考えられるようになる
この作業を「単位化」といい、大きさが1になったベクトルのことを「単位ベクトル」と呼ぶ
単位化されたベクトルの各要素は、その値が -1〜1 の範囲に必ず収まる
また単位ベクトルは、その先端(終点)が必ず「半径1の円」の外周に重なる
// ベクトル
let V = [5, -3];
// ベクトルの大きさを求める
let L = Math.sqrt(V[0] * V[0] + V[1] * V[1]);
// ベクトルの単位化
V[0] /= L;
V[1] /= L;
// 結果を出力
console.log(L); // 5.830951894845301
console.log(V); // [0.8574929257125441, -0.5144957554275265]
この「半径1の円」は「角度とラジアン」でも登場したが、
同じ角度を元にしたサインやコサインで得られる値をベクトルとして表現すると、それは常に単位ベクトルとなる
三角関数の逆関数として、サインの値からラジアンを求めるアークサイン(arcsin / 逆正弦)や、コサインの値からラジアンを求めるアークコサイン(arccos / 逆余弦)がある
任意のベクトルVが定義できるとき、それを単位化してから要素をアークサインやアークコサインに与えると、ベクトルが成す角度が得られる
// サインとコサインの値
let sin = 0.49999999999999994;
let cos = 0.8660254037844387;
// アークサインとアークコサインでラジアンを求める
let radianA = Math.asin(sin);
let radianB = Math.acos(cos);
// ラジアンから角度を取得
let A = radToDeg(radianA);
let B = radToDeg(radianB);
// 結果を出力
console.log(radianA); // 0.5235987755982988
console.log(radianB); // 0.5235987755982987
console.log(A); // 29.999999999999996
console.log(B); // 29.999999999999993
// ラジアンから度数への変換
function radToDeg(radian) {
return 180 / Math.PI * radian;
}
■ベクトルの加算と減算
ベクトルは、スカラーと同じように加算と減算が行える
ベクトル同士の加算や減算は、単にベクトルを構成するXやYなどの要素ごとに、それぞれ加算と減算を行う
// ベクトル
let V = [5, -3];
let W = [-2, 6];
// ベクトルの加算(V + W)
let A = [
V[0] + W[0],
V[1] + W[1]
];
// 結果を出力
console.log(A); // [3, 3]
// ベクトルの加算(V - W)
let B = [
V[0] - W[0],
V[1] - W[1]
];
// 結果を出力
console.log(B); // [7, -9]
■ベクトルのスカラー倍
ベクトルには、掛け算や割り算の計算方法は無い
しかし「スカラー倍」と呼ばれる、ベクトルをスケール(拡大縮小)する方法がある
これは単に、ベクトルを構成する各要素に対して、何らかの値(スカラー)を掛けることで実現する
// ベクトル
let V = [5, -3];
// スケールするためのスカラーの定義
let scalar = 2.0
// ベクトルVをスカラー倍する
let W = [
V[0] * scalar,
V[1] * scalar
];
// 結果を出力
console.log(W); // [10, -6]
■ベクトルの内積
ベクトルの内積とは、「ベクトル同士の成す角」のこと
結果は必ずスカラーになる
また、単位化したベクトル同士の内積はcosθに等しくなる
(処理内にあるアークサインについては、前述の「単位ベクトル」を参照)
// 2つのベクトルを定義
let V = [5, 1];
let W = [-2, 3];
// それぞれベクトルを単位化する
V = normalize(V);
W = normalize(W);
console.log(V); // [0.9805806756909202, 0.19611613513818404]
console.log(W); // [-0.5547001962252291, 0.8320502943378437]
// 単位化したベクトル同士で内積を求める
let dotValue = dot(V, W);
console.log(dotValue); // -0.3807498052542949
// 単位ベクトルの内積の結果はcosθなので、アークコサインでラジアンを得られる
let rad = Math.acos(dotValue);
console.log(rad); // 1.9614033704925835
// ラジアンから度数への変換
let deg = radToDeg(rad);
// 結果を出力
console.log(deg); // 112.38013505195958
// ベクトルを単位化
function normalize(v) {
let len = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
return [v[0] / len, v[1] / len];
}
// ベクトルの内積を求める
function dot(v0, v1) {
return (v0[0] * v1[0]) + (v0[1] * v1[1]);
}
// ラジアンから度数への変換
function radToDeg(radian) {
return 180 / Math.PI * radian;
}
※2次元ベクトルでも3次元ベクトルでも、同じように考えることができる
■ベクトルの外積
単位化したベクトル同士の外積はsinθに等しくなる
(内積は高校数学範囲だが、外積は高校数学範囲外らしい)
// 2つのベクトルを定義
let V = [5, 1];
let W = [-2, 3];
// それぞれベクトルを単位化する
V = normalize(V);
W = normalize(W);
console.log(V); // [0.9805806756909202, 0.19611613513818404]
console.log(W); // [-0.5547001962252291, 0.8320502943378437]
// 単位化したベクトル同士で外積を求める
let crossValue = cross(V, W);
console.log(crossValue); // 0.7071067811865476
// 単位ベクトルの外積の結果はsinθなので、アークサインでラジアンを得られる
let rad = Math.asin(crossValue);
console.log(rad); // 0.7853981633974484
// ラジアンから度数への変換
let deg = radToDeg(rad);
// 結果を出力
console.log(deg); // 45.00000000000001
// ベクトルを単位化
function normalize(v) {
let len = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
return [v[0] / len, v[1] / len];
}
// ベクトル(2次元)の外積を求める
function cross(v0, v1) {
return (v0[0] * v1[1]) + (v0[1] * v1[0]);
}
// ラジアンから度数への変換
function radToDeg(radian) {
return 180 / Math.PI * radian;
}
※外積は2次元ベクトル同士では結果がスカラーに、3次元ベクトルでは結果が3次元ベクトルになる
3次元ベクトルで得られる結果は「2つのベクトルに直行するベクトル」になる
3Dプログラミングでは、「ある平面からまっすぐ上に伸びるベクトルを求め、そのベクトルの向きに応じて明るさを計算する」などの用途で使用される
※上の例で使用しているcross関数は、2次元用に計算内容を調整している
■ベクトルの内積と外積
外積とは何か。ベクトルの外積の定義・意味・大きさについて|アタリマエ!
https://atarimae.biz/archives/23716
ベクトルの内積と外積の意味と嬉しさ | 高校数学の美しい物語
https://manabitimes.jp/math/678
アークサイン(arcsin, sin-1)の基本と微分積分 | 数学のトムラボ
https://rikeinvest.com/math/arcsin-2/
【ベクトル編】内積と外積を画像付きで徹底解説! | 大学1年生もバッチリ分かる線形代数入門
https://oguemon.com/study/linear-algebra/inner-and-cross-product/
内積と外積のイメージ | 物理学を学ぶ
https://butsuriblog.com/%E5%86%85%E7%A9%8D%E3%81%A8%E5%A4%96%E7%A9%8D/
以下、勉強中
必要になった時に改めて勉強することにしたい
・コサイン(内積)は「左右の方向、もしくは垂直」を判定するのに使うことができる
・サイン(外積)は「上下の方向、もしくは水平」を判定するのに使うことができる
・サイン単体あるいはコサイン単体では、それぞれ「縦横どちらかの向き」しか判定できない
まとめると、以下のようになる
・単位ベクトル同士の内積は、コサインに相当する
・単位ベクトル同士の外積は、サインに相当する
・内積の結果が0のとき、ベクトル同士は垂直である
・内積の結果が正の値であるとき、両者の成す角は鋭角である
・内積の結果が負の値であるとき、両者の成す角は鈍角である
・外積の結果が0のとき、ベクトル同士は並行である
・外積の結果が正の値であるとき、ベクトルAから見て上(左側)にベクトルBがある
・外積の結果が負の値であるとき、ベクトルAから見て下(右側)にベクトルBがある
■行列
行列は、ベクトルを変形したり変換したりする際に、よく用いられる
回転行列を用いたベクトルの回転など、
必要になった時に改めて勉強することにしたい