自由研究ノート(仮)

とかいう名前の備忘録

WebGL使い試し

そういえばブログ文中に
3D描画するものを埋め込むことができるのかな..

と思ったので WebGLの勉強がてら 試しにやってみる

結果


いけるっぽい

ソース


<p id="my_canvas_anchor"></p>

<!-- 
頂点シェーダ 
-->
<script id="vShader" type="text/plain">// <![CDATA[
attribute vec2 position;
void main ()
{
    gl_Position = vec4(position, 1.0, 1.0);
}
// ]]></script>

<!-- 
ピクセルシェーダ 
-->
<script id="pShader" type="text/plain">// <![CDATA[
precision mediump float;
void main ()
{
    gl_FragColor = vec4 (1.0);
}
// ]]></script>

<!-- 
ここからスクリプト 
-->
<script type="text/javascript">// <![CDATA[
function Sample()
{
    const canvasSize = 280;
    
    // canvas の追加
    const anchor = document.getElementById("my_canvas_anchor");
    const canvas = document.createElement('canvas');
    canvas.id = "my_canvas"; 
    canvas.width = canvasSize;
    canvas.height = canvasSize;
    anchor.parentNode.insertBefore(canvas, anchor);

    const gl = canvas.getContext('webgl', null);
    if(gl == null)
    {
        anchor.innerHTML = "Error:WebGLの初期化に失敗しました";
        return;
    }
    gl.viewport(0, 0, canvasSize, canvasSize);    
    
    // シェーダ準備
    const vsElem = document.getElementById ('vShader');
    const vShader = gl.createShader( gl.VERTEX_SHADER );
    gl.shaderSource( vShader, vsElem.text );
    gl.compileShader( vShader );
    
    const psElem = document.getElementById ('pShader');
    const pShader = gl.createShader( gl.FRAGMENT_SHADER );
    gl.shaderSource( pShader, psElem.text );
    gl.compileShader( pShader );
    
    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vShader);
    gl.attachShader(shaderProgram, pShader);
    gl.linkProgram(shaderProgram);
    
    if (gl.getProgramParameter(shaderProgram, gl.LINK_STATUS) == false) 
    {
        anchor.innerHTML = "Error:シェーダの生成に失敗しました";
        return;
    }
    
    // ポリゴン準備
    const posnBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, posnBuffer);
    
    var position = [
      0,    0.5,
      -0.5, -0.5,
      0.5 , -0.5
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array (position), gl.STATIC_DRAW);
    
    // 描画
    gl.clearColor (0.8, 0.9, 1.0, 1.0);
    gl.clear (gl.COLOR_BUFFER_BIT);
    
    const vsPosAttribute = gl.getAttribLocation(shaderProgram, "position");
    gl.vertexAttribPointer(vsPosAttribute, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vsPosAttribute);

    gl.useProgram(shaderProgram);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
}
Sample();
// ]]></script>

参考にしたサイトさん


https://developer.mozilla.org/ja/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL

https://www.shibuya24.info/entry/2015/07/28/200310

http://webos-goodies.jp/archives/getting_started_with_webgl.html

平行線の同位角

平面上の平行線の同位角は等しい

f:id:DarkCrowCorvus:20200606153320p:plain

図の xy は同じ角度になる
いまさらながら それってホント? と思ったので証明の仕方を調べてみる 

 


平行線公準

この証明のために 平行線公準(ユークリッドの第5公準) を利用する

1つの線分が2つの直線に交わり、同じ側の内角の和が2直角より小さいならば、この2つの直線は限りなく延長されると、2直角より小さい角のある側において交わる。
平行線公準 - Wikipedia

2直線が1つの線に交わるところの
その1つの線から見て同じ側の内角の合計が

  • 2直角 ...90°\times2 = 180° ちょうどならば2直線は平行
  • 小さい場合はその側に線を延長した先で2直線が交わり
  • 大きい場合は反対側に線を延長した先で2直線が交わる

 f:id:DarkCrowCorvus:20200606211331g:plain

とのこと


公準 というのも「何ぞや」という状態だったため
そちらについても軽く調べてみる

その他の命題を導きだすための前提として導入される最も基本的な仮定のことである。

なお、ユークリッド原論などの古典的な数学観では、最も自明(絶対的)な前提を公理、それに準じて要請される前提を公準 (postulate) として区別していた。

 公理 - Wikipedia

証明無用で正しいとする、
これ以上さかのぼって証明することができない仮定のことを表す

昔は "公準" と "公理" を別の意味として分けて使用していたらしい
今だと区別せず、どちらも 公理 として扱って問題ないとのこと

これを使って証明をできれば間違いがなさそう


証明

図の2直線は平行線である。
f:id:DarkCrowCorvus:20200607021337p:plain

平行線の同位角を  x, y 
y の外角を  180°- y と表す

x  <  y  のとき
  x + 180°- y  は  180° よりも小さくなる。
 平行線公準によって 2直線は図の右側で交わる

x  >  y  のとき
  x + 180°- y  は   180° よりも大きくなる。
 平行線公準によって 2直線は図の左側で交わる

どちらも 2直線が平行線である前提に反するためなり得ない
よって x = y が成立する

 


参考にしたサイトさん

https://chukoikkan.com/column/ks191124

最大公約数と最小公倍数を求める ~3/3 ユークリッドの互除法を利用する~

2018/08/07 微編集
最大公約数と最小公倍数を求める ~1/3 割れるだけ割ってみる~
最大公約数と最小公倍数を求める ~2/3 素因数分解を利用する~
最大公約数と最小公倍数を求める ~3/3 ユークリッドの互除法を利用する~ ←この記事

 
最後に ユークリッドの互除法 という手法を利用して、
最大公約数と、最小公倍数を求める方法について勉強してみる

 


ユークリッドの互除法を利用する

2つの数のうち、大きい方を A、小さい方を B と表すことにする。

1. AB で割ってあまり r を求める。
ここで r=0 であれば  B が2つの数A,B の最大公約数になる。

2. r \gt 0 ならば、AB の数を 、Br の数を入れて、再度割り算を行う。

あまりが 0 になるまで、この「2.」の手順を繰り返し、あまりが 0 になったとき、その割り算に使った"割った数" の方が、2つの数 A,B の 最大公約数 になる。

f:id:DarkCrowCorvus:20171206010823j:plain

これによる最大公約数の求め方をユークリッドの互除法と呼ぶ。

また、求まった最大公約数で A,B のどちらか一方を割って、その結果を割っていない方に掛けた結果が、2つの数 A,B最小公倍数 になる。

f:id:DarkCrowCorvus:20171206013321j:plain


関連する事実 

本題の前に ある事実を紹介

■ 事実..

A{\div}B のあまりを r とするとき、
AB の最大公約数は Br の最大公約数でもある。

f:id:DarkCrowCorvus:20180805200510p:plain

■ 証明..

AB で割って求まる商を q
あまりを r とする時、この関係を以下の式で表す

{\hspace{6pt}}r=A-Bq\ {\cdots}

AB の公約数を d とするとき
① の A と B から d を引っ張り出して式を整理する

{\hspace{6pt}}r=A'd-B'dq
{\hspace{12pt}}=(A'-B'q)d

右辺は d の倍数。
よって、左辺 rd の倍数。
つまり、dr の約数である

dB の約数なので、
dBr の公約数になる

f:id:DarkCrowCorvus:20180805210427p:plain

次に ① を 「 A を左辺とする式」に書き換えてみる

{\hspace{6pt}}A=Bq+r\ {\cdots}

Br の公約数を d' とするとき、
② の Br から d' を引っ張り出して式を整理する

{\hspace{6pt}}A=(B'q+r')d'

右辺は d' の倍数。
よって、左辺 Ad' の倍数。
つまり、d'A の約数である

d'B の約数なので、
d'AB の公約数になる

以上のことから、
AB の公約数 d は、Br の公約数であり (d\ {\subseteqq}\ d')
Br の公約数 d' は、AB の公約数である (d\ {\supseteqq}\ d')

よって双方の公約数は、もれなく一致する。
"どちらか片方にだけある" という公約数は存在しない...その結果、AB の最大公約数は、ちょうど Br の最大公約数と一致する。

自分なりに解釈 (最大公約数)

AB で割ってあまりが出る場合、AB の数を、B にあまり r の数を入れて、割り算を繰り返す。

「あまりの数で割り、そのあまりの数で割り…」の繰り返しになるため、あまり r はその度にだんだんと小さくなり、いずれ r=0 に行き着く

f:id:DarkCrowCorvus:20171212015213j:plain

r=0 になったとき、つまりは繰り返しの中で A_iB_i で割り切れるタイミングが来たとき、その B_i の数が、 A_iB_i にとっての最大公約数になる

B_i の最大の約数は B_i 自身である。 A_iB_i で割り切れるなら、B_iA_iB_i の最大公約数になる

また、前述の事実に従って、繰り返しの中の AB の最大公約数、並びに Br の最大公約数は、どれも常に一致し、ずっと変わらない。

f:id:DarkCrowCorvus:20180731062839g:plain

よって、A_iB_i の最大公約数は、そのまま 初めの AB の最大公約数になる

自分なりに解釈 (最小公倍数)

上で求まった最大公約数を使って 2つの数のどちらか一方を割り、得られた商を "割っていない方" に掛けた結果が、2つの数の最小公倍数になる。

2つの数を A,B、最大公約数を G
そのGによって割られた 2つの数を a,b
とするとき、最小公倍数 L を求めるこの計算は

{\hspace{6pt}}L=aB{\hspace{8pt}}もしくは {\hspace{8pt}}L=Ab

{\hspace{6pt}}{\therefore}{\hspace{6pt}}L=aGb{\hspace{8pt}} である。

これより先は 「割れるだけ割ってみる」 の記事で説明したとおり。


3つ以上の数の最大公約数と最小公倍数

3つ以上の数の中で一番小さな数を使って、その他の数を割り、そのあまりの数で元の数を置きかえる。

新しくできたグループの中でまた一番小さな数 (0を除く) を探し、その数で他の数を割ってあまりの数で元の数を置きかえる...

これを繰り返し、最終的に「他の数」すべてのあまりの数が 0 になったとき、その割り算に使った"一番小さな数" が 3つ以上の数にとっての最大公約数 になる

f:id:DarkCrowCorvus:20180807020158g:plain


もしくは、3つ以上の数の中のどれか 2つの数から 前述のユークリッドの互除法によって 2つの数の最大公約数を求め、

その数と、また別の残っている数を使って ユークリッドの互除法によって3つの数の最大公約数を求め… を繰り返すことによっても 、3つ以上の数の最大公約数を求めることができる。

f:id:DarkCrowCorvus:20180805183330g:plain


3つ以上の数の最小公倍数
を求めるために、ユークリッドの互除法を使うサンプルは、今回見つけることができなかった。

最小公倍数を求める対象が3つ以上になる場合は、「割れるだけ割ってみる」または「素因数分解を利用する」の記事で紹介した方法を使って解くのがよろしそう。 

 


 最大公約数と最小公倍数の求め方を、
自分の納得がいくまで調べてみたつもり。

ユークリッドの互除法は、この用途とは別に
1次不定方程式の解を求めるためにも利用できるらしい。

その辺の理屈を調べてみるのは、また今度気が向いた時にでも (やらない)


参考にした書籍/サイトさん

書籍
なっとくする群・環・体 (Amazon)

 
最小公倍数/最大公約数
最大公約数と最小公倍数