c# 直线和椭圆弧的交点坐标算法

本文介绍了如何计算直线与椭圆弧的交点坐标,首先通过旋转和平移椭圆使其长轴对准X轴且圆心位于原点,然后求解直线与简化椭圆的交点,再反向移动得到实际交点。最后通过判断交点是否在椭圆弧上来确定有效交点。
摘要由CSDN通过智能技术生成

在求直线和椭圆弧的交点坐标的时候,我们同样和我上一个求直线和圆弧交点坐标一样,先来分析一下,主要分为
第一步: 求直线和椭圆弧交点,我们可以先求直线和椭圆弧的交点。
第二步:由于椭圆的可能是有角度的,椭圆圆心不在坐标轴的原点上,比如长轴不在X轴上,也不在Y轴上,这样的椭圆就是有角度的椭圆,这样的椭圆我们不好进行计算。对此,我们需要将圆弧旋转,然后再平移,使长轴在X轴上,是椭圆圆心在原点上,但是你会发现这样操作椭圆还是比较麻烦,因此,我们可以操作直线,想象椭圆圆心已经移动到了原点,因为移动椭圆只需要移动椭圆圆心就好,这样我们也根据移动椭圆圆心一样的步伐移动直线,然后求直线和假设移动后的椭圆的交点,然后根据椭圆圆心一样的步伐反向移动回去,得到的点就是直线和有角度的椭圆交点。(有点绕,可以画图理解哦)
第三步:最终通过判断交点是否在椭圆弧上。

下面开始展示代码,伸手党有福了,可能有些地方写的不好,望谅解,创作不易,喜欢给个好评吧。

主干
  /// <summary>
        /// 线段和椭圆弧的交点
        /// </summary>
        /// <param name="line">线段对象</param>
        /// <param name="ht">存储交点和error信息</param>
        /// <returns>返回交点和error信息</returns>
        internal static Hashtable LineIntersectEllipticArc(Line line, Hashtable ht)
        {
   
            //线段的终点
            Vector2 LineendPoint = line.endPoint;
            //线段的起点
            Vector2 LinestartPoint = line.startPoint;
            //椭圆弧的长轴的一半
            double maxAxis = 262.39051820125013 / 2;
            //椭圆弧的短轴一半
            double minAxis = 135.76528231694766 / 2;
            //椭圆弧的起点
            //椭圆弧的起始角度 
            double startAngle = DegreeToRadian(132.0438345714015);
            //椭圆弧的终点
            //椭圆弧的终止角度 //默认设置为90度对应的弧度
            double endAngle = DegreeToRadian(258.13766538237763);
            //椭圆弧的圆心
            Vector2 center = new Vector2(17.7894639270817, 15.0254309579905);
            //设置原点坐标(0,0)
            Vector2 centerZero = new Vector2(0, 0);
            //椭圆弧的导入角度'
            double angle = DegreeToRadian(191.75357833501226);
            //将直线顺时针旋转angle度
            Vector2[] ve = Anticlockwise(LineendPoint, LinestartPoint, center, angle);
            //假设默认交点坐标
            Vector2 ptInter1 = new Vector2(0, 0);
            Vector2 ptInter2 = new Vector2(0, 0);
            //直线和椭圆的交点坐标
            LineIntersectEllipse(MoveOne(ve[0], center), MoveOne(ve[1], center), maxAxis, minAxis, ref ptInter1, ref ptInter2);
            //用于存储交点
            List<Vector2> node = new List<Vector2>();
            //用于判断是否有交点
            bool judgeNode = false;
            //存储的版本号
            int version = 0;
            double a = NormalizeRadianAngle(startAngle);
            double b = NormalizeRadianAngle(endAngle);
            if (Zero(ptInter1))
            {
   
                JudgeDotQualified(centerZero, ptInter1, a, b, node);
                if (node.Count == 1)
                {
   
                    if (node[0] != null)
                    {
   
                        //表示第一次有一个值
                        //将交点逆时针旋转
                        Vector2[] ve1 = Anticlockwise(ptInter1, ptInter2, centerZero, angle, false);
                        //再将交点平移得到最后真正的交点
                        ve1[0] = MoveTwo(ve1[0], center);
                        node[0] = ve1[0];
                        version = 1;
                    }
                }
            }
            if (Zero(ptInter2))
            {
   
                if (version == 0)
                {
   
                    JudgeDotQualified(centerZero, ptInter2, a, b, node);
                    if (node.Count == 1)
                    {
   
                        if (node[0] != null)
                        {
   
                            //表示第一次没有一个值
                            //将交点逆时针旋转
          
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值