using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using CategoryTheory;
namespace Motion6D
{
[Serializable()]
public class RigidReferenceFrame : IReferenceFrame, ISerializable, ICategoryObject, IPostSetArrow
{
#region Fields
protected ReferenceFrame own = new ReferenceFrame();
protected ReferenceFrame relative = new ReferenceFrame();
private double[] relativePosition = new double[] { 0, 0, 0 };
private double[] relativeQuaternion = new double[] { 1, 0, 0, 0 };
List<IPosition> children = new List<IPosition>();
protected object obj;
protected bool isSerialized = false;
protected IReferenceFrame parent;
protected object parameters;
#endregion
#region Ctor
public RigidReferenceFrame()
{
Init();
}
protected RigidReferenceFrame(SerializationInfo info, StreamingContext context)
: this()
{
relativePosition = info.GetValue("Position", typeof(double[])) as double[];
relativeQuaternion = info.GetValue("Quaternion", typeof(double[])) as double[];
isSerialized = true;
Init();
}
#endregion
#region ISerializable Members
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Position", relativePosition, typeof(double[]));
info.AddValue("Quaternion", relativeQuaternion, typeof(double[]));
}
#endregion
#region IReferenceFrame Members
ReferenceFrame IReferenceFrame.Own
{
get { return own; }
}
List<IPosition> IReferenceFrame.Children
{
get { return children; }
}
#endregion
#region IPosition Members
double[] IPosition.Position
{
get { return own.Position; }
}
public virtual IReferenceFrame Parent
{
get
{
return parent;
}
set
{
if (value != null & parent != null)
{
throw new Exception("Parent");
}
parent = value;
if (value == null)
{
own = Motion6DFrame.Base;
return;
}
if (isSerialized)
{
isSerialized = false;
return;
}
IPostSetArrow post = this;
post.PostSetArrow();
}
}
public virtual object Parameters
{
get
{
return parameters;
}
set
{
parameters = value;
}
}
public virtual void Update()
{
ReferenceFrame b = BaseFrame;
own.Set(b, relative);
}
#endregion
#region ICategoryObject Members
ICategory ICategoryObject.Category
{
get { throw new Exception("The method or operation is not implemented."); }
}
ICategoryArrow ICategoryObject.Id
{
get { throw new Exception("The method or operation is not implemented."); }
}
#endregion
#region IAssociatedObject Members
object IAssociatedObject.Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
#endregion
#region IPostSetArrow Members
void IPostSetArrow.PostSetArrow()
{
CreateFrame();
for (int i = 0; i < 3; i++)
{
relative.Position[i] = relativePosition[i];
}
for (int i = 0; i < 4; i++)
{
relative.Quaternion[i] = relativeQuaternion[i];
}
relative.SetMatrix();
}
#endregion
#region Specific Members
public double[] RelativePosition
{
get { return relativePosition; }
}
public double[,] RelativeMatrix
{
get
{
double[,] m = new double[3, 3];
double[,] q = new double[4, 4];
Vector3D.V3DOperations.CalculateMatrix(relativeQuaternion, m, q);
return m;
}
set
{
Vector3D.V3DOperations.ConvertMatrixToQuaternion(relativeQuaternion, value);
}
}
protected ReferenceFrame BaseFrame
{
get
{
if (parent != null)
{
return parent.Own;
}
return Motion6DFrame.Base;
}
}
protected virtual void CreateFrame()
{
if (!IsVelocity & !IsAngularVelocity)
{
relative = new ReferenceFrame();
own = new ReferenceFrame();
}
else if (!IsVelocity)
{
relative = new RotatedFrame();
own = new RotatedFrame();
}
else
{
relative = new Motion6DFrame();
own = new Motion6DFrame();
}
}
protected virtual bool IsVelocity
{
get
{
if (parent == null)
{
return true;
}
return parent.Own is IVelocity;
}
}
protected virtual bool IsAngularVelocity
{
get
{
if (parent == null)
{
return true;
}
return parent.Own is IAngularVelocity;
}
}
public void Init()
{
double[] q = relative.Quaternion;
for (int i = 0; i < q.Length; i++)
{
q[i] = relativeQuaternion[i];
}
double[] p = relative.Position;
for (int i = 0; i < p.Length; i++)
{
p[i] = relativePosition[i];
}
}
#endregion
}
}