精华内容
下载资源
问答
  • 今天小编就为大家分享一篇Python求两个圆的交点坐标或三个圆的交点坐标方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 计算交点坐标

    2018-07-03 16:19:28
    计算两条相交的线交点坐标。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • c++求一个平面内,两条线段的交点坐标。传入四个坐标点,返回一个坐标点。
  • 一个专门用于提取CASS等高线交点坐标的程序,也可提取任意黄线交点坐标。自动输出文本文件。
  • 求2线段交点坐标.txt

    2019-10-22 20:03:33
    实现在二维坐标中,2条线段交点坐标算法。 形参为2条直线的起始与结束点坐标,返回一个坐标点。
  • c# 直线和椭圆弧的交点坐标算法

    千次阅读 2020-05-08 18:22:22
    在求直线和椭圆弧的交点坐标的时候,我们同样和我上一个求直线和圆弧交点坐标一样,先来分析一下,主要分为 第一步: 求直线和椭圆弧交点,我们可以先该圆弧对应的圆和圆的交点。 第二步:通过判断交点是否同时是存在...

    在求直线和椭圆弧的交点坐标的时候,我们同样和我上一个求直线和圆弧交点坐标一样,先来分析一下,主要分为
    第一步: 求直线和椭圆弧交点,我们可以先求直线和椭圆弧的交点。
    第二步:由于椭圆的可能是有角度的,椭圆圆心不在坐标轴的原点上,比如长轴不在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)
                            {
                                //表示第一次没有一个值
                                //将交点逆时针旋转
                                Vector2[] ve1 = Anticlockwise(ptInter1, ptInter2, centerZero, angle, false);
                                //再将交点平移得到最后真正的交点
                                ve1[1] = MoveTwo(ve1[1], center);
                                node[0] = ve1[1];
                            }
                        }
                    }
                    else if (version == 1)
                    {
                        JudgeDotQualified(centerZero, ptInter2, a, b, node);
                        if (node.Count == 2)
                        {
                            if (node[1] != null)
                            {
                                //表示第一次有一个值
                                //将交点逆时针旋转
                                Vector2[] ve1 = Anticlockwise(ptInter1, ptInter2, centerZero, angle, false);
                                //再将交点平移得到最后真正的交点
                                ve1[1] = MoveTwo(ve1[1], center);
                                node[1] = ve1[1];
                            }
                        }
                    }
                }
                ht.Add("node", node);
                return ht;
            }
       /// <summary>
            /// 角度转弧度
            /// </summary>
            /// <param name="angle">角度</param>
            /// <returns>弧度</returns>
            public static double DegreeToRadian(double angle)
            {
                return ((angle * System.Math.PI) / 180.0);
            }
            public const double EPSILON = 1E-12;
     public static bool IsEqual(double x, double y, double epsilon = EPSILON)
            {
                return IsEqualZero(x - y, epsilon);
            }
            public static bool IsEqualZero(double x, double epsilon = EPSILON)
            {
                return (System.Math.Abs(x) < epsilon);
            }
            /// <summary>
            /// 点的绕椭圆弧弧心旋转
            /// </summary>
            /// <param name="LineendPoint">线段终点</param>
            /// <param name="LinestartPoint">线段起点</param>
            /// <param name="center">椭圆弧弧心</param>
            /// <param name="angle">椭圆弧的导入角度'</param>
            /// /// <param name="isClockwise">顺逆旋转,默认为顺时针旋转</param>
            internal static Vector2[] Anticlockwise(Vector2 LineendPoint, Vector2 LinestartPoint, Vector2 center, double angle, bool isClockwise = true)
            {
                Vector2[] ve = new Vector2[2];
                if (isClockwise)
                {
                    angle = -angle;
                }
                double cos = System.Math.Cos(angle);
                double sin = System.Math.Sin(angle);
                if (IsEqual(cos, 0))
                {
                    cos = 0;
                }
                if (IsEqual(sin, 0))
                {
                    sin = 0;
                }
                double x = ((LineendPoint.x - center.x) * cos - (LineendPoint.y - center.y) * sin + center.x);
                double y = ((LineendPoint.x - center.x) * sin + (LineendPoint.y - center.y) * cos + center.y);
                ve[0].x = x;
                ve[0].y = y;
                double x1 = ((LinestartPoint.x - center.x) * cos - (LinestartPoint.y - center.y) * sin + center.x);
                double y1 = ((LinestartPoint.x - center.x) * sin + (LinestartPoint.y - center.y) * cos + center.y);
                ve[1].x = x1;
                ve[1].y = y1;
                return ve;
            }
            /// <summary>
            /// 第一次平移
            /// </summary>
            /// <param name="dot">交点坐标</param>
            /// <param name="center">圆心坐标</param>
            /// <returns>返回平移后的点坐标</returns>
            internal static Vector2 MoveOne(Vector2 dot, Vector2 center)
            {
                Vector2 returnDot = new Vector2();
                if (center.x >= 0 && center.y >= 0)
                {
                    //圆心在第一象限
                    returnDot.x = dot.x - center.x;
                    returnDot.y = dot.y - center.y;
                }
                else if (center.x <= 0 && center.y >= 0)
                {
                    //圆心在第二象限
                    returnDot.x = dot.x + center.x;
                    returnDot.y = dot.y - center.y;
                }
                else if (center.x <= 0 && center.y <= 0)
                {
                    //圆心在第三象限
                    returnDot.x = dot.x + center.x;
                    returnDot.y = dot.y + center.y;
                }
                else if (center.x >= 0 && center.y <= 0)
                {  //圆心在第四象限
                    returnDot.x = dot.x - center.x;
                    returnDot.y = dot.y + center.y;
                }
                return returnDot;
            }
            /// <summary>
            /// 第二次平移
            /// </summary>
            /// <param name="dot">点坐标</param>
            /// <param name="center">圆心坐标</param>
            /// <returns>返回平移后的点</returns>
            internal static Vector2 MoveTwo(Vector2 dot, Vector2 center)
            {
                Vector2 returnDot = new Vector2();
                if (center.x >= 0 && center.y >= 0)
                {
                    //圆心在第一象限
                    returnDot.x = dot.x + center.x;
                    returnDot.y = dot.y + center.y;
                }
                else if (center.x <= 0 && center.y >= 0)
                {
                    //圆心在第二象限
                    returnDot.x = dot.x - center.x;
                    returnDot.y = dot.y + center.y;
                }
                else if (center.x <= 0 && center.y <= 0)
                {
                    //圆心在第三象限
                    returnDot.x = dot.x - center.x;
                    returnDot.y = dot.y - center.y;
                }
                else if (center.x >= 0 && center.y <= 0)
                {  //圆心在第四象限
                    returnDot.x = dot.x + center.x;
                    returnDot.y = dot.y - center.y;
                }
                return returnDot;
            }
            /// <summary>
            /// 判断点是否为(0,0)
            /// </summary>
            /// <param name="dot">交点</param>
            /// <returns>是(0,0)返回false</returns>
            internal static bool Zero(Vector2 dot)
            {
                if (dot.x == 0)
                {
                    if (dot.y == 0)
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
                else
                {
                    return true;
                }
            }
            /// <summary>
            /// 规整化弧度
            /// 返回值范围:[0, 2*PI)
            /// </summary>
            internal static double NormalizeRadianAngle(double rad)
            {
                double value = rad % (2 * System.Math.PI);
                if (value < 0)
                    value += 2 * System.Math.PI;
                return value;
            }

    计算线段和椭圆的

     /// <summary>
            /// 计算线段和椭圆的交点
            /// </summary>
            /// <param name="LineendPoint">线段的终点</param>
            /// <param name="LinestartPoint">线段的起始点</param>
            /// <param name="maxAxis">长轴的长度的一半</param>
            /// <param name="minAxis">短轴的长度的一半</param>
            /// <param name="angle">椭圆弧的导入角度'</param>
            /// <param name="ptInter1">交点一</param>
            /// <param name="ptInter2">交点二</param>
            /// <returns>返回是否有交点</returns>
            internal static bool LineIntersectEllipse(Vector2 LineendPoint, Vector2 LinestartPoint, double maxAxis, double minAxis, ref Vector2 ptInter1, ref Vector2 ptInter2)
            {
                //直线方程为y=kx+b 求出k,c
                double k, c;
                k = (LineendPoint.y - LinestartPoint.y) / (LineendPoint.x - LinestartPoint.x);
                c = LinestartPoint.y - k * LinestartPoint.x;
                //maxAxis为x轴上的长轴 ,minAxis为y轴上的短轴
                //判断是否有交点
                double media = ((2 * maxAxis * maxAxis * k * c) * (2 * maxAxis * maxAxis * k * c) - 4 * (minAxis * minAxis + k * k * maxAxis * maxAxis) * maxAxis * maxAxis * (c * c - minAxis * minAxis));
                if (media > 0)
                {
                    //直线和椭圆有两个交点
                    ptInter1.x = (-2 * maxAxis * maxAxis * k * c + System.Math.Sqrt(media)) / (2 * (minAxis * minAxis + k * k * maxAxis * maxAxis));
                    ptInter1.y = k * ptInter1.x + c;
                    ptInter2.x = (-2 * maxAxis * maxAxis * k * c - System.Math.Sqrt(media)) / (2 * (minAxis * minAxis + k * k * maxAxis * maxAxis));
                    ptInter2.y = k * ptInter2.x + c;
                    return true;
                }
                else if (media == 0)
                {
                    //直线和椭圆只有一个交点
                    ptInter1.x = (-2 * maxAxis * maxAxis * k * c + System.Math.Sqrt(media)) / (2 * (minAxis * minAxis + k * k * maxAxis * maxAxis));
                    ptInter1.y = k * ptInter1.x + c;
                    return true;
                }
                else
                {
                    //直线和椭圆没有交点
                    return false;
                }
            }
    

    判断交点是否合格方法,也就是交点是否在椭圆弧上

    
            /// <summary>
            /// 判断交点是否合格方法
            /// </summary>
            /// <param name="vector">中心圆心</param>
            /// <param name="ptInter1">交点</param>
            /// <param name="startAngle">圆弧起始角度</param>
            /// <param name="endAngle">圆弧终止角度</param>
            /// <param name="node">存放交点集合</param>
            /// <param name="_direction">圆弧得顺逆,默认为逆时针</param>
            internal static void JudgeDotQualified(Vector2 vector, Vector2 ptInter1, double startAngle, double endAngle, List<Vector2> node, bool _direction = false)
            {
                if (!_direction)
                {
                    //画弧为逆时针
                    //得到一个交点对应的弧度
                    double radian = Tangent(vector, ptInter1);
                    if (startAngle > endAngle)
                    { //起始角度大于终止角度时,交点角度小于终止角度或者交点角度大于起始角度就会与圆弧相交
                        if (radian <= endAngle || radian >= startAngle)
                        {
                            node.Add(ptInter1);
                        }
                    }
                    else
                    { //起始角度小于终止角度时,交点角度在起始角度和终止角度之间就会与圆弧相交
                        if (startAngle < radian && radian < endAngle)
                        {
                            node.Add(ptInter1);
                        }
                        else if (startAngle == radian || endAngle == radian)
                        {
                            node.Add(ptInter1);
                        }
                    }
                }
                else
                {
                    //画弧为顺时针
                    //得到一个交点对应的弧度
                    double radian = MathUtils.Tangent(vector, ptInter1);
                    if (startAngle < endAngle)
                    { //起始角度小于终止角度时,交点角度大于终止角度或者交点角度小于起始角度就会与圆弧相交
                        if (radian <= startAngle || radian >= endAngle)
                        {
                            node.Add(ptInter1);
                        }
                    }
                    else
                    { //起始角度大于终止角度时,交点角度在终止角度和起始角度之间就会与圆弧相交
                        if (endAngle < radian && radian < startAngle)
                        {
                            node.Add(ptInter1);
                        }
                        else if (startAngle == radian || endAngle == radian)
                        {
                            node.Add(ptInter1);
                        }
                    }
                }
            }
            /// <summary>
            /// 利用正切值
            /// 计算交点对应的弧度
            /// </summary>
            /// <param name="vector">圆心坐标</param>
            /// <param name="intersect">交点坐标</param>
            /// <returns>弧度</returns>
            internal static double Tangent(Vector2 vector, Vector2 intersect)
            {
              double Y1 = vector.y;
                double X1 = vector.x;
                double Y2 = intersect.y;
                double X2 = intersect.x;
                double DegreeToRadian1 = System.Math.Atan2((Y2 - Y1), (X2 - X1)) * 180 / System.Math.PI;
                if (DegreeToRadian1 < 0)
                {
                    DegreeToRadian1 = 360 + DegreeToRadian1;
                }
                return DegreeToRadian(DegreeToRadian1);
                    }
                }
            }
            /// <summary>
            /// 正切值转弧度
            /// </summary>
            /// <returns>返回一个弧度</returns>
            public static double TangentToDegree(double tangent)
            {
                //得到正切值对应的弧度
                return System.Math.Atan(tangent);
            }

    总结: 由上面的分析可以看出,在分析第二步的时候,有点绕,但是你可以画图理解,再结合代码学习,会发现也不是很难,当然最后不要忘记,点赞,好评加关注哦。

    展开全文
  • 求两条直线的交点坐标

    千次阅读 2020-08-07 18:13:36
    业务中需要计算两条折线图的交点坐标,假设折线图仅有一个交点的情况,先求出x轴位置差最小(绝对值)的坐标,再分别拿前一个节点,求出坐标,如果没有求出,则取下一个节点进行计算 交点坐标方法(涉及求线段交点的...

    计算两条折线图的交点坐标,假设折线图仅有一个交点的情况,先求出x轴位置差最小(绝对值)的坐标,再分别拿前一个节点,求出坐标,如果没有求出,则取下一个节点进行计算

    交点坐标方法(涉及求线段交点的几何计算)
    参考:谈谈"求线段交点"的几种算法(js实现,完整版)

    /**
      * 顺序无关,ab,cd为线段
      * @param {*} a 线段ab起点坐标
      * @param {*} b 线段ab终点坐标
      * @param {*} c 线段cd起点坐标
      * @param {*} d 线段ab终点坐标
      */
     function segmentsIntr(a, b, c, d) {
       // 三角形abc 面积的2倍
       const area_abc = (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);
    
       // 三角形abd 面积的2倍
       const area_abd = (a.x - d.x) * (b.y - d.y) - (a.y - d.y) * (b.x - d.x);
    
       // 面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理(==0则对点));
       // 对点也当作相交则 > 0 即可
       if (area_abc * area_abd > 0) {
         return false;
       }
    
       // 三角形cda 面积的2倍
       const area_cda = (c.x - a.x) * (d.y - a.y) - (c.y - a.y) * (d.x - a.x);
       // 三角形cdb 面积的2倍
       // 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.
       const area_cdb = area_cda + area_abc - area_abd;
       if (area_cda * area_cdb > 0) {
         return false;
       }
    
       // 计算交点坐标
       const t = area_cda / (area_abd - area_abc);
       // eslint-disable-next-line one-var
       const dx = t * (b.x - a.x),
         dy = t * (b.y - a.y);
       // const x = Math.trunc(a.x + dx);
       const x = +(a.x + dx).toFixed(2);
       const y = +(a.y + dy).toFixed(2);
       return { x, y };
     }
    
    // 平行
    const a = { x: 10, y: 20 };
    const b = { x: 40, y: 20 };
    const c = { x: 10, y: 20 };
    const d = { x: 40, y: 40 };
    // 一个点相同
    const a1 = { x: 10, y: 20 };
    const b1 = { x: 40, y: 20 };
    const c1 = { x: 10, y: 20 };
    const d1 = { x: 40, y: 40 };
    // 没有点相同
    const a2 = { x: 10, y: 20 };
    const b2 = { x: 40, y: 40 };
    const c2 = { x: 10, y: 50 };
    const d2 = { x: 40, y: 30 };
    const test = segmentsIntr2(a1, b1, c1, d1);
    console.log(test);
    

    获取坐标的方法:

    const list1 = [
      { legend: '比较便宜', percent: 100, price: 50 },
      { legend: '比较便宜', percent: 100, price: 75 },
      { legend: '比较便宜', percent: 100, price: 100 },
      { legend: '比较便宜', percent: 83.33, price: 125 },
      { legend: '比较便宜', percent: 33.33, price: 150 },
      { legend: '比较便宜', percent: 16.67, price: 175 },
      { legend: '比较便宜', percent: 16.67, price: 200 },
      { legend: '比较便宜', percent: 16.67, price: 225 }
    ];
    const list2 = [
      { legend: '非常贵', percent: 0, price: 50 },
      { legend: '非常贵', percent: 0, price: 75 },
      { legend: '非常贵', percent: 0, price: 100 },
      { legend: '非常贵', percent: 16.67, price: 125 },
      { legend: '非常贵', percent: 50, price: 150 },
      { legend: '非常贵', percent: 66.67, price: 175 },
      { legend: '非常贵', percent: 66.67, price: 200 },
      { legend: '非常贵', percent: 100, price: 225 }
    ]
    function getCoordinate(list1, list2, type) {
      const arr = [];
      // const index = 0;
      list1.forEach((element, index) => {
        const value = Math.abs(element.percent - list2[index].percent);
        arr.push(value);
      });
      const min = Math.min(...arr);
      const index = arr.findIndex(item => item === min);
      const a = { x: list1[index].price, y: list1[index].percent };
      const b =
        type === 'prev'
          ? { x: list1[index - 1].price, y: list1[index - 1].percent }
          : { x: list1[index + 1].price, y: list1[index + 1].percent };
      const c = { x: list2[index].price, y: list2[index].percent };
      const d =
        type === 'prev'
          ? { x: list2[index - 1].price, y: list2[index - 1].percent }
          : { x: list2[index + 1].price, y: list2[index + 1].percent };
      // console.log(arr, index, min, a, b, c, d);
      return [a, b, c, d];
    }
    
    const abcdPrev = getCoordinate(list1, list2, 'prev');
    const abcdNext = getCoordinate(list1, list2, 'next');
    const p = segmentsIntr(...abcdPrev) || segmentsIntr(...abcdNext);
    
    console.log(abcdPrev, abcdNext, p);
    
    展开全文
  • 在直角坐标系求某点关于直线的对称点是初二数学的重要题型,本文就例题详细解析这类题型的解题思路,希望能给初二学生的数学学习带来帮助。例题如图,点A,B的坐标分别为(0,2),(3,4),P为x轴上的一点,若点B关于...

    在直角坐标系求某点关于直线的对称点是初二数学的重要题型,本文就例题详细解析这类题型的解题思路,希望能给初二学生的数学学习带来帮助。

    例题

    如图,点A,B的坐标分别为(0,2),(3,4),P为x轴上的一点,若点B关于直线AP的对称点B'恰好落在x轴上,求点P的坐标。

    f6f8593917dd671f97e6406ca1aebd5b.png

    解题过程:

    设点B'的坐标为(x1,0)

    根据题目中的条件:点B与点B'关于直线AP对称,B'(x1,0),B(3,4)则BB'连线与对称轴AP交点的纵坐标=(4+0)/2=2,交点的横坐标=(x1+3)/2;

    根据题目中的条件和结论:A(0,2),点A在对称轴上,BB'连线与对称轴AP交点的纵坐标=2,则点A即为BB'连线与对称轴AP的交点;

    根据题目中的条件和结论:A(0,2),BB'连线与对称轴交于点A,交点的横坐标=(x1+3)/2,则(x1+3)/2=0,可求得x1=-3,即点B'的坐标为(-3,0);

    连接BA并延长,与x轴交于点B',连接BP,过点B作BC⊥x轴于点C

    f4bd309fe972e2e6a822f069772d7925.png

    设BP=x

    根据轴对称性质和题目中的条件:成轴对称的点与对称轴上点的连线相等,BP=x,点B与点B'关于直线AP对称,则BP=B'P=x;

    根据题目中的条件:B(3,4),B'(-3,0),BC⊥x轴,则BC=4,OC=3,B'O=3;

    根据结论:OC=3,B'O=3,则B'C=B'O+OC=6;

    根据结论:B'P=x,B'C=6,则CP=B'C-B'P=6-x;

    根据勾股定理和结论:BC⊥x轴,CP=6-x,BP=x,BC=4,BP^2=CP^2+BC^2,则x^2=(6-x)^2+16,可求得x=13/3,即BP=13/3;

    根据结论:BP=B'P,BP=13/3,则B'P=13/3;

    根据结论:B'(-3,0),B'P=13/3,则点P的横坐标=-3+13/3=4/3;

    根据题目中的条件和结论:点P的横坐标=4/3,P为x轴上的一点,则点P的坐标为(4/3,0)。

    展开全文
  • 原来从事物探行业,经常遇到计算测线交点坐标的问题,根据已知的L1线两点(X1,Y1),(X11,Y11),和L2线上两点(x2,y2),(x22,y22)计算交点,在一般情况遇到,虽然通过解方程组便可得到,但对于我们使用较为频繁时,就显得...
  • java 获取两条经纬度线段的交点坐标工具类 网上有线段是否相交的判断方法,但是很少有获取线段交点的坐标的方法 我在这里整合了网上的一些相交的方法,通过相交的xy轴点返推出了经纬度。 使用方法可以按...

    java 获取两条经纬度线段的交点坐标工具类

    网上有线段是否相交的判断方法,但是很少有获取线段交点的坐标的方法
    我在这里整合了网上的一些相交的方法,通过相交的xy轴点返推出了经纬度。

    使用方法可以按GisCheckUtils类中main方法中的实例使用,如需要修改(如需要获取延长线上的交点
    修改getIntersectPoint()方法中加----的地方即可),查看代码中发注释修改代码即可。

    如果发现问题可以在下面留言讨论。

    一、获取两条经纬度线段的交点坐标工具类

    package cn.wys.utils;
    
    
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * @program: Wys
     * @description 获取两条经纬度线段的交点坐标工具类
     * @author: wys
     * @create: 2020-11-27 09:21
     **/
    public class GisCheckUtils {
        private static Logger log = LoggerFactory.getLogger(GisCheckUtils.class);
        /**
         * 地球周长
         */
        private static double L = 6381372 * Math.PI * 2;
        /**
         * 平面展开后,x轴等于周长
         */
        private static double W = L;
        /**
         * y轴约等于周长一半
         */
        private static double H = L / 2;
        /**
         * 米勒投影中的一个常数,范围大约在正负2.3之间
         */
        private static double mill = 2.3;
    
        public static void main(String[] args) {
            /* 拾取坐标系统 可直接复制坐标测试
            http://api.map.baidu.com/lbsapi/getpoint/index.html
             */
            //线段一
            SegmentLatLon segmentLatLonOne = new SegmentLatLon();
            segmentLatLonOne.setStartLatLon(new LatLon(116.393561, 39.940041));
            segmentLatLonOne.setEndLatLon(new LatLon(116.400172, 39.953704));
            //线段二
            SegmentLatLon segmentLatLonTwo = new SegmentLatLon();
            segmentLatLonTwo.setStartLatLon(new LatLon(116.37387, 39.946569));
            segmentLatLonTwo.setEndLatLon(new LatLon(116.402288,39.943856));
            //判断是否相交(延长线相交不算)
            boolean b = segIntersect(segmentLatLonOne, segmentLatLonTwo);
            log.info("判断是否相交: " + b);
            //交点坐标(延长线相交不算)
            LatLon intersectPoint = getIntersectPoint(segmentLatLonOne, segmentLatLonTwo);
            log.info("交点坐标:" + intersectPoint);
        }
    
    
        /**
         * 将经纬度转换成X和Y轴
         * 米勒投影算法
         *
         * @param lat 纬度
         * @param lon 经度
         * @return
         */
        private static Point millierConvertion(double lat, double lon) {
            // 将经度从度数转换为弧度
            double x = lon * Math.PI / 180;
            // 将纬度从度数转换为弧度
            double y = lat * Math.PI / 180;
            // 米勒投影的转换
            y = 1.25 * Math.log(Math.tan(0.25 * Math.PI + 0.4 * y));
            // 弧度转为实际距离
            x = (W / 2) + (W / (2 * Math.PI)) * x;
            y = (H / 2) - (H / (2 * mill)) * y;
            return new Point(x, y);
        }
    
        /**
         * xy轴转坐标
         *
         * @param x
         * @param y
         * @return 坐标点
         */
        private static LatLon xyToLatLon(double x, double y) {
            //实际距离 转为弧度
            x = (x - (W / 2)) / (W / (2 * Math.PI));
            y = -1 * (y - (H / 2)) / (H / (2 * mill));
            // 米勒投影的转换反转
            y = (Math.atan(Math.pow(Math.E, y / 1.25)) - 0.25 * Math.PI) / 0.4;
            //将经度从弧度转换为度数
            double lon = 180 / Math.PI * x;
            //将纬度从弧度转换为度数
            double lat = 180 / Math.PI * y;
            return new LatLon(lon, lat);
        }
    
    
        /**
         * 获取两条直线相交的点
         *
         * @param segmentLatLonOne 线段一
         * @param segmentLatLonTwo 线段二
         * @return 相交点坐标  为null 不相交
         */
        public static LatLon getIntersectPoint(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) {
            //先判断有没有相交 (延长线不算) 不相交返回null 相交执行获取交点坐标 (如需获取延长线交点注释此方法)----
            if (!segIntersect(segmentLatLonOne, segmentLatLonTwo)) {
                return null;
            }
            //----
    
            //转换对象
            Point[] points = segmentLatLonToPoint(segmentLatLonOne, segmentLatLonTwo);
            //获取两条直线相交的点
            Point latLon = getIntersectPoint(points[0], points[1], points[2], points[3]);
            if (latLon != null) {
                return xyToLatLon(latLon.x, latLon.y);
            }
            return null;
        }
    
    
        /**
         * 获取两条直线相交的点
         *
         * @param p1 线段一 开始点
         * @param p2 线段一 结束点
         * @param p3 线段二 开始点
         * @param p4 线段二 结束点
         * @return
         */
        public static Point getIntersectPoint(Point p1, Point p2, Point p3, Point p4) {
    
            double A1 = p1.getY() - p2.getY();
            double B1 = p2.getX() - p1.getX();
            double C1 = A1 * p1.getX() + B1 * p1.getY();
    
            double A2 = p3.getY() - p4.getY();
            double B2 = p4.getX() - p3.getX();
            double C2 = A2 * p3.getX() + B2 * p3.getY();
    
            double det_k = A1 * B2 - A2 * B1;
    
            if (Math.abs(det_k) < 0.00001) {
                return null;
            }
    
            double a = B2 / det_k;
            double b = -1 * B1 / det_k;
            double c = -1 * A2 / det_k;
            double d = A1 / det_k;
    
            double x = a * C1 + b * C2;
            double y = c * C1 + d * C2;
    
            return new Point(x, y);
        }
    
        /**
         * 验证两条线有没有相交
         *
         * @param segmentLatLonOne 线段1
         * @param segmentLatLonTwo 线段2
         * @return true 相交
         */
        public static boolean segIntersect(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) {
            //转换对象
            Point[] points = segmentLatLonToPoint(segmentLatLonOne, segmentLatLonTwo);
            //验证两条线有没有相交
            return segIntersect(points[0], points[1], points[2], points[3]) > 0;
    
        }
    
        /**
         * 线段转换为点对象
         *
         * @param segmentLatLonOne 线段一
         * @param segmentLatLonTwo 线段二
         * @return 点对象数组
         */
        private static Point[] segmentLatLonToPoint(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) {
            //线段1
            Double oneStartLat = segmentLatLonOne.getStartLatLon().getLat();
            Double oneStartLon = segmentLatLonOne.getStartLatLon().getLon();
            Double oneEndLat = segmentLatLonOne.getEndLatLon().getLat();
            Double oneEndLon = segmentLatLonOne.getEndLatLon().getLon();
            // 线段2
            Double twoStartLat = segmentLatLonTwo.getStartLatLon().getLat();
            Double twoStartLon = segmentLatLonTwo.getStartLatLon().getLon();
            Double twoEndLat = segmentLatLonTwo.getEndLatLon().getLat();
            Double twoEndLon = segmentLatLonTwo.getEndLatLon().getLon();
            Point[] points = new Point[4];
            //将经纬度转换成X和Y轴
            points[0] = millierConvertion(oneStartLat, oneStartLon);
            points[1] = millierConvertion(oneEndLat, oneEndLon);
            points[2] = millierConvertion(twoStartLat, twoStartLon);
            points[3] = millierConvertion(twoEndLat, twoEndLon);
    
            return points;
    
        }
    
        /**
         * 验证两条线有没有相交
         *
         * @param A 线段一 开始点
         * @param B 线段一 结束点
         * @param C 线段二 开始点
         * @param D 线段二 结束点
         * @return
         */
        public static int segIntersect(Point A, Point B, Point C, Point D) {
            Point intersection = new Point();
    
            if (Math.abs(B.getY() - A.getY()) + Math.abs(B.getX() - A.getX()) + Math.abs(D.getY() - C.getY())
                    + Math.abs(D.getX() - C.getX()) == 0) {
                if ((C.getX() - A.getX()) + (C.getY() - A.getY()) == 0) {
                    log.info("ABCD是同一个点!");
                } else {
                    log.info("AB是一个点,CD是一个点,且AC不同!");
                }
                return 0;
            }
    
            if (Math.abs(B.getY() - A.getY()) + Math.abs(B.getX() - A.getX()) == 0) {
                if ((A.getX() - D.getX()) * (C.getY() - D.getY()) - (A.getY() - D.getY()) * (C.getX() - D.getX()) == 0) {
                    log.info("A、B是一个点,且在CD线段上!");
                } else {
                    log.info("A、B是一个点,且不在CD线段上!");
                }
                return 0;
            }
            if (Math.abs(D.getY() - C.getY()) + Math.abs(D.getX() - C.getX()) == 0) {
                if ((D.getX() - B.getX()) * (A.getY() - B.getY()) - (D.getY() - B.getY()) * (A.getX() - B.getX()) == 0) {
                    log.info("C、D是一个点,且在AB线段上!");
                } else {
                    log.info("C、D是一个点,且不在AB线段上!");
                }
                return 0;
            }
    
            if ((B.getY() - A.getY()) * (C.getX() - D.getX()) - (B.getX() - A.getX()) * (C.getY() - D.getY()) == 0) {
                log.info("线段平行,无交点!");
                return 0;
            }
    
            intersection
                    .setX(((B.getX() - A.getX()) * (C.getX() - D.getX())
                            * (C.getY() - A.getY()) - C.getX()
                            * (B.getX() - A.getX()) * (C.getY() - D.getY()) + A
                            .getX() * (B.getY() - A.getY()) * (C.getX() - D.getX()))
                            / ((B.getY() - A.getY()) * (C.getX() - D.getX()) - (B
                            .getX() - A.getX()) * (C.getY() - D.getY())));
            intersection
                    .setY(((B.getY() - A.getY()) * (C.getY() - D.getY())
                            * (C.getX() - A.getX()) - C.getY()
                            * (B.getY() - A.getY()) * (C.getX() - D.getX()) + A
                            .getY() * (B.getX() - A.getX()) * (C.getY() - D.getY()))
                            / ((B.getX() - A.getX()) * (C.getY() - D.getY()) - (B
                            .getY() - A.getY()) * (C.getX() - D.getX())));
    
            if ((intersection.getX() - A.getX()) * (intersection.getX() - B.getX()) <= 0
                    && (intersection.getX() - C.getX())
                    * (intersection.getX() - D.getX()) <= 0
                    && (intersection.getY() - A.getY())
                    * (intersection.getY() - B.getY()) <= 0
                    && (intersection.getY() - C.getY())
                    * (intersection.getY() - D.getY()) <= 0) {
    
                if ((A.getX() == C.getX() && A.getY() == C.getY()) || (A.getX() == D.getX() && A.getY() == D.getY())
                        || (B.getX() == C.getX() && B.getY() == C.getY()) || (B.getX() == D.getX() && B.getY() == D.getY())) {
    
                    log.info("线段相交于端点上");
                    return 2;
                } else {
                    log.info("线段相交于点(" + intersection.getX() + ","
                            + intersection.getY() + ")!");
                    //相交
                    return 1;
                }
            } else {
                log.info("线段相交于虚交点(" + intersection.getX() + ","
                        + intersection.getY() + ")!");
                //相交但不在线段上
                return -1;
            }
        }
        /**
         * 点对象
         */
        public static class Point {
            private double x;
            private double y;
    
            public Point() {
            }
    
            public Point(double x, double y) {
                this.x = x;
                this.y = y;
            }
    
            @Override
            public String toString() {
                return  x  + ","+ y ;
            }
    
            public double getX() {
                return x;
            }
    
            public void setX(double x) {
                this.x = x;
            }
    
            public double getY() {
                return y;
            }
    
            public void setY(double y) {
                this.y = y;
            }
    
        }
    }
    
    
    

    二、线段坐标实体

    package cn.wys.core;
    
    /**
     * @program: Wys
     * @description 线段坐标实体
     * @author: wys
     * @create: 2020-11-27 10:44
     **/
    public class SegmentLatLon {
        /**
         * 开始点的坐标
         */
        private LatLon startLatLon;
        /**
         * 结束点的坐标
         */
        private LatLon endLatLon;
    
        public SegmentLatLon(LatLon startLatLon, LatLon endLatLon) {
            this.startLatLon = startLatLon;
            this.endLatLon = endLatLon;
        }
    
        public SegmentLatLon() {
        }
    
        public LatLon getStartLatLon() {
            return startLatLon;
        }
    
        public void setStartLatLon(LatLon startLatLon) {
            this.startLatLon = startLatLon;
        }
    
        public LatLon getEndLatLon() {
            return endLatLon;
        }
    
        public void setEndLatLon(LatLon endLatLon) {
            this.endLatLon = endLatLon;
        }
    }
    
    

    三、经纬度实体

    package cn.wys.core;
    
    /**
     * @program: Wys
     * @description 经纬度实体
     * @author: wys
     * @create: 2020-11-26 10:44
     **/
    public class LatLon {
    
        /**
         * 经度
         */
        private Double lon;
    
        /**
         * 纬度
         */
        private Double lat;
    
        public LatLon() {
        }
    
        public LatLon(Double lon, Double lat) {
            this.lon = lon;
            this.lat = lat;
        }
    
        public Double getLon() {
            return lon;
        }
    
        public void setLon(Double lon) {
            this.lon = lon;
        }
    
        public Double getLat() {
            return lat;
        }
    
        public void setLat(Double lat) {
            this.lat = lat;
        }
    
        @Override
        public String toString() {
            return lon +"," + lat ;
        }
    }
    
    

    对您有帮助的话点个赞吧,谢谢。

    展开全文
  • 1.已知四点坐标分别为A1(x,y),A2(x,y),B1(x,y),B2(x,y) ...则求四点对应的直线交点坐标求解方法如下: if A1(x)==A2(x) X= A1(x); k2=(B2(y)-B1(y))/(B2(x)-B1(x)); b2=B1(y)-k2.*B1(x); Y=k2.*X+b2;
  • 本资料主要是 LabVIEW的图形控件中游标与曲线的交点坐标显示 的源代码
  • 在求圆弧和圆弧的交点坐标的时候,我们同样和我上一个求直线和圆弧交点坐标一样,先来分析一下,主要分为 第一步: 求圆弧和圆弧交点,我们可以先该圆弧对应的圆和圆的交点。 第二步:通过判断交点是否同时是存在两个...
  • 作者:henu_wxj链接:...默认使用笛卡尔直角坐标系。计算点到线段的最近点。已知线段 ,点 ,求点Q到线段P1P2的 最近坐标。存在两种情况:1.情况一: && 时,直线 的方程为 ...
  • R语言求拟合函数图形的交点坐标 通过二分类无限逼近的方法获得的 代码如下: 1)四个曲线的数据结构 v_ac=log(vir_1) op_log=log(opp) test1=data.frame(v_ac1,op_log) v_ac=log(vir_2) op_log=log(opp) test2=data...
  • (2)根据导线点测设交点导线点的坐标交点的设计坐标,计算测设数据,用极坐标法,距离交会法或角度交设交点。如图11-3所示,根据导线点T5、T6和JD11三点的坐标,计算出导线边的方位角a56和T5至JD11的平距D和方位角a...
  • 已知两组数据,在EXCEL中求出两组数据的交点坐标
  • 直线的交点坐标与距离公式
  • 方法一仔细检查了,公式没啥问题,但在实践使用时发现当y1,y2相等时,k2是求不出来的,特殊情况没考虑,建议把最后求y的式子用圆的方程联立 问:大佬们,方法一的CF=EF*K2怎么得到的呀,看不懂啊 ...
  • 已知:两个圆相交,圆心坐标...求:两个圆的交点坐标 IDE:VS2019 三角定位法代码如下如下: (脚踏实地 仰望星空 若有疑问 创所欲言 互帮互助 共同进步) 数学推理过程动手画图即可明白。变量含义注释已标明。 ...
  • python求十字交点坐标

    千次阅读 2019-10-12 14:15:53
    cv2.HoughLines 使用函数cv2.HoughLines(),返回(ρ,θ),ρ的单位是像素,θ是弧度,三轴矩阵。 输入参数:第一个参数是二值化图像,进行霍夫变换之前要进行二值化或者canny边缘检测。第二第三个参数代表ρ和θ的...
  • (x3, y3, z3)、(x4, y4, z4),求它们的交点坐标? 已知线段1坐标:(7,6,7)、(1,4,5),线段2的坐标:(4,7,4)、(4,4,7)。 由于两条线段交点是唯一的,两条直线交点也是唯一的,所以,求解线段交点可以利用求解直线交点...
  • 求两线段交点坐标

    万次阅读 2018-09-22 21:59:24
    求两线段交点坐标 判断线段是否相交 求交点坐标 判断线段是否相交 a. 快速互斥实验 即线段的外接矩形相交,线段才会相交,以两条线段为对角线的矩形,如果不重合的话,那么两条线段一定不可能相交。看下图: 判断...
  • C# 求直线和圆弧的交点坐标

    千次阅读 2020-05-08 15:30:49
    在求直线和圆弧的交点时,我们先分析一下,主要分为两步。 第一步:先求出直线和圆的交点。 第二步: 判断交点是否在圆弧上。 下面开始展示代码,伸手党有福了,可能有些地方写的不好,望谅解,创作不易,喜欢给个...
  • 求解两圆相交的交点坐标

    万次阅读 2018-12-11 09:43:28
  • 求取两条直线的交点坐标

    千次阅读 2018-08-31 12:35:45
    Opencv学习笔记—–求取两条直线的交点坐标 #include &amp;amp;lt;opencv2\highgui\highgui.hpp&amp;amp;gt; #include &amp;amp;lt;opencv2\opencv.hpp&amp;amp;gt; using namespace std; using ...
  • 2.输入一个直线的斜率k,及与直线与y轴交点坐标(0,b) (要考虑k存不存的情况) y=kx+b 斜切式 k有不存在的情况 输入一直线 ax+by+c=0,中的啊a,b,c的值 (一般式) 判断园与直线的位置关系 若直线与圆存在交点,求...
  • 本期将介绍使用OpenCV用两种不同的方法实现快速查找计算直线/网格线交点坐标。 直线交点计算思路与常用方法 直线交点的计算这里列举几个比较常用的方法: ① 在知道直线方程的前提下(或知道直线上一点和直线角度)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,718
精华内容 10,287
关键字:

交点坐标