ardupilot/Tools/ArdupilotMegaPlanner/HIL/Matrix3.cs

180 lines
6.0 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YLScsDrawing.Drawing3d;
namespace ArdupilotMega.HIL
{
public class Matrix3
{
// '''a 3x3 matrix, intended as a rotation matrix'''
Matrix3 self;
Vector3 a;
Vector3 b;
Vector3 c;
public Matrix3()
{
self = this;
self.identity();
}
public Matrix3(Vector3 a, Vector3 b, Vector3 c)
{
self = this;
this.a = a;
this.b = b;
this.c = c;
}
public new string ToString()
{
return String.Format("Matrix3(({0}, {1}, {2}), ({3}, {4}, {5}), ({6}, {7}, {8}))",
self.a.x, self.a.y, self.a.z,
self.b.x, self.b.y, self.b.z,
self.c.x, self.c.y, self.c.z);
}
public void identity()
{
self.a = new Vector3(1, 0, 0);
self.b = new Vector3(0, 1, 0);
self.c = new Vector3(0, 0, 1);
}
public Matrix3 transposed()
{
return new Matrix3(new Vector3(self.a.x, self.b.x, self.c.x),
new Vector3(self.a.y, self.b.y, self.c.y),
new Vector3(self.a.z, self.b.z, self.c.z));
}
public void from_euler(double roll, double pitch, double yaw)
{
// '''fill the matrix from Euler angles in radians'''
double cp = Utils.cos(pitch);
double sp = Utils.sin(pitch);
double sr = Utils.sin(roll);
double cr = Utils.cos(roll);
double sy = Utils.sin(yaw);
double cy = Utils.cos(yaw);
self.a.x = cp * cy;
self.a.y = (sr * sp * cy) - (cr * sy);
self.a.z = (cr * sp * cy) + (sr * sy);
self.b.x = cp * sy;
self.b.y = (sr * sp * sy) + (cr * cy);
self.b.z = (cr * sp * sy) - (sr * cy);
self.c.x = -sp;
self.c.y = sr * cp;
self.c.z = cr * cp;
}
public void to_euler(ref double roll, ref double pitch, ref double yaw)
{
// '''find Euler angles for the matrix'''
if (self.c.x >= 1.0)
pitch = Math.PI;
else if (self.c.x <= -1.0)
pitch = -Math.PI;
else
pitch = -Utils.asin(self.c.x);
roll = Utils.atan2(self.c.y, self.c.z);
yaw = Utils.atan2(self.b.x, self.a.x);
//return (roll, pitch, yaw)
}
public static Matrix3 operator +(Matrix3 self, Matrix3 m)
{
return new Matrix3(self.a + m.a, self.b + m.b, self.c + m.c);
}
public static Matrix3 operator -(Matrix3 self, Matrix3 m)
{
return new Matrix3(self.a - m.a, self.b - m.b, self.c - m.c);
}
public static Vector3 operator *(Matrix3 self, Vector3 v)
{
return new Vector3(self.a.x * v.x + self.a.y * v.y + self.a.z * v.z,
self.b.x * v.x + self.b.y * v.y + self.b.z * v.z,
self.c.x * v.x + self.c.y * v.y + self.c.z * v.z);
}
public static Matrix3 operator *(Matrix3 self, Matrix3 m)
{
return new Matrix3(new Vector3(self.a.x * m.a.x + self.a.y * m.b.x + self.a.z * m.c.x,
self.a.x * m.a.y + self.a.y * m.b.y + self.a.z * m.c.y,
self.a.x * m.a.z + self.a.y * m.b.z + self.a.z * m.c.z),
new Vector3(self.b.x * m.a.x + self.b.y * m.b.x + self.b.z * m.c.x,
self.b.x * m.a.y + self.b.y * m.b.y + self.b.z * m.c.y,
self.b.x * m.a.z + self.b.y * m.b.z + self.b.z * m.c.z),
new Vector3(self.c.x * m.a.x + self.c.y * m.b.x + self.c.z * m.c.x,
self.c.x * m.a.y + self.c.y * m.b.y + self.c.z * m.c.y,
self.c.x * m.a.z + self.c.y * m.b.z + self.c.z * m.c.z));
}
public static Matrix3 operator *(Matrix3 self, double v)
{
return new Matrix3(self.a * v, self.b * v, self.c * v);
}
public static Matrix3 operator /(Matrix3 self, double v)
{
return new Matrix3(self.a / v, self.b / v, self.c / v);
}
public static Matrix3 operator -(Matrix3 self)
{
return new Matrix3(-self.a, -self.b, -self.c);
}
public Matrix3 copy()
{
return new Matrix3(self.a.copy(), self.b.copy(), self.c.copy());
}
public void rotate(Vector3 g)
{
// '''rotate the matrix by a given amount on 3 axes'''
Matrix3 temp_matrix = new Matrix3(self.a.copy(), self.b.copy(), self.c.copy());
temp_matrix.a.x = a.y * g.z - a.z * g.y;
temp_matrix.a.y = a.z * g.x - a.x * g.z;
temp_matrix.a.z = a.x * g.y - a.y * g.x;
temp_matrix.b.x = b.y * g.z - b.z * g.y;
temp_matrix.b.y = b.z * g.x - b.x * g.z;
temp_matrix.b.z = b.x * g.y - b.y * g.x;
temp_matrix.c.x = c.y * g.z - c.z * g.y;
temp_matrix.c.y = c.z * g.x - c.x * g.z;
temp_matrix.c.z = c.x * g.y - c.y * g.x;
self.a += temp_matrix.a;
self.b += temp_matrix.b;
self.c += temp_matrix.c;
}
public void normalize()
{
// '''re-normalise a rotation matrix'''
Vector3 error = self.a * self.b;
Vector3 t0 = self.a - (self.b * (0.5 * error));
Vector3 t1 = self.b - (self.a * (0.5 * error));
Vector3 t2 = t0 % t1;
self.a = t0 * (1.0 / t0.length());
self.b = t1 * (1.0 / t1.length());
self.c = t2 * (1.0 / t2.length());
}
public double trace()
{
// '''the trace of the matrix'''
return self.a.x + self.b.y + self.c.z;
}
}
}