这里是算法的数学思想:

http://mathworld.wolfram.com/Circle-CircleIntersection.html

其实懂了之后发现也很简单,中文概况是这样:

1 计算两个圆心之间的距离L
2 如果 L>r1+r2 无交点
3 如果 l = r1 + r2 则一个交点, 用圆心的坐标可以计算出具体点
4 假定 两个交点的连线和圆心连线的交点是D,D到第一个圆心的距离是d, 则
   d*d + y*y = r1*r1
   (l-d)*(l-d) + y*y = r2 * r2
   其中y就是两交点连线距离的一半了
   合并一下可得到:
   r2*r2 - r1*r1 = l*l - 2dl
   d = (l*l - r2*r2 + r1*r1) / 2l
5 根据前面的公式,还可以确定出来 y的数值
6 y = sqrt(r1*r1-d*d)

 1 /// <summary>
 2 /// 判断两个平行于x轴的圆的交点
 3 /// </summary>
 4 /// <param name="centerA">第一个圆的中点</param>
 5 /// <param name="rA">半径</param>
 6 /// <param name="centerB">第二个圆的中点</param>
 7 /// <param name="rB">半径</param>
 8 /// <param name="ptInter1">交点1(若不存在返回65536)</param>
 9 /// <param name="ptInter2">交点1(若不存在返回65536)</param>
10 public static void CircleInterCircleOnXAxis(PointF centerA, double rA, PointF centerB, double rB, ref PointF ptInter1, ref PointF ptInter2)
11 {
12     ptInter1.X = ptInter2.X = 65536.0f;
13     ptInter1.Y = ptInter2.Y = 65536.0f;
14     PointF centerLeft;
15     double R, r, d;
16     if (centerA.X < centerB.X)
17     {
18         centerLeft = centerA;
19         R = rA;
20         r = rB;
21         d = centerB.X - centerA.X;
22     }
23     else
24     {
25         centerLeft = centerB;
26         R = rB;
27         r = rA;
28         d = centerA.X - centerB.X;
29     }
30     double R2 = R * R;
31     double x = (d*d - r*r + R2)/(2*d);
32     double y = Math.Sqrt(R2 - x * x);
33     ptInter1.X = centerLeft.X + (int)x;
34     ptInter1.Y = centerLeft.Y + (int)y;
35     ptInter2.X = centerLeft.X + (int)x;
36     ptInter2.Y = centerLeft.Y - (int)y;
37 }

当然上面说的方法需要两个圆平行于x轴,否则说不通。在数学计算上其实经常有这样的现象,就是变换坐标轴位置和方向,使计算简单。所以,这里思来想去需要另外一个工具函数来帮忙。

以某个点为中心点逆时针旋转Angle角度:(代码是网上找的)

 1 /// <summary>
 2 /// 以中心点逆时针旋转Angle角度
 3 /// </summary>
 4 /// <param name="center">中心点</param>
 5 /// <param name="p1">待旋转的点</param>
 6 /// <param name="angle">旋转角度(弧度)</param>
 7 public static PointF PointRotate(PointF center, PointF p1, double angle)
 8 {
 9     double x1 = (p1.X - center.X) * Math.Cos(angle) + (p1.Y - center.Y) * Math.Sin(angle) + center.X;
10     double y1 = -(p1.X - center.X) * Math.Sin(angle) + (p1.Y - center.Y) * Math.Cos(angle) + center.Y;
11     return new PointF((float)x1, (float)y1);
12 }

思路就是,通过将两个圆的其中一个旋转到和另一个平行,计算出交点,再把交点反向旋转回来

所以这里就需要计算两个向量夹角的函数

 1 /// <summary>
 2 /// 计算两个向量的夹角
 3 /// </summary>
 4 /// <param name="Va"></param>
 5 /// <param name="Vb"></param>
 6 /// <returns></returns>
 7 public static double GetAngleOfVectors(PointF Va, PointF Vb)
 8 {
 9     double da = Math.Sqrt(Va.X*Va.X + Va.Y*Va.Y);
10     double db = Math.Sqrt(Vb.X*Vb.X + Vb.Y*Vb.Y);
11     double theta = Math.Acos((Va.X*Vb.X + Va.Y*Vb.Y)/(da*db));
12     return theta;
13 }

全部的代码我就不贴了,一方面是写的搓,一方面是希望各位自己也动动脑。哈

以上代码已经经过简单测试

好吧,还是贴出来好了:

/// <summary>
///     求任意两个圆的交点
/// </summary>
/// <param name="centerA">第一个圆的中点</param>
/// <param name="rA">半径</param>
/// <param name="centerB">第二个圆的中点</param>
/// <param name="rB">半径</param>
/// <param name="ptInter1">交点1(若不存在返回65536)</param>
/// <param name="ptInter2">交点1(若不存在返回65536)</param>
public static void CircleInterCircle(PointF centerA, double rA, PointF centerB, double rB, ref PointF ptInter1,ref PointF ptInter2)
{var v = new PointF(centerB.X - centerA.X, centerB.Y - centerA.Y);double angle = GetAngleWithXAxis(v);PointF bb = PointRotate(centerA, centerB, angle);PointF p1 = Point.Empty, p2 = Point.Empty;CircleInterCircleOnXAxis(centerA, rA, bb, rB, ref p1, ref p2);if (!Equal(p1.X, 65536.0f)){p1 = PointRotate(centerA, p1, -angle);}if (!Equal(p2.X, 65536.0f)){p2 = PointRotate(centerA, p2, -angle);}ptInter1 = p1;ptInter2 = p2;
}

转载于:https://www.cnblogs.com/william7neral/p/4182398.html

计算任意两个圆的交点相关推荐

  1. python求交点坐标_Python求两个圆的交点坐标或三个圆的交点坐标方法

    计算两个圆的交点 代码如下: # -*- coding: utf-8 -*- import math import numpy as np def insec(p1,r1,p2,r2): x = p1 ...

  2. Python求两个圆的交点坐标或三个圆的交点坐标

    计算两个圆的交点代码如下 # -*- coding: utf-8 -*- import math import numpy as np def insec(p1,r1,p2,r2):x = p1[0] ...

  3. T-SQL 2 Tips: 1.计算任意两日期之间的周一到周日分别各有几个! 2.根据出生日期计算精确年龄!...

    这两个小技巧,不写不知道,一写吓一跳! 都是看似简单,实际做起来就懵,得仔细想一想,才能写对! 凡是有日期运算的程序都要细心哦! 先说第二个: 2.根据出生日期精确计算年龄!   所谓计算精确年龄就是 ...

  4. js编写一个函数,计算任意两个数字之间所能组成的奇数个数,数字必须是个位数。...

    编写一个函数,计算任意两个数字之间所能组成的奇数个数,数字必须是个位数. <body><input type="text" id="txt"& ...

  5. Python 计算任意两向量之间的夹角

    如图所示,我们要计算任意两个向量之间的夹角. (图中的坐标数字是估计值,随手给定) python代码如下 import math AB = [1,-3,5,-1] CD = [4,1,4.5,4.5] ...

  6. 练习题记录:求解距离矩阵,首先生成一百个二维坐标点,计算任意两个坐标点的距离

    碰到一道练习题:求解距离矩阵,首先生成一百个二维坐标点,计算任意两个坐标点的距离.我一开始看到这题目是一脸懵逼,然后上网找了一下,更是二脸懵逼.生成一百个二维坐标点,我首先就是想去生成一个1010的二 ...

  7. 两个向量之间的夹角公式_Python 计算任意两向量之间的夹角方法

    如图所示,我们要计算任意两个向量之间的夹角. (图中的坐标数字是估计值,随手给定) python代码如下 import math AB = [1,-3,5,-1] CD = [4,1,4.5,4.5] ...

  8. js 编写一个函数,计算任意两个数字之间所能组成的奇数个数

    <!DOCTYPE html> <html> <head><title></title> </head> <body> ...

  9. Java 计算任意两天之间相隔的天数

    在学习了Java中的Date类相关的方法之后,我试着自己写了小程序可以计算任意两天之间相隔的天数,挺好用的. 设计思路: 运用Date类中提供的getTime()方法,获取输入的日期与1990-01- ...

最新文章

  1. coordinatorlayout 设置不可滑动_滑动关闭App损害iPhone电池寿命,我们需要“改掉强迫症”吗?...
  2. 百度html删除,百度地图-删除默认版权信息
  3. urlrewrite伪静态 及多参数传递-附正则表达式语法 [轉]
  4. ariel字体_播客第58集:软件开发人员和freeCodeCamp超级巨星Ariel Leslie
  5. 同一个页面提交多个form表单方法(详细)
  6. 今日恐慌与贪婪指数为77 贪婪程度有所缓解
  7. py库: GUI(tkinter)
  8. 两台设备有三条链路,请问如何添加?
  9. GarsiaWachs算法:石子归并问题
  10. Facebook开源MySQL分支获大佬捧场
  11. Androrid Studio Debug Warning:debug info can be unavailable
  12. flask服务器获取多个文件,python - OkHttp将带有名称的多个文件上传到Python Flask服务器 - 堆栈内存溢出...
  13. 使用Seam Framework + JBoss 5.0 开发第一个Web应用 - 简单投票程序
  14. task文件服务器无法反弹,手把手带你玩转NAS 篇二十一:小米Redmi AC2100路由器刷机padavan保姆级教程...
  15. Vi编辑器基本常用命令
  16. 我的世界服务器怎么开启坐标显示,坐标 - Minecraft Wiki,最详细的官方我的世界百科...
  17. cv2.imshow无法显示图像
  18. HTTP:网络请求状态码204、304
  19. crop图片后,同时修改物体相应的坐标
  20. maven仓库已经存在jar包但是还是显示引入错误/失败

热门文章

  1. session很快失效_深夜,我偷听到程序员要对session下手……
  2. 属于微型计算机主要性能指示,2014年兰大入学测试题--计算机基础
  3. linux内核烧制,手机烧录自己编译的linux kernel
  4. python3程序运行中会跳过注释行_[python] 去除代码源文件中单行注释
  5. 笔记本电脑电池怎么拆_笔记本电脑光驱位置加装机械硬盘,应该知道的事
  6. 反卷积(Deconvolution)、上采样(UNSampling)与上池化(UnPooling)加入自己的思考(tensorflow函数)(一)
  7. pytorch: 自定义数据集加载
  8. 2021.5.23 中国高速列车运维技术讲座
  9. 关于Extjs gridpanel设置autoHeight:true时,横向滚动条的问题
  10. 技术剖析 | Axonius为什么能获得 2019 RSAC创新大奖 1