由余弦定理,求两个线段的夹角

       ///   
        /// 根据余弦定理求两个线段夹角,单位:
        ///   
        /// 端点  
        /// start点  
        /// end点  
        ///   
        /// remark: cos(fi) = (a * a + b * b - c * c) / (2ab),经过公式化简:
        /// cos(fi) = (dx21 * dx31 + dy21 * dy31)/(sqrt(dx12 * dx12 + dy12 * dy12) * sqrt(dx13 * dx13 + dy13 * dy13))

        public static double Angle(float x1, float y1, float x2, float y2, float x3, float y3)
        {


            double cosfi;
            double fi;
            double Degree;

            double dX21 = x2 - x1;
            double dY21 = y2 - y1;
            double dX31 = x3 - x1;
            double dY31 = y3 - y1;

            double numerator = dX21 * dX31 + dY21 * dY31;                         // 分子 
            double denominator = Math.Sqrt((dX21 * dX21 + dY21 * dY21) * (dX31 * dX31 + dY31 * dY31));   // 分母

            if (denominator == 0)   // 余弦定理,分母为零的情况,对应角度为0度或180度
            {
                Degree = 0;
            }
            else                    // 分母不为零,使用反余弦函数计算角度
            {
                cosfi = numerator / denominator;   // cos(fi) 范围为:[-1, 1]
                fi = Math.Acos(cosfi);             // Acos(x) 范围为:[pi, 0] 
                if (dY31 >= 0)                      // 处于第1、2象限,返回一个0~180的角度
                {
                    Degree = 180 * (fi / Math.PI);
                }
                else                              // 处于第3、4象限,返回一个180~360的角度
                {
                    Degree = 360 - 180 * (fi / Math.PI);

                }
            }

            return Degree;

        }


 在网上找了一些函数代码,不过都似乎有一些bug。这个自己动手改进了一下,条理梳理了一下,初步验证,暂未发现bug。不过有一点比较模糊,三点重合或三点中有两点重合,应该算作0度?180度?




你可能感兴趣的:(C#)