/// <summary>/// 坐标转换的算法 /// </summary>public class CoordinateTransHelper{//坐标系1是标准坐标系// 坐标系2相对于坐标系1MARK点距离差值的最大值public double Max_MarkDistanceDIF = 1;// 坐标系2相对于坐标系1MARK点距离差值public double MarkDistanceDIF = 0;// //计算坐标系2相对于坐标系1的旋转角,结果是弧度public double Crd2ToCrd1Angle = 0;/// <summary>/// 坐标转换方法/// </summary>/// <param name="Crd2Mark1">坐标系2的Mark1的点坐标</param>/// <param name="Crd2Mark2">坐标系2的Mark2的点坐标</param>/// <param name="Crd1Mark1">坐标系1的Mark1的点坐标</param>/// <param name="Crd1Mark2">坐标系1的Mark2的点坐标</param>/// <param name="InPoint"></param>/// <param name="OutPoint"></param>/// <returns></returns>public string GetCalcCoordCoordinate(Coord Crd2Mark1, Coord Crd2Mark2, Coord Crd1Mark1, Coord Crd1Mark2, Coord InPoint, out Coord OutPoint, double Max_MarkDistanceDI_Temp){//增加 未设置坐标系参数,前的防呆 if (IsSetCrdData == false){throw new Exception("请先设置坐标系参数,然后进行坐标转换");}OutPoint = new Coord();OutPoint.X = 0;OutPoint.Y = 0;try{string msg = string.Empty;// 第一:计算坐标系2相对于坐标系1的缩放系数double Crd2ToCrd1Zoom =Math.Sqrt(Math.Pow((Crd2Mark1.X - Crd2Mark2.X), 2) + Math.Pow((Crd2Mark1.Y - Crd2Mark2.Y), 2))/Math.Sqrt(Math.Pow((Crd1Mark1.X - Crd1Mark2.X), 2)+Math.Pow((Crd1Mark1.Y - Crd1Mark2.Y), 2));// Math.Pow(x, 2);//第二个//计算坐标系2相对于坐标系1MARK点距离差值MarkDistanceDIF = 0;MarkDistanceDIF =Math.Sqrt(Math.Pow((Crd2Mark1.X - Crd2Mark2.X), 2) + Math.Pow((Crd2Mark1.Y - Crd2Mark2.Y), 2))-Math.Sqrt(Math.Pow((Crd1Mark1.X - Crd1Mark2.X), 2) + Math.Pow((Crd1Mark1.Y - Crd1Mark2.Y), 2));if (Math.Abs(MarkDistanceDIF) > Math.Abs(Max_MarkDistanceDI_Temp)){throw new Exception($"坐标系2相对于坐标系1MARK点距离差值:{MarkDistanceDIF},大于限制值:{Max_MarkDistanceDI_Temp}");}//第三个double Crd1DertaX = Crd1Mark2.X - Crd1Mark1.X;double Crd1DertaY = Crd1Mark2.Y - Crd1Mark1.Y;double Crd2DertaX = Crd2Mark2.X - Crd2Mark1.X;double Crd2DertaY = Crd2Mark2.Y - Crd2Mark1.Y;//第四个double Crd1Angle = 0;//坐标系1的MARK点连成的直线指向第一象限if (Crd1DertaX > 0 && Crd1DertaY > 0){// K1PointTo1 := 1;Crd1Angle = Math.Abs(Math.Atan((Crd1Mark2.Y - Crd1Mark1.Y) / (Crd1Mark2.X - Crd1Mark1.X)));}else{// K1PointTo1 := 0; }//坐标系1的MARK点连成的直线指向第二象限if (Crd1DertaX < 0 && Crd1DertaY > 0){Crd1Angle = (180 * 3.1415926 / 180) - Math.Abs(Math.Atan((Crd1Mark2.Y - Crd1Mark1.Y) / (Crd1Mark2.X - Crd1Mark1.X)));}else{}//坐标系1的MARK点连成的直线指向第三象限if (Crd1DertaX < 0 && Crd1DertaY < 0){Crd1Angle = (180 * 3.1415926 / 180) + Math.Abs(Math.Atan((Crd1Mark2.Y - Crd1Mark1.Y) / (Crd1Mark2.X - Crd1Mark1.X)));}else{}//坐标系1的MARK点连成的直线指向第四象限if (Crd1DertaX > 0 && Crd1DertaY < 0){Crd1Angle = (360 * 3.1415926 / 180) - Math.Abs(Math.Atan((Crd1Mark2.Y - Crd1Mark1.Y) / (Crd1Mark2.X - Crd1Mark1.X)));}else{}//第五个double Crd2Angle = 0;//坐标系2的MARK点连成的直线指向第一象限if (Crd2DertaX > 0 && Crd2DertaY > 0){Crd2Angle = Math.Abs(Math.Atan((Crd2Mark2.Y - Crd2Mark1.Y) / (Crd2Mark2.X - Crd2Mark1.X)));}else{}//坐标系2的MARK点连成的直线指向第二象限if (Crd2DertaX < 0 && Crd2DertaY > 0){Crd2Angle = (180 * 3.1415926 / 180) - Math.Abs(Math.Atan((Crd2Mark2.Y - Crd2Mark1.Y) / (Crd2Mark2.X - Crd2Mark1.X)));}else{}//坐标系2的MARK点连成的直线指向第三象限if (Crd2DertaX < 0 && Crd2DertaY < 0){Crd2Angle = (180 * 3.1415926 / 180) + Math.Abs(Math.Atan((Crd2Mark2.Y - Crd2Mark1.Y) / (Crd2Mark2.X - Crd2Mark1.X)));}else{}//坐标系2的MARK点连成的直线指向第四象限if (Crd2DertaX > 0 && Crd2DertaY < 0){Crd2Angle = (360 * 3.1415926 / 180) - Math.Abs(Math.Atan((Crd2Mark2.Y - Crd2Mark1.Y) / (Crd2Mark2.X - Crd2Mark1.X)));}else{}//double Crd1Angle =0;//第六个if (Crd1DertaX > 0 && Crd1DertaY == 0){Crd1Angle = 0;}//坐标系1的MARK点连成的直线倾角是90度if (Crd1DertaX == 0 && Crd1DertaY > 0){Crd1Angle = (90 * 3.1415926 / 180);}//坐标系1的MARK点连成的直线倾角是180度if (Crd1DertaX < 0 && Crd1DertaY == 0){Crd1Angle = (180 * 3.1415926 / 180);}//坐标系1的MARK点连成的直线倾角是270度if (Crd1DertaX == 0 && Crd1DertaY < 0){Crd1Angle = (270 * 3.1415926 / 180);}//第七个//坐标系2的MARK点连成的直线倾角是0度if (Crd2DertaX > 0 && Crd2DertaY == 0){Crd2Angle = 0;}//坐标系2的MARK点连成的直线倾角是90度if (Crd2DertaX == 0 && Crd2DertaY > 0){Crd2Angle = (90 * 3.1415926 / 180);}//坐标系2的MARK点连成的直线倾角是180度if (Crd2DertaX < 0 && Crd2DertaY == 0){Crd2Angle = (180 * 3.1415926 / 180);}//坐标系2的MARK点连成的直线倾角是270度if (Crd2DertaX == 0 && Crd2DertaY < 0){Crd2Angle = (270 * 3.1415926 / 180);}//第八个//计算坐标系2相对于坐标系1的旋转角,结果是弧度Crd2ToCrd1Angle = Crd2Angle - Crd1Angle;//输出坐标计算OutPoint.X = ((InPoint.X - Crd1Mark1.X) * Math.Cos(Crd2ToCrd1Angle) - (InPoint.Y - Crd1Mark1.Y) * Math.Sin(Crd2ToCrd1Angle)) * Crd2ToCrd1Zoom + Crd2Mark1.X;OutPoint.Y = ((InPoint.X - Crd1Mark1.X) * Math.Sin(Crd2ToCrd1Angle) + (InPoint.Y - Crd1Mark1.Y) * Math.Cos(Crd2ToCrd1Angle)) * Crd2ToCrd1Zoom + Crd2Mark1.Y;return msg;}catch (Exception ex){string msg1 = "计算异常:" + ex.Message + ex.StackTrace;return msg1;//throw; }}public Coord Crd1Mark1 { get; set; } = new Coord();public Coord Crd1Mark2 { get; set; } = new Coord();public Coord Crd2Mark1 { get; set; } = new Coord();public Coord Crd2Mark2 { get; set; } = new Coord();public int MaxX_Difference { get; set; } = 5;public int MaxY_Difference { get; set; } = 5;/// <summary>/// 根据数据坐标经过坐标系转换后得出新的坐标 /// </summary>/// <param name="InPoint"></param>/// <returns></returns>public Coord GetCalcCoordCoordinate_Execute(Coord InPoint){Coord OutPoint = new Coord();string msg = GetCalcCoordCoordinate(Crd2Mark1, Crd2Mark2, Crd1Mark1, Crd1Mark2, InPoint, out OutPoint, Max_MarkDistanceDIF);if (msg != string.Empty){throw new Exception("计算坐标异常:" + msg);}//double DifferenceX = Math.Abs(InPoint.X - OutPoint.X);//double DifferenceY = Math.Abs(InPoint.Y - OutPoint.Y);//if (DifferenceX > MaxX_Difference || DifferenceY > MaxY_Difference)//{// string msg_tip = $"坐标转换后的值与前值相减的差值过大:前值:({InPoint.X},{InPoint.Y}),后值:({OutPoint.X},{OutPoint.Y}),X差值:{DifferenceX},Y差值:{DifferenceY}";// throw new Exception(msg_tip);//}return OutPoint;}/// <summary>/// 设置坐标系数据 /// </summary>/// <param name="Crd1Mark1_Temp">坐标系1的Mark1坐标</param>/// <param name="Crd1Mark2_Temp">坐标系1的Mark2坐标</param>/// <param name="Crd2Mark1_Temp">坐标系2的Mark1坐标</param>/// <param name="Crd2Mark2_Temp">坐标系2的Mark2坐标</param>public void SetCrdData( Coord Crd1Mark1_Temp, Coord Crd1Mark2_Temp,Coord Crd2Mark1_Temp, Coord Crd2Mark2_Temp){try{Crd1Mark1 = Crd1Mark1_Temp;Crd1Mark2 = Crd1Mark2_Temp;Crd2Mark1 = Crd2Mark1_Temp;Crd2Mark2 = Crd2Mark2_Temp;//设置完成后增加标志位IsSetCrdData = true;}catch (Exception ex){IsSetCrdData = false;throw new Exception("转换坐标设置数据异常:" + ex.Message+ex.StackTrace);}}//public void SetMaxDifference(int MaxX = 5, int MaxY = 5)//{// MaxX_Difference = MaxX;// MaxY_Difference = MaxY;//}/// <summary>/// 是否设置坐标系数据 /// </summary>public bool IsSetCrdData { get; set; }}