namespace Yw.WpfUI.Hydro
{
///
/// 抽象线转换辅助类
///
internal class LogicalLineTransformHelper
{
///
///
///
public LogicalLineTransformHelper(Point3D start, Point3D end)
{
this.StartPoint = start;
this.EndPoint = end;
this.Direction = end - start;
this.Length = this.Direction.Length;
this.Direction.Normalize();
this.Perpendicular = Math.Abs(Direction.X) > 0.9
? Vector3D.CrossProduct(Direction, new Vector3D(0, 1, 0))
: Vector3D.CrossProduct(Direction, new Vector3D(1, 0, 0));
this.Perpendicular.Normalize();
}
///
/// 开始点
///
public Point3D StartPoint { get; }
///
/// 结束点
///
public Point3D EndPoint { get; }
///
/// 长度
///
public double Length { get; }
///
/// 方向
///
public Vector3D Direction { get; }
///
/// 垂线
///
public Vector3D Perpendicular { get; }
///
/// 将局部坐标转换为世界坐标
///
public Point3D LocalToWorld(Point3D local)
{
// 计算中点作为局部坐标系原点
Point3D center = this.StartPoint + (this.EndPoint - this.StartPoint) * 0.5;
// 创建变换矩阵
var transform = new Matrix3D();
// 旋转从Z轴到实际方向
var axis = Vector3D.CrossProduct(new Vector3D(0, 0, 1), this.Direction);
double angle = Vector3D.AngleBetween(new Vector3D(0, 0, 1), this.Direction);
transform.Rotate(new Quaternion(axis, angle));
// 平移
transform.Translate(new Vector3D(center.X, center.Y, center.Z));
return transform.Transform(local);
}
///
/// 将世界坐标转换为局部坐标
///
public Point3D WorldToLocal(Point3D world)
{
Point3D center = this.StartPoint + (this.EndPoint - this.StartPoint) * 0.5;
var transform = new Matrix3D();
transform.Translate(new Vector3D(-center.X, -center.Y, -center.Z));
var axis = Vector3D.CrossProduct(new Vector3D(0, 0, 1), Direction);
double angle = -Vector3D.AngleBetween(new Vector3D(0, 0, 1), Direction);
transform.Rotate(new Quaternion(axis, angle));
return transform.Transform(world);
}
///
/// 计算矩阵
///
public Matrix3D CalculateMatrix()
{
// 计算中点
var center = this.StartPoint + (this.EndPoint - this.StartPoint) * 0.5;
// 计算旋转轴和角度(从Z轴旋转到实际方向)
var axis = Vector3D.CrossProduct(new Vector3D(0, 0, 1), this.Direction);
double angle = Vector3D.AngleBetween(new Vector3D(0, 0, 1), this.Direction);
// 创建变换矩阵
var transform = new Matrix3D();
transform.Rotate(new Quaternion(axis, angle));
transform.Translate(new Vector3D(center.X, center.Y, center.Z));
return transform;
}
///
/// 计算转换
///
public Transform3D CalculateTransform()
{
var matrix = CalculateMatrix();
return new MatrixTransform3D(matrix);
}
}
}