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

       /// <summary>  
        /// 根据余弦定理求两个线段夹角,单位:
        /// </summary>  
        /// <param name="(x1,y1)">端点</param>  
        /// <param name="(x2,y2)">start点</param>  
        /// <param name="(x3,y3)">end点</param>  
        /// <returns></returns>  
        /// 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度?




  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值