瀏覽代碼

新增基于两对点的坐标系变换构造函数

新增 CoordinateTransformer 构造函数,支持通过基坐标系与本地坐标系的两对对应点(不含缩放,仅旋转和平移)快速建立坐标系变换关系,便于灵活定义坐标映射。
孝锋 徐 8 月之前
父節點
當前提交
8193b9b8d2
共有 1 個文件被更改,包括 53 次插入0 次删除
  1. 53 0
      TeamAAS-VM/Core/CoordinateTransformer.cs

+ 53 - 0
TeamAAS-VM/Core/CoordinateTransformer.cs

@@ -167,6 +167,59 @@ namespace TeamAAS_VP.Core
             T[1, 2] = -P1[1];
         }
 
+        /// <summary>
+        /// 使用两对对应点创建坐标系:给定基坐标系中的两个点及它们在Local坐标系中的对应坐标(单位一致),构造Local坐标系(不包含缩放)。
+        /// worldP1 对应 localP1,worldP2 对应 localP2。
+        /// </summary>
+        /// <param name="worldP1">基坐标系中的点1</param>
+        /// <param name="worldP2">基坐标系中的点2</param>
+        /// <param name="localP1">Local坐标系中对应点1</param>
+        /// <param name="localP2">Local坐标系中对应点2</param>
+        public CoordinateTransformer(PointF worldP1, PointF worldP2, PointF localP1, PointF localP2)
+        {
+            // Convert to vectors
+            var w1 = Vector<double>.Build.Dense(new double[] { worldP1.X, worldP1.Y });
+            var w2 = Vector<double>.Build.Dense(new double[] { worldP2.X, worldP2.Y });
+            var l1 = Vector<double>.Build.Dense(new double[] { localP1.X, localP1.Y });
+            var l2 = Vector<double>.Build.Dense(new double[] { localP2.X, localP2.Y });
+
+            var w = w2 - w1;
+            var l = l2 - l1;
+
+            double normW = w.L2Norm();
+            double normL = l.L2Norm();
+
+            if (normW < 1e-9 || normL < 1e-9)
+            {
+                throw new ArgumentException("提供的点应当不重合且形成有效方向向量。");
+            }
+
+            // Compute rotation angle that maps local vector to world vector (no scaling)
+            double angleW = Math.Atan2(w[1], w[0]);
+            double angleL = Math.Atan2(l[1], l[0]);
+            double theta = angleW - angleL;
+
+            double cos = Math.Cos(theta);
+            double sin = Math.Sin(theta);
+
+            // Set basis vectors (unit vectors) in world coordinates corresponding to local axes
+            E1 = Vector<double>.Build.Dense(new double[] { cos, sin });
+            E2 = Vector<double>.Build.Dense(new double[] { -sin, cos });
+
+            // Rotation matrix (columns are basis vectors)
+            R = Matrix<double>.Build.DenseOfColumnVectors(E1, E2);
+            InvR = R.Inverse();
+
+            // Determine origin P1 (world coordinates of local origin)
+            // worldP1 = R * localP1 + P1  => P1 = worldP1 - R * localP1
+            P1 = w1 - R * l1;
+
+            // Compute translation matrix
+            T = Matrix<double>.Build.DenseIdentity(3);
+            T[0, 2] = -P1[0];
+            T[1, 2] = -P1[1];
+        }
+
         /// <summary>
         /// Word坐标系下的点转换成Local坐标系下的点
         /// </summary>