Files
wg_cpso/CaeMesh/CoordinateSystem.cs

511 lines
24 KiB
C#
Raw Permalink Normal View History

2026-03-25 18:20:24 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CaeGlobals;
using DynamicTypeDescriptor;
using System.Runtime.Serialization;
using System.Drawing;
using System.Net.Configuration;
namespace CaeMesh
{
[Serializable]
public enum CsPointCreatedFromEnum
{
[StandardValue("Coordinates", Description = "Coordinates", DisplayName = "Coordinates")]
Coordinates,
[StandardValue("OnPoint", Description = "On point", DisplayName = "On point")]
OnPoint,
[StandardValue("BetweenTwoPoints", Description = "Between two points", DisplayName = "Between two points")]
BetweenTwoPoints,
[StandardValue("CircleCenter", Description = "Circle center by 3 points", DisplayName = "Circle center by 3 points")]
CircleCenter
}
//
[Serializable]
public enum CoordinateSystemTypeEnum
{
//[StandardValue("Selection", Description = "Selection/Coordinates", DisplayName = "Selection/Coordinates")]
Rectangular,
//[StandardValue("BetweenTwoPoints", Description = "Between two points", DisplayName = "Between two points")]
Cylindrical,
}
//
[Serializable]
public class CoordinateSystem : NamedClass, ISerializable, IContainsEquations
{
// Variables
private CoordinateSystemTypeEnum _type; //ISerializable
private EquationContainer _x1; //ISerializable
private EquationContainer _y1; //ISerializable
private EquationContainer _z1; //ISerializable
private EquationContainer _x2; //ISerializable
private EquationContainer _y2; //ISerializable
private EquationContainer _z2; //ISerializable
private EquationContainer _x3; //ISerializable
private EquationContainer _y3; //ISerializable
private EquationContainer _z3; //ISerializable
private CsPointCreatedFromEnum _centerCreatedFrom; //ISerializable
private CsPointCreatedFromEnum _pointXCreatedFrom; //ISerializable
private CsPointCreatedFromEnum _pointXYCreatedFrom; //ISerializable
private int[] _centerCreationIds; //ISerializable
private Selection _centerCreationData; //ISerializable
private int[] _pointXCreationIds; //ISerializable
private Selection _pointXCreationData; //ISerializable
private int[] _pointXYCreationIds; //ISerializable
private Selection _pointXYCreationData; //ISerializable
private bool _nameVisible; //ISerializable
private bool _twoD; //ISerializable
private Color _color; //ISerializable
[NonSerialized] private Vec3D _center;
[NonSerialized] private Vec3D _dx;
[NonSerialized] private Vec3D _dy;
[NonSerialized] private Vec3D _dz;
public const string DefaultCoordinateSystemName = "Global";
// Properties
public CoordinateSystemTypeEnum Type { get { return _type; } set { _type = value; } }
public EquationContainer X1 { get { return _x1; } set { SetX1(value); } }
public EquationContainer Y1 { get { return _y1; } set { SetY1(value); } }
public EquationContainer Z1 { get { return _z1; } set { SetZ1(value); } }
public EquationContainer X2 { get { return _x2; } set { SetX2(value); } }
public EquationContainer Y2 { get { return _y2; } set { SetY2(value); } }
public EquationContainer Z2 { get { return _z2; } set { SetZ2(value); } }
public EquationContainer X3 { get { return _x3; } set { SetX3(value); } }
public EquationContainer Y3 { get { return _y3; } set { SetY3(value); } }
public EquationContainer Z3 { get { return _z3; } set { SetZ3(value); } }
public CsPointCreatedFromEnum CenterCreatedFrom
{
get { return _centerCreatedFrom; }
set
{
if (_centerCreatedFrom != value)
{
ClearCenterRegionData();
_centerCreatedFrom = value;
}
}
}
public CsPointCreatedFromEnum PointXCreatedFrom
{
get { return _pointXCreatedFrom; }
set
{
if (_pointXCreatedFrom != value)
{
ClearPointXRegionData();
_pointXCreatedFrom = value;
}
}
}
public CsPointCreatedFromEnum PointXYCreatedFrom
{
get { return _pointXYCreatedFrom; }
set
{
if (_pointXYCreatedFrom != value)
{
ClearPointXYRegionData();
_pointXYCreatedFrom = value;
}
}
}
public int[] CenterCreationIds { get { return _centerCreationIds; } set { _centerCreationIds = value; } }
public Selection CenterCreationData { get { return _centerCreationData; } set { _centerCreationData = value; } }
public int[] PointXCreationIds { get { return _pointXCreationIds; } set { _pointXCreationIds = value; } }
public Selection PointXCreationData { get { return _pointXCreationData; } set { _pointXCreationData = value; } }
public int[] PointXYCreationIds { get { return _pointXYCreationIds; } set { _pointXYCreationIds = value; } }
public Selection PointXYCreationData { get { return _pointXYCreationData; } set { _pointXYCreationData = value; } }
public bool NameVisible { get { return _nameVisible; } set { _nameVisible = value; } }
public bool TwoD { get { return _twoD; } }
public Color Color { get { return _color; } set { _color = value; } }
// Constructors
public CoordinateSystem(string name, bool twoD)
: base(name)
{
Clear();
//
_twoD = twoD;
}
public CoordinateSystem(SerializationInfo info, StreamingContext context)
: base(info, context)
{
foreach (SerializationEntry entry in info)
{
switch (entry.Name)
{
case "_type":
_type = (CoordinateSystemTypeEnum)entry.Value; break;
case "_x1":
SetX1((EquationContainer)entry.Value, false); break;
case "_y1":
SetY1((EquationContainer)entry.Value, false); break;
case "_z1":
SetZ1((EquationContainer)entry.Value, false); break;
case "_x2":
SetX2((EquationContainer)entry.Value, false); break;
case "_y2":
SetY2((EquationContainer)entry.Value, false); break;
case "_z2":
SetZ2((EquationContainer)entry.Value, false); break;
case "_x3":
SetX3((EquationContainer)entry.Value, false); break;
case "_y3":
SetY3((EquationContainer)entry.Value, false); break;
case "_z3":
SetZ3((EquationContainer)entry.Value, false); break;
case "_centerCreatedFrom":
_centerCreatedFrom = (CsPointCreatedFromEnum)entry.Value; break;
case "_pointXCreatedFrom":
_pointXCreatedFrom = (CsPointCreatedFromEnum)entry.Value; break;
case "_pointXYCreatedFrom":
_pointXYCreatedFrom = (CsPointCreatedFromEnum)entry.Value; break;
case "_centerCreationIds":
_centerCreationIds = (int[])entry.Value; break;
case "_centerCreationData":
_centerCreationData = (Selection)entry.Value; break;
case "_pointXCreationIds":
_pointXCreationIds = (int[])entry.Value; break;
case "_pointXCreationData":
_pointXCreationData = (Selection)entry.Value; break;
case "_pointXYCreationIds":
_pointXYCreationIds = (int[])entry.Value; break;
case "_pointXYCreationData":
_pointXYCreationData = (Selection)entry.Value; break;
case "_nameVisible":
_nameVisible = (bool)entry.Value; break;
case "_twoD":
_twoD = (bool)entry.Value; break;
case "_color":
_color = (Color)entry.Value; break;
}
}
// Compatibility for version v2.1.2
if (_centerCreationData == null) _centerCreatedFrom = CsPointCreatedFromEnum.Coordinates;
if (_pointXCreationData == null) _pointXCreatedFrom = CsPointCreatedFromEnum.Coordinates;
if (_pointXYCreationData == null) _pointXYCreatedFrom = CsPointCreatedFromEnum.Coordinates;
}
// Methods
private void SetX1(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _x1, value, null, EquationChanged, checkEquation);
}
private void SetY1(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _y1, value, null, EquationChanged, checkEquation);
}
private void SetZ1(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _z1, value, Check2D, EquationChanged, checkEquation);
}
private void SetX2(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _x2, value, null, EquationChanged, checkEquation);
}
private void SetY2(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _y2, value, null, EquationChanged, checkEquation);
}
private void SetZ2(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _z2, value, Check2D, EquationChanged, checkEquation);
}
private void SetX3(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _x3, value, null, EquationChanged, checkEquation);
}
private void SetY3(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _y3, value, null, EquationChanged, checkEquation);
}
private void SetZ3(EquationContainer value, bool checkEquation = true)
{
EquationContainer.SetAndCheck(ref _z3, value, Check2D, EquationChanged, checkEquation);
}
//
private double Check2D(double value)
{
if (_twoD) return 0;
else return value;
}
private void EquationChanged()
{
Vec3D p1 = new Vec3D(new double[] { _x1.Value, _y1.Value, _z1.Value }); // _center might be null
Vec3D p2 = new Vec3D(PointX());
Vec3D p3 = new Vec3D(PointXY());
// Center
_center = p1;
// Direction x
_dx = p2 - p1;
_dx.Normalize();
// Direction z
Vec3D d3 = p3 - p1;
_dz = Vec3D.CrossProduct(_dx, d3);
_dz.Normalize();
// Direction y
_dy = Vec3D.CrossProduct(_dz, _dx);
_dy.Normalize();
}
// IContainsEquations
public void CheckEquations()
{
_x1.CheckEquation();
_y1.CheckEquation();
_z1.CheckEquation();
_x2.CheckEquation();
_y2.CheckEquation();
_z2.CheckEquation();
_x3.CheckEquation();
_y3.CheckEquation();
_z3.CheckEquation();
}
public bool TryCheckEquations()
{
try
{
CheckEquations();
return true;
}
catch (Exception ex) { return false; }
}
//
private void Clear()
{
if (_x1 == null) _x1 = new EquationContainer(typeof(StringLengthConverter), 0);
else _x1.SetEquationFromValue(0);
if (_y1 == null) _y1 = new EquationContainer(typeof(StringLengthConverter), 0);
else _y1.SetEquationFromValue(0);
if (_z1 == null) _z1 = new EquationContainer(typeof(StringLengthConverter), 0);
else _z1.SetEquationFromValue(0);
//
if (_x2 == null) _x2 = new EquationContainer(typeof(StringLengthConverter), 1);
else _x2.SetEquationFromValue(1);
if (_y2 == null) _y2 = new EquationContainer(typeof(StringLengthConverter), 0);
else _y2.SetEquationFromValue(0);
if (_z2 == null) _z2 = new EquationContainer(typeof(StringLengthConverter), 0);
else _z2.SetEquationFromValue(0);
//
if (_x3 == null) _x3 = new EquationContainer(typeof(StringLengthConverter), 0);
else _x3.SetEquationFromValue(0);
if (_y3 == null) _y3 = new EquationContainer(typeof(StringLengthConverter), 1);
else _y3.SetEquationFromValue(1);
if (_z3 == null) _z3 = new EquationContainer(typeof(StringLengthConverter), 0);
else _z3.SetEquationFromValue(0);
//
ClearCenterRegionData();
ClearPointXRegionData();
ClearPointXYRegionData();
//
_nameVisible = true;
_twoD = false;
_color = Color.Yellow;
//
EquationChanged();
}
private void ClearCenterRegionData()
{
_centerCreatedFrom = CsPointCreatedFromEnum.Coordinates;
//
if (_x1.IsEquation()) _x1.SetEquationFromValue(_x1.Value);
if (_y1.IsEquation()) _y1.SetEquationFromValue(_y1.Value);
if (_z1.IsEquation()) _z1.SetEquationFromValue(_z1.Value);
//
_centerCreationIds = null;
_centerCreationData = null;
}
private void ClearPointXRegionData()
{
_pointXCreatedFrom = CsPointCreatedFromEnum.Coordinates;
//
if (_x2.IsEquation()) _x2.SetEquationFromValue(_x2.Value);
if (_y2.IsEquation()) _y2.SetEquationFromValue(_y2.Value);
if (_z2.IsEquation()) _z2.SetEquationFromValue(_z2.Value);
//
_pointXCreationIds = null;
_pointXCreationData = null;
}
private void ClearPointXYRegionData()
{
_pointXYCreatedFrom = CsPointCreatedFromEnum.Coordinates;
//
if (_x3.IsEquation()) _x3.SetEquationFromValue(_x3.Value);
if (_y3.IsEquation()) _y3.SetEquationFromValue(_y3.Value);
if (_z3.IsEquation()) _z3.SetEquationFromValue(_z3.Value);
//
_pointXYCreationIds = null;
_pointXYCreationData = null;
}
public void Reset()
{
Clear();
}
public Vec3D Center()
{
if (_center == null) EquationChanged();
return _center;
}
public double[] PointX()
{
return new double[] { _x2.Value, _y2.Value, _z2.Value };
}
public double[] PointXY()
{
return new double[] { _x3.Value, _y3.Value, _z3.Value };
}
public Vec3D DirectionX(double[] coor = null)
{
if (_dx == null) EquationChanged();
if (coor == null || coor.Length != 3 || (coor[0] == 0 && coor[1] == 0 && coor[2] == 0) ||
_type == CoordinateSystemTypeEnum.Rectangular) return _dx;
// Cylindrical point not equal to (0, 0, 0)
else
{
Vec3D p1 = new Vec3D(Center());
Vec3D p2 = new Vec3D(coor);
Vec3D dx = p2 - p1;
double k = Vec3D.DotProduct(dx, _dz); // project on x-y plane
Vec3D projDx = dx - k * _dz;
projDx.Normalize();
return projDx;
}
}
public Vec3D DirectionY(double[] coor = null, Vec3D dx = null)
{
if (_dy == null) EquationChanged();
if (coor == null || coor.Length != 3 || (coor[0] == 0 && coor[1] == 0 && coor[2] == 0) ||
_type == CoordinateSystemTypeEnum.Rectangular) return _dy;
// Cylindrical point not equal to (0, 0, 0)
else
{
if (dx == null) dx = DirectionX(coor);
Vec3D dy = Vec3D.CrossProduct(_dz, dx);
dy.Normalize();
return dy;
}
}
public Vec3D DirectionZ(double[] coor = null)
{
if (_dz == null) EquationChanged();
return _dz;
}
public double[] GetOrientedVectorAtPoint(double[] vector, double[] coor)
{
Vec3D directionX = DirectionX(coor);
Vec3D directionY = DirectionY(coor);
Vec3D directionZ = DirectionZ(coor);
Vec3D direction = vector[0] * directionX + vector[1] * directionY + vector[2] * directionZ;
return direction.Coor;
}
public double[] GetLocalCoordinates(double[] globalCoor)
{
double[] result = new double[3];
Vec3D v = new Vec3D(globalCoor) - Center();
//
if (_type == CoordinateSystemTypeEnum.Rectangular)
{
result[0] = Vec3D.DotProduct(v, _dx);
result[1] = Vec3D.DotProduct(v, _dy);
result[2] = Vec3D.DotProduct(v, _dz);
}
else if (_type == CoordinateSystemTypeEnum.Cylindrical)
{
// Z component
double z = Vec3D.DotProduct(v, _dz);
// Transverse vector
Vec3D vPerp = v - z * _dz;
// Radial distance
double rho = vPerp.Len;
// Compute angle φ
double xProj = Vec3D.DotProduct(vPerp, _dx);
double yProj = Vec3D.DotProduct(vPerp, _dy);
double phi = Math.Atan2(yProj, xProj); // in radians
//
result[0] = rho;
result[1] = phi;
result[2] = z;
}
else throw new NotSupportedException();
//
return result;
}
public bool IsProperlyDefined(out string error)
{
error = null;
try
{
EquationChanged();
//
if (_dx.Len2 == 0 || _dy.Len2 == 0 || _dz.Len2 == 0)
throw new CaeException("One of the directions is not properly defined. " +
"The selected points must not be colinear.");
//
if ((_centerCreatedFrom == CsPointCreatedFromEnum.OnPoint &&
(_centerCreationIds == null || _centerCreationIds.Length != 1)) ||
(_centerCreatedFrom == CsPointCreatedFromEnum.BetweenTwoPoints &&
(_centerCreationIds == null || _centerCreationIds.Length != 2)) ||
(_centerCreatedFrom == CsPointCreatedFromEnum.CircleCenter &&
(_centerCreationIds == null || _centerCreationIds.Length != 3)))
throw new CaeException("The selection of the coordinate system center point is not complete.");
if ((_pointXCreatedFrom == CsPointCreatedFromEnum.OnPoint &&
(_pointXCreationIds == null || _pointXCreationIds.Length != 1)) ||
(_pointXCreatedFrom == CsPointCreatedFromEnum.BetweenTwoPoints &&
(_pointXCreationIds == null || _pointXCreationIds.Length != 2)) ||
(_pointXCreatedFrom == CsPointCreatedFromEnum.CircleCenter &&
(_pointXCreationIds == null || _pointXCreationIds.Length != 3)))
throw new CaeException("The selection of coordinate system point in the 1st axis direction is not complete.");
if ((_pointXYCreatedFrom == CsPointCreatedFromEnum.OnPoint &&
(_pointXYCreationIds == null || _pointXYCreationIds.Length != 1)) ||
(_pointXYCreatedFrom == CsPointCreatedFromEnum.BetweenTwoPoints &&
(_pointXYCreationIds == null || _pointXYCreationIds.Length != 2)) ||
(_pointXYCreatedFrom == CsPointCreatedFromEnum.CircleCenter &&
(_pointXYCreationIds == null || _pointXYCreationIds.Length != 3)))
throw new CaeException("The selection of coordinate system point in 1-2 plane is not complete.");
//
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
// ISerialization
public new void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Using typeof() works also for null fields
base.GetObjectData(info, context);
//
info.AddValue("_type", _type, typeof(CoordinateSystemTypeEnum));
info.AddValue("_x1", _x1, typeof(EquationContainer));
info.AddValue("_y1", _y1, typeof(EquationContainer));
info.AddValue("_z1", _z1, typeof(EquationContainer));
info.AddValue("_x2", _x2, typeof(EquationContainer));
info.AddValue("_y2", _y2, typeof(EquationContainer));
info.AddValue("_z2", _z2, typeof(EquationContainer));
info.AddValue("_x3", _x3, typeof(EquationContainer));
info.AddValue("_y3", _y3, typeof(EquationContainer));
info.AddValue("_z3", _z3, typeof(EquationContainer));
info.AddValue("_centerCreatedFrom", _centerCreatedFrom, typeof(CsPointCreatedFromEnum));
info.AddValue("_pointXCreatedFrom", _pointXCreatedFrom, typeof(CsPointCreatedFromEnum));
info.AddValue("_pointXYCreatedFrom", _pointXYCreatedFrom, typeof(CsPointCreatedFromEnum));
info.AddValue("_centerCreationIds", _centerCreationIds, typeof(int[]));
info.AddValue("_centerCreationData", _centerCreationData, typeof(Selection));
info.AddValue("_pointXCreationIds", _pointXCreationIds, typeof(int[]));
info.AddValue("_pointXCreationData", _pointXCreationData, typeof(Selection));
info.AddValue("_pointXYCreationIds", _pointXYCreationIds, typeof(int[]));
info.AddValue("_pointXYCreationData", _pointXYCreationData, typeof(Selection));
info.AddValue("_nameVisible", _nameVisible, typeof(bool));
info.AddValue("_twoD", _twoD, typeof(bool));
info.AddValue("_color", _color, typeof(Color));
}
}
}