開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
空のプロジェクト |
プロジェクト名 |
Quaternion |
参考
Program.cs
// Quaternion6 大圏コース逆算
using System;
using Microsoft.Xna.Framework; // .NET参照
class Program
{
static void Main()
{
float startLatDeg = 35;
float startLonDeg = 135;
float angleDeg = 53.22f;
float distNM = 4863.88f;
float startLatRad = MathHelper.ToRadians(startLatDeg);
float startLonRad = MathHelper.ToRadians(startLonDeg);
float angleRad = MathHelper.ToRadians(angleDeg);
float dist = distNM * 1.852f / 20000;
Console.WriteLine(string.Format("dist={0:f2}", dist));
// +Z=0 +X=90
float y = (float)Math.Sin(startLatRad);
float r = (float)Math.Cos(startLatRad);
float z = (float)Math.Cos(startLonRad) * r;
float x = (float)Math.Sin(startLonRad) * r;
Vector3 axis = new Vector3(x, y, z); // 回転軸
Print(axis);
// +Z=0 +X=90
float rad = startLatRad + dist * MathHelper.Pi;
y = (float)Math.Sin(rad);
r = (float)Math.Cos(rad);
z = (float)Math.Cos(startLonRad) * r;
x = (float)Math.Sin(startLonRad) * r;
Vector3 v = new Vector3(x, y, z); // 回転する座標
Print(v);
Quaternion p = new Quaternion(v, 0);
Quaternion rot = Quaternion.CreateFromAxisAngle(axis, angleRad);
Quaternion q = Quaternion.Conjugate(rot) * p * rot;
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2} w={3:f2} len={4:f2}",
q.X, q.Y, q.Z, q.W, q.Length()));
PrintLatLon(q.X, q.Y, q.Z);
Console.ReadLine();
}
static void Print(Vector3 v)
{
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2} len={3:f2}",
v.X, v.Y, v.Z, v.Length()));
PrintLatLon(v.X, v.Y, v.Z);
}
static void PrintLatLon(float x, float y, float z)
{
Console.WriteLine(string.Format("lat={0:f1} lon={1:f1}",
MathHelper.ToDegrees((float)Math.Asin(y)),
MathHelper.ToDegrees((float)Math.Atan2(x, z))));
}
}
出力
dist=0.45
x=0.58 y=0.57 z=-0.58 len=1.00
lat=35.0 lon=135.0
x=-0.31 y=0.90 z=0.31 len=1.00
lat=63.9 lon=-45.0
x=-0.71 y=0.57 z=-0.41 w=0.00 len=1.00
lat=35.0 lon=-120.0
Program.cs
// Quaternion6 2.Vector4 ver.
using System;
using Microsoft.Xna.Framework; // .NET参照
class Program
{
static void Main()
{
float startLatDeg = 35;
float startLonDeg = 135;
float angleDeg = 53.22f;
float distNM = 4863.88f;
float startLatRad = MathHelper.ToRadians(startLatDeg);
float startLonRad = MathHelper.ToRadians(startLonDeg);
float angleRad = MathHelper.ToRadians(angleDeg);
float dist = distNM * 1.852f / 20000;
Console.WriteLine(string.Format("dist={0:f2}", dist));
// +Z=0 +X=90
float y = (float)Math.Sin(startLatRad);
float r = (float)Math.Cos(startLatRad);
float z = (float)Math.Cos(startLonRad) * r;
float x = (float)Math.Sin(startLonRad) * r;
Vector3 axis = new Vector3(x, y, z); // 回転軸
Print(axis);
// +Z=0 +X=90
float rad = startLatRad + dist * MathHelper.Pi;
y = (float)Math.Sin(rad);
r = (float)Math.Cos(rad);
z = (float)Math.Cos(startLonRad) * r;
x = (float)Math.Sin(startLonRad) * r;
Vector3 v = new Vector3(x, y, z); // 回転する座標
Print(v);
Vector4 p = new Vector4(v, 0);
Vector4 rot = CreateFromAxisAngle(axis, angleRad);
Vector4 conj = new Vector4(-rot.X, -rot.Y, -rot.Z, rot.W);
Vector4 q = MulQ(MulQ(conj, p), rot);
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2} w={3:f2} len={4:f2}",
q.X, q.Y, q.Z, q.W, q.Length()));
PrintLatLon(q.X, q.Y, q.Z);
Console.ReadLine();
}
static Vector4 CreateFromAxisAngle(Vector3 axis, float angle)
{
// 回転軸の正規化
float norm = axis.Length();
if (norm <= 0) return Vector4.Zero;
norm = 1 / (float)Math.Sqrt(norm);
axis *= norm;
angle *= 0.5f;
float c = (float)Math.Cos(angle);
float s = (float)Math.Sin(angle);
Vector4 v = new Vector4(axis * s, c);
return v;
}
static Vector4 MulQ(Vector4 v1, Vector4 v2)
{
Vector4 v;
v.X = (v1.W * v2.X) + (v1.X * v2.W) + (v1.Y * v2.Z) - (v1.Z * v2.Y);
v.Y = (v1.W * v2.Y) + (v1.Y * v2.W) + (v1.Z * v2.X) - (v1.X * v2.Z);
v.Z = (v1.W * v2.Z) + (v1.Z * v2.W) + (v1.X * v2.Y) - (v1.Y * v2.X);
v.W = (v1.W * v2.W) - (v1.X * v2.X) - (v1.Y * v2.Y) - (v1.Z * v2.Z);
return v;
}
static void Print(Vector3 v)
{
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2} len={3:f2}",
v.X, v.Y, v.Z, v.Length()));
PrintLatLon(v.X, v.Y, v.Z);
}
static void PrintLatLon(float x, float y, float z)
{
Console.WriteLine(string.Format("lat={0:f1} lon={1:f1}",
MathHelper.ToDegrees((float)Math.Asin(y)),
MathHelper.ToDegrees((float)Math.Atan2(x, z))));
}
}
最終更新:2012年12月19日 17:02