using System;
using XELF.Framework;

partial class MathSample3 {
	static void Main(string[] args) {
		Dot();
		Length();
		Conjugate();
		Inverse();
		Multiply();
		AxisAngle();
		Slerp();
		ToMatrix();
		ExpLog();
	}
}

partial class MathSample3 {
	static void Dot() {
		var axis1 = new Vector3(1, 1, 0);
		axis1.Normalize();
		var angle1 = MathHelper.Pi / 3;
		var a = Quaternion.CreateFromAxisAngle(axis1, angle1);
		var axis2 = new Vector3(0, -1, 2);
		axis2.Normalize();
		var angle2 = MathHelper.Pi;
		var b = Quaternion.CreateFromAxisAngle(axis1, angle2);
		var angle3 = Math.Acos(Quaternion.Dot(a, b));
        Console.WriteLine("-- 4.4.2項 160ページ");
        Console.WriteLine("内積");
		Console.WriteLine("a = {0}", a);
		Console.WriteLine("b = {0}", b);
		Console.WriteLine("aとbとのなす角度 = {0}°", angle3 / Math.PI * 180);
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void Length() {
		var a = new Quaternion(1, 2, -3, -4);
        Console.WriteLine("-- 4.4.3項 161ページ");
        Console.WriteLine("大きさ");
		Console.WriteLine("クォータニオン = {0}, その大きさ = {1}", a, a.Length());
		a.Normalize();
		Console.WriteLine("正規化したクォータニオン = {0}, その大きさ = {1}", a, a.Length());
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void Conjugate() {
		var a = new Quaternion(1, 2, -3, -4);
		Quaternion b;
		Quaternion.Conjugate(ref a, out b);
        Console.WriteLine("-- 4.4.4項 163ページ");
        Console.WriteLine("共役クォータニオン");
		Console.WriteLine("クォータニオン = {0}", a);
		Console.WriteLine("共役クォータニオン = {0}", b);
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void Inverse() {
		var a = new Quaternion(1, 2, -3, -4);
		Quaternion b;
		Quaternion.Inverse(ref a, out b);
        Console.WriteLine("-- 4.4.5項 164ページ");
        Console.WriteLine("逆クォータニオン");
		Console.WriteLine("元のクォータニオン = {0}, その逆クォータニオン = {1}", a, b);
		a.Normalize();
		Quaternion.Inverse(ref a, out b);
		Console.WriteLine("正規化したクォータニオン = {0}, その逆クォータニオン = {1}", a, b);
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void Multiply() {
		var a = new Quaternion(1, 2, -3, -4);
		var b = new Quaternion(2, -1, 5, 3);
		a.Normalize();
		b.Normalize();
		var c = a * b;
        Console.WriteLine("-- 4.4.8項 168ページ");
        Console.WriteLine("積");
		Console.WriteLine("クォータニオンa = {0}, クォータニオンb = {1}", a, b);
		Console.WriteLine("a * b = {0}, その大きさ = {1}", c, c.Length());
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void AxisAngle() {
		var axis = new Vector3(1, 1, 0);
		axis.Normalize();
		var angle = MathHelper.Pi / 3;
		var a = Quaternion.CreateFromAxisAngle(axis, angle);
        Console.WriteLine("-- 4.4.9項 169ページ");
        Console.WriteLine("軸と角度から回転クォータニオン");
		Console.WriteLine("軸 = {0}, 角度 = {1}[rad]", axis, angle);
		Console.WriteLine("クォータニオン = {0}", a);
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void Slerp() {
		var a = new Quaternion(1, 2, -3, -4);
		var b = new Quaternion(1, -1, -3, 3);
		Quaternion c;
		float amount;
		a.Normalize();
		b.Normalize();
        Console.WriteLine("-- 4.4.10項 172ページ");
        Console.WriteLine("球面線形補間");
		Console.WriteLine("クォータニオンa = {0}", a);
		Console.WriteLine("クォータニオンb = {0}", b);

		amount = 0;
		c = Quaternion.Slerp(a, b, amount);
		Console.WriteLine("Slerp(a, b, {0}) = {1}, その大きさ = {2}", amount, c, c.Length());

		amount = 0.25f;
		c = Quaternion.Slerp(a, b, amount);
		Console.WriteLine("Slerp(a, b, {0}) = {1}, その大きさ = {2}", amount, c, c.Length());

		amount = 1;
		c = Quaternion.Slerp(a, b, amount);
		Console.WriteLine("Slerp(a, b, {0}) = {1}, その大きさ = {2}", amount, c, c.Length());

		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void ToMatrix() {
		var a = new Quaternion(1, 2, -3, -4);
		a.Normalize();
		Matrix b;
		Matrix.CreateFromQuaternion(ref a, out b);
        Console.WriteLine("-- 4.4.11項 173ページ");
        Console.WriteLine("クォータニオンから行列");
		Console.WriteLine("クォータニオン = {0}", a);
		Console.WriteLine("行列 = {0}", b);
		Console.WriteLine();
	}
}

partial class MathSample3 {
	static void ExpLog() {
		var a = new Quaternion(1, -2, -3, 4);
		a.Normalize();
		Quaternion b, c, cc;
		Quaternion.Log(ref a, out b);
		Quaternion.Exp(ref b, out c);
		var aa = a * a;
		var b2 = b + b;
		Quaternion.Exp(ref b2, out cc);
        Console.WriteLine("-- 4.4.14項 178ページ");
		Console.WriteLine("クォータニオンの指数と対数");
		Console.WriteLine("クォータニオン = {0}", a);
		Console.WriteLine("aの対数クォータニオンb = {0}", b);
		Console.WriteLine("bの指数クォータニオンc = {0}", c);
		Console.WriteLine("a * a = {0}", aa);
		Console.WriteLine("Exp(b + b) = Exp(Log(a) + Log(a)) = {0}", cc);
		Console.WriteLine();
	}
}
