|
|
@@ -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>
|