namespace Yw.WpfUI.Hydro
|
{
|
/// <summary>
|
/// 抽象线转换辅助类
|
/// </summary>
|
internal class LogicalLineTransformHelper
|
{
|
/// <summary>
|
///
|
/// </summary>
|
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();
|
}
|
|
/// <summary>
|
/// 开始点
|
/// </summary>
|
public Point3D StartPoint { get; }
|
|
/// <summary>
|
/// 结束点
|
/// </summary>
|
public Point3D EndPoint { get; }
|
|
/// <summary>
|
/// 长度
|
/// </summary>
|
public double Length { get; }
|
|
/// <summary>
|
/// 方向
|
/// </summary>
|
public Vector3D Direction { get; }
|
|
/// <summary>
|
/// 垂线
|
/// </summary>
|
public Vector3D Perpendicular { get; }
|
|
|
/// <summary>
|
/// 将局部坐标转换为世界坐标
|
/// </summary>
|
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);
|
}
|
|
/// <summary>
|
/// 将世界坐标转换为局部坐标
|
/// </summary>
|
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);
|
}
|
|
/// <summary>
|
/// 计算矩阵
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 计算转换
|
/// </summary>
|
public Transform3D CalculateTransform()
|
{
|
var matrix = CalculateMatrix();
|
return new MatrixTransform3D(matrix);
|
}
|
|
|
|
}
|
}
|