namespace RobotNet10.RobotApp.SLAM.Cartographer.Geometry;
///
/// 3x3 matrix for representing covariance matrices
///
public readonly struct Matrix3x3
{
private readonly double[,] _data;
///
/// Creates a new 3x3 matrix with all zeros
///
public Matrix3x3()
{
_data = new double[3, 3];
}
///
/// Creates a new 3x3 matrix from a 2D array
///
/// 3x3 array of values
/// Thrown if array is not 3x3
public Matrix3x3(double[,] data)
{
if (data.GetLength(0) != 3 || data.GetLength(1) != 3)
{
throw new ArgumentException("Matrix must be 3x3", nameof(data));
}
_data = new double[3, 3];
Array.Copy(data, _data, 9);
}
///
/// Gets or sets the value at the specified row and column
///
public double this[int row, int col]
{
get => _data[row, col];
set => _data[row, col] = value;
}
///
/// Gets the determinant of the matrix
///
public double Determinant
{
get
{
return _data[0, 0] * (_data[1, 1] * _data[2, 2] - _data[1, 2] * _data[2, 1])
- _data[0, 1] * (_data[1, 0] * _data[2, 2] - _data[1, 2] * _data[2, 0])
+ _data[0, 2] * (_data[1, 0] * _data[2, 1] - _data[1, 1] * _data[2, 0]);
}
}
///
/// Creates an identity matrix
///
public static Matrix3x3 Identity()
{
var matrix = new Matrix3x3();
matrix[0, 0] = 1.0;
matrix[1, 1] = 1.0;
matrix[2, 2] = 1.0;
return matrix;
}
///
/// Creates a covariance matrix for 2D pose (x, y, theta)
///
/// Variance in x
/// Variance in y
/// Variance in theta
/// Covariance between x and y
/// Covariance between x and theta
/// Covariance between y and theta
public static Matrix3x3 Covariance(double xx, double yy, double tt, double xy = 0.0, double xt = 0.0, double yt = 0.0)
{
var matrix = new Matrix3x3();
matrix[0, 0] = xx; // Var(x)
matrix[1, 1] = yy; // Var(y)
matrix[2, 2] = tt; // Var(theta)
matrix[0, 1] = matrix[1, 0] = xy; // Cov(x,y)
matrix[0, 2] = matrix[2, 0] = xt; // Cov(x,theta)
matrix[1, 2] = matrix[2, 1] = yt; // Cov(y,theta)
return matrix;
}
///
/// Gets all values as a 2D array
///
public double[,] ToArray()
{
var result = new double[3, 3];
Array.Copy(_data, result, 9);
return result;
}
///
/// Gets the matrix as a flattened array (row-major order)
///
public double[] ToFlatArray()
{
return
[
_data[0, 0], _data[0, 1], _data[0, 2],
_data[1, 0], _data[1, 1], _data[1, 2],
_data[2, 0], _data[2, 1], _data[2, 2]
];
}
public override string ToString()
{
return $"[{_data[0, 0]:F3}, {_data[0, 1]:F3}, {_data[0, 2]:F3}]\n" +
$"[{_data[1, 0]:F3}, {_data[1, 1]:F3}, {_data[1, 2]:F3}]\n" +
$"[{_data[2, 0]:F3}, {_data[2, 1]:F3}, {_data[2, 2]:F3}]";
}
}