SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

データサイエンス基礎を高校数学から復習

グラフを描画して、三角関数のサイン・コサインの理解を深めよう

データサイエンス基礎を高校数学から復習しよう 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

sin関数を動的に描写する

 続いては、もう少し複雑なデータを動的に変更する方法を紹介します。

 具体的には、角度が動的に変わり図3の線が左へ移動し続けるようなsin関数のグラフを動的に描画してみます。これは、先ほどの回転している様子でX軸を時間(角度)に、Y軸をsinの値にしたグラフになります。

 つまり、等速回転運動を表した波形とも言えます。例えば、先ほどのスイングの例で言えば回転が等速にはならないため、それが波長として見えるようになるはずです。

 また、前回までと今回が異なるのは、X軸(度数)が1度ずつ増加するため、軸も同時に移動する点です。

図6:動的なsin関数のグラフ
図6:動的なsin関数のグラフ

 これを実装したのが、リスト3のコードです。

[リスト3]動的にデータが変化する波形のサンプル例(js/sample/DynamicController.js)
export default class DynamicController{

	drawGrid(ele){
		const rect = ele.getBoundingClientRect();
		const width = rect.width;
		const height = rect.height;
		const marginTop = 30;
		const marginRight = 30;
		const marginBottom = 30;
		const marginLeft = 30;

		const xDomain = [-180, 360];
		const yDomain = [-2, 2];

		// (1) X軸を作成(時間と共に動く前提)
		this.scaleX = d3.scaleLinear()
			.domain(xDomain)
			.range([marginLeft, width - marginRight]);

		// (2) Y軸を作成(固定)
		const scaleY = d3.scaleLinear()
			.domain(yDomain)
			.range([height - marginBottom, marginTop]);

		const contents = d3.select(ele);
		const svg = contents.append("svg")
			.attr("width", width)
			.attr("height", height);

		const x_zero = this.scaleX(0);
		const y_zero = scaleY(0);

		//  (3) X軸を配置する
		this.axisX = svg.append("g")
			.attr("transform", `translate(0,${y_zero})`)
			.call(d3.axisBottom(this.scaleX));

		//  (4) Y軸を配置する
		svg.append("g")
			.attr("transform", `translate(${x_zero},0)`)
			.call(d3.axisLeft(scaleY));

		//  (5) lineを描写するようの関数を作成する
		this.line = d3.line().x((d) => {
			return this.scaleX(d.x);
		}).y((d) => {
			return scaleY(d.y);
		});

		//  (6) sin関数の値を描写する為のpath要素を作成
		this.path = svg.append("path");
	}

	// (7) データを動的に更新する
	updateDataset(){
		let deg = 0;
		setInterval(() => {
			// (8)データを作成
			const dataset = [];
			for(let i = -180 + deg ; i <= 360 + deg; i++) {
				const r = Math.PI / 180 * (i + deg);
				dataset.push({
					x : i,
					y : Math.sin(r),
				});
			}
			//  (9) X軸の範囲を更新
			this.updateXDomain([-180 + deg , 360 + deg]);
			//  (10)sin関数のグラフを描写(更新)
			this.sinLine(dataset);

			deg++;
		},10);
	}

	sinLine(dataset){
		this.path
			.datum(dataset)
			.attr('fill','none')
			.attr('stroke',"red")
			.attr('d',this.line);
	}

	updateXDomain(xDomain){
		this.scaleX.domain(xDomain);
		this.axisX
			.transition()
			.duration(50)
			.call(d3.axisBottom(this.scaleX));
	}
}

 (1)でX軸を描画します。このX軸は後で更新するため、クラス内のメンバ変数として保持します。(2)のY軸は固定したままであるため、メンバ変数にはしていません。

 そして、(3)(4)でX軸とY軸をSVG上に描画しています。次に、(5)でsin関数のグラフを描画するための関数を作成し、その描画対象となるノードを(6)で作成します。

 (5)と(6)も再描画の際に利用するため、メンバ変数にしています。

 そして、(7)のsetIntervalで繰り返し処理を行い、その中で変化した角度ごとにデータを更新します(8)。また、その変化したデータに伴いX軸の範囲を変更し(9)、データに合わせて線を描画し直します(10)。

 (9)と(10)の処理自体はこれまで行ってきた内容と変わりませんが、データセット内の角度やsin値の変化に応じて、自動的に再描画されます。

 このようにSVG上の同じノードの内容を変更するだけの場合には、それぞれ描画する際に作成した関数をそのまま用いて、変化した内容で更新すれば動的な描画を行えます。

円運動と波運動との連動

 これまでのコードをもとに、円運動とsin波形の動きを同期させて表示させたものが、図7です(詳細はサンプルコード(sync.html)を参照してください)。

 また、サンプルコードを実行すると円運動の中心点(Y軸)と、円運動の速度を変更できるようにしました。できればこれまでのコードなどを参考にパラメータが変わった場合なども試してみてください。

図7:円運動とsin波形のイメージ
図7:円運動とsin波形のイメージ

 同じ現象も異なる方法で見ると、計測したデータ結果も変わります。特に三角関数が生かせる領域は幅広く、さまざまな視点でデータを見ることが重要になります。

 例えば、円運動の条件のわずかな変化が大きな結果の違いとして出てしまうケースがあります。実際のデータ分析でも、データだけを見ていると、より複雑な結果に注意を向けがちです。

 しかし、円運動側を見ると思ったよりも複雑な動きをしていないように、データをどのような視点から見ているのかにも注意が必要となります。

最後に

 今回は、基本的な三角関数について、視覚的な理解を通じて、三角関数が単なる数学の公式ではなく、現実世界に適用した際にも同じようにイメージできる手助けになれば幸いです。

 次回はsin、cosの波としての特徴について、より深く掘り下げます。高校時代にsinやcosの合成や分解について問われる問題を解いたことを思い出す方もいるかもしれません。そのような波の合成と分解の理解の手助けになる内容について紹介します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
データサイエンス基礎を高校数学から復習連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21944 2025/07/31 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング