坐标转换的算法

    /// <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; }

        

    }

 

posted @ 2025-11-27 22:57  家煜宝宝  阅读(3)  评论(0)    收藏  举报