2025.03.21

回転行列

回転行列

回転行列とは

xy平面上の座標(x,y)を、原点のまわりに角度θだけ回転させる行列です。この回転を図にすると以下のようになります。

角度θがプラスの場合は反時計回り、マイナスの場合は時計回りになります。

原点まわりの座標の回転(反時計回り)

座標(x,y)を原点まわりに角度θだけ回転する式を回転行列を使って書くと以下のようになります。(x',y')は、回転後の座標です。

回転行列を使った計算式

赤の四角で囲んだ部分が回転行列です。

回転行列

回転行列を使わないで書くと以下のようになります。

反時計回りの回転計算

上の式に、回転する座標xとy、回転する角度θを入れると、原点座標(0,0)を中心に回転した座標(x',y')が求められます。

Javaソースコード

x座標y座標、度単位の回転角度をキーボードから入力して、計算した回転後の座標コンソール出力するJavaソースコードです。

RotationMatrix1.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
import java.util.Scanner;

public class RotationMatrix1 {
	public static void main( String[] args ) {
		// Scannerを作成
		Scanner scan = new Scanner( System.in );

		// x座標の入力
		System.out.println( "x座標を入力してください" );
		double x = scan.nextDouble();

		// y座標の入力
		System.out.println( "y座標を入力してください" );
		double y = scan.nextDouble();

		// 回転角度の入力
		System.out.println( "回転角度を度単位で入力してください" );
		double deg = scan.nextDouble();

		// 度をラジアンに変換
		double rad = Math.toRadians( deg );

		// 回転後の座標(rx,ry)を計算
		double rx = x * Math.cos( rad ) - y * Math.sin( rad );
		double ry = x * Math.sin( rad ) + y * Math.cos( rad );

		// 結果をコンソール出力
		System.out.println( "入力した座標 : ( " + x + ", " + y + " )");
		System.out.println( "入力した角度 : " + deg + "度" );
		System.out.println( "回転後の座標 : ( " + rx + ", " + ry + " )");
	}
}

コンパイル ソースコードが「ANSI」の場合

C:\talavax\javasample>javac -encoding sjis RotationMatrix1.java

コンパイル ソースコードが「UTF-8」の場合

C:\talavax\javasample>javac RotationMatrix1.java

実行

C:\talavax\javasample>java RotationMatrix1

実行例1 座標(1.0)を90°回転

x座標を入力してください
1
y座標を入力してください
0
回転角度を度単位で入力してください
90
入力した座標 : ( 1.0, 0.0 )
入力した角度 : 90.0度
回転後の座標 : ( 6.123233995736766E-17, 1.0 )

回転後のx座標「6.123233995736766E-17」が指数表記ですが0.0に近い値です。「E-17」は10-17を表しています。

計算誤差があるので「0.0」になりませんが、回転後の理論上の座標(0.0,1.0)に近い結果になっています。

実行例2 座標(1.0)を30°回転

x座標を入力してください
1
y座標を入力してください
0
回転角度を度単位で入力してください
30
入力した座標 : ( 1.0, 0.0 )
入力した角度 : 30.0度
回転後の座標 : ( 0.8660254037844387, 0.49999999999999994 )

回転後のy座標の理論値は「0.5」です。sin30°の値です。

計算誤差があるので、回転後のy座標「0.49999999999999994」となりましたが、「0.5」に近い値です。

Javaソースコードの解説

ここから、ソースコードを解説していきます。

001
import java.util.Scanner;

Javaクラスライブラリの中から「java.util.Scanner」というパッケージにあるクラスを使うために記述しています。

003
public class RotationMatrix1 {

クラス名を、RotationMatrix1としています。

004
	public static void main( String[] args ) {

このmainメソッドからプログラムを実行します。

005
006
		// Scannerを作成
		Scanner scan = new Scanner( System.in );

標準入力System.inを使って、Scannerクラスのscanを初期化しています。

008
009
010
		// x座標の入力
		System.out.println( "x座標を入力してください" );
		double x = scan.nextDouble();

nextDoubleメソッドで、キーボードから入力された1行を読み取り、x座標を格納するdouble型変数xに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数xに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

012
013
014
		// y座標の入力
		System.out.println( "y座標を入力してください" );
		double y = scan.nextDouble();

nextDoubleメソッドで、キーボードから入力された1行を読み取り、y座標を格納するdouble型変数yに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数yに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

016
017
018
		// 回転角度の入力
		System.out.println( "回転角度を度単位で入力してください" );
		double deg = scan.nextDouble();

nextDoubleメソッドで、キーボードから入力された1行を読み取り、度単位の角度を格納するdouble型変数degに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数degに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

020
021
		// 度をラジアンに変換
		double rad = Math.toRadians( deg );

度単位の角度degを、Math.toRadiansメソッドを使ってラジアンに変換し、double型変数radに代入しています。

Math.toRadiansメソッド

public static double Math.toRadians( double a )
・引数aで指定した角度をラジアンに変換した値を返します。

  パラメータ a : 角度(単位:度)[

  戻り値    ラジアン
023
024
025
		// 回転後の座標(rx,ry)を計算
		double rx = x * Math.cos( rad ) - y * Math.sin( rad );
		double ry = x * Math.sin( rad ) + y * Math.cos( rad );

座標(x,y)と角度radを使って、回転後の座標(rx,ry)を計算しています。

027
028
029
030
		// 結果をコンソール出力
		System.out.println( "入力した座標 : ( " + x + ", " + y + " )");
		System.out.println( "入力した角度 : " + deg + "度" );
		System.out.println( "回転後の座標 : ( " + rx + ", " + ry + " )");

結果をコンソール出力しています。

Javaソースコード - 回転のメソッド化

x座標y座標、度単位の回転角度をキーボードから入力して、計算した回転後の座標コンソール出力するJavaソースコードです。

回転後の座標計算はメソッドを作成して求めています。

RotationMatrix2.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
import java.util.Scanner;

public class RotationMatrix2 {
	// (x,y)をdegだけ回転したx座標を戻す
	private static double rotation_x( double x, double y, double deg  )
	{
		// 度をラジアンに変換
		double rad = Math.toRadians( deg );

		// 回転後のx座標を計算
		return x * Math.cos( rad ) - y * Math.sin( rad );
	}


	// (x,y)をdegだけ回転したy座標を戻す
	private static double rotation_y( double x, double y, double deg  )
	{
		// 度をラジアンに変換
		double rad = Math.toRadians( deg );

		// 回転後のy座標を計算
		return  x * Math.sin( rad ) + y * Math.cos( rad );
	}


	// メインメソッド
	public static void main( String[] args ) {
		// Scannerを作成
		Scanner scan = new Scanner( System.in );

		// x座標の入力
		System.out.println( "x座標を入力してください" );
		double x = scan.nextDouble();

		// y座標の入力
		System.out.println( "y座標を入力してください" );
		double y = scan.nextDouble();

		// 回転角度の入力
		System.out.println( "回転角度を度単位で入力してください" );
		double deg = scan.nextDouble();

		// 回転後の座標(rx,ry)を計算
		double rx = rotation_x( x, y, deg );
		double ry = rotation_y( x, y, deg );

		// 結果をコンソール出力
		System.out.println( "入力した座標 : ( " + x + ", " + y + " )");
		System.out.println( "入力した角度 : " + deg + "度" );
		System.out.println( "回転後の座標 : ( " + rx + ", " + ry + " )");
	}
}

コンパイル ソースコードが「ANSI」の場合

C:\talavax\javasample>javac -encoding sjis RotationMatrix2.java

コンパイル ソースコードが「UTF-8」の場合

C:\talavax\javasample>javac RotationMatrix2.java

実行

C:\talavax\javasample>java RotationMatrix2

Javaソースコード - 回転のメソッド化の解説

ここから、ソースコードを解説していきます。

001
import java.util.Scanner;

Javaクラスライブラリの中から「java.util.Scanner」というパッケージにあるクラスを使うために記述しています。

003
public class RotationMatrix2 {

クラス名を、RotationMatrix2としています。

004
005
006
007
008
009
010
011
012
	// (x,y)をdegだけ回転したx座標を戻す
	private static double rotation_x( double x, double y, double deg  )
	{
		// 度をラジアンに変換
		double rad = Math.toRadians( deg );

		// 回転後のx座標を計算
		return x * Math.cos( rad ) - y * Math.sin( rad );
	}

引数に、回転元の座標(x,y)と度単位の回転角度degを渡して回転後のx座標を計算するメソッドです。

015
016
017
018
019
020
021
022
023
	// (x,y)をdegだけ回転したy座標を戻す
	private static double rotation_y( double x, double y, double deg  )
	{
		// 度をラジアンに変換
		double rad = Math.toRadians( deg );

		// 回転後のy座標を計算
		return  x * Math.sin( rad ) + y * Math.cos( rad );
	}

引数に、回転元の座標(x,y)と度単位の回転角度degを渡して回転後のy座標を計算するメソッドです。

026
027
	// メインメソッド
	public static void main( String[] args ) {

このmainメソッドからプログラムを実行します。

028
029
		// Scannerを作成
		Scanner scan = new Scanner( System.in );

標準入力System.inを使って、Scannerクラスのscanを初期化しています。

031
032
033
		// x座標の入力
		System.out.println( "x座標を入力してください" );
		double x = scan.nextDouble();

nextDoubleメソッドで、キーボードから入力された1行を読み取り、x座標を格納するdouble型変数xに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数xに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

035
036
037
		// y座標の入力
		System.out.println( "y座標を入力してください" );
		double y = scan.nextDouble();

nextDoubleメソッドで、キーボードから入力された1行を読み取り、y座標を格納するdouble型変数yに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数yに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

039
040
041
		// 回転角度の入力
		System.out.println( "回転角度を度単位で入力してください" );
		double deg = scan.nextDouble();

nextDoubleメソッドで、キーボードから入力された1行を読み取り、度単位の角度を格納するdouble型変数degに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数degに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

043
044
045
		// 回転後の座標(rx,ry)を計算
		double rx = rotation_x( x, y, deg );
		double ry = rotation_y( x, y, deg );

rotation_xメソッド、rotation_yメソッド座標(x,y)と角度radを渡して、回転後の座標(rx,ry)を計算しています。

047
048
049
050
		// 結果をコンソール出力
		System.out.println( "入力した座標 : ( " + x + ", " + y + " )");
		System.out.println( "入力した角度 : " + deg + "度" );
		System.out.println( "回転後の座標 : ( " + rx + ", " + ry + " )");

結果をコンソール出力しています。

回転に関するコンテンツ

「回転」に関係があるコンテンツをまとめています。

関連コンテンツ

変数やクラスに格納されている値をコンソール出力する方法は?

2020.03.23

プログラムの最初に実行されるメソッドは?

2022.12.13

プログラミングで使う変数って何?

2020.03.23

Javaのプログラムを書いてみませんか?プログラムの書き方をくわしく説明しています。

2020.03.23

「Javaソースコード」から実行可能な「オブジェクトコード」に変換する方法をくわしく説明しています。

2020.03.23

メソッドを抜けるときに使用するreturn文について説明しています。

2020.03.20

Javaのプログラムを作ってみませんか?プログラミングに必要なものの用意から実行までを説明しています。

2020.03.23

Javaの学習に役立つソースコードを多数紹介しています。是非、ご覧ください。

2022.09.10

Swingパッケージを使ってグラフィック表示を行う方法を解説しています。

2020.03.23

画像フォーマット形式・色・大きさ・傾きなどの変更、特定の図形(文字・記号など)を見つけたり、取り出したりする画像処理について詳しく解説。

2015.11.29

繰り返し処理を使ったJavaのソースコードサンプルを紹介しています。

2020.03.23

配列を使うJavaソースコードを多数紹介しています。

2021.05.18

数学に関係するJavaのメソッドやソースコードなどを紹介しています。

2022.10.25

三角形、台形、円などいろいろな図形の面積を計算するプログラムを紹介しています。詳しくは、記事をご覧ください。

2021.05.18

StringクラスとStringBuilderクラスを利用したプログラミングの仕方を紹介しています。

2016.12.16

Javaを使った簡単な応用プログラム(生年月日から年齢を計算プログラムなど)を紹介しています。

2022.07.07

プログラミング、ITに関する用語をまとめています。

2022.10.17

日本で使われてきた伝統文様「和柄」について解説しています。

2022.07.27

平面上の位置を表す座標系の1つXY座標系について詳しく解説。

2020.03.23

国際単位系における角度の単位のラジアンについて説明しています。興味のある方は、記事をご覧ください。

2016.01.26

プログラミング言語とは?種類や特徴について説明しています。

2022.08.03

指数表記は、非常に大きな数値や、0に近い小さい数値を表現するときに使われる表記方法の1つです。興味のある方は、記事をご覧ください。

2020.03.23

double型のもつ誤差について解説しています。

2016.02.15

sin(サイン)の意味と、Math.sinメソッドの使い方をソースコードを使って詳しく解説しています。

2020.03.23

Javaプログラムの構成について解説しています。詳しくは、こちらをご覧ください。

2020.03.23

キーボードを使って実数値(double)を入力する方法を解説しています。Scannerクラスを利用しています。

2023.03.09

メソッドの定義方法を詳しく解説しています。Javaのサンプルソースコードを使った説明もあります。

2020.03.23

「ゆるゆるプログラム」のコンテンツを紹介しています。興味のある方はこの記事をご覧ください。

2020.03.23

広告