lixiaojun
2025-04-18 28ba54f194f1301c45aa30b44cd7b612855b8963
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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);
        }
 
 
 
    }
}