给定两个点和半径找到圆心
Posted
技术标签:
【中文标题】给定两个点和半径找到圆心【英文标题】:Finding center of a circle given two points and radius 【发布时间】:2016-03-24 22:38:50 【问题描述】:我正在编写一个 G 代码解释器,当给定圆上的两个点 (X, Y) 和半径时,我很难确定圆的中心。当给定中心硬币时,我可以从 2 个点绘制一个圆,但如果给定半径值,我不能将它用于中心点。
我查找了多个以不同数学形式(微积分、几何、三角函数等)编写的示例,但无法将其中任何一个转换为代码。我的理解是给定的值会产生两个不同的中心/相交点。这些都是我需要弄清楚的。
解释器在 Arduino 上运行并用 C 语言编写。如果有人可以用伪代码引导我完成它,我将非常感激。
谢谢!
【问题讨论】:
一个以两点为半径的圆有两种解。 检查this 答案,但不要只使用sqrt,而是使用Math.Sqrt。 【参考方案1】:给定圆方程和中点方程:
q = sqrt((x2-x1)^2 + (y2-y1)^2)
y3 = (y1+y2)/2
x3 = (x1+x2)/2
一个答案是:
x = x3 + sqrt(r^2-(q/2)^2)*(y1-y2)/q
y = y3 + sqrt(r^2-(q/2)^2)*(x2-x1)/q
另一个是:
x = x3 - sqrt(r^2-(q/2)^2)*(y1-y2)/q
y = y3 - sqrt(r^2-(q/2)^2)*(x2-x1)/q
假设点的变量已经被声明,你的代码应该是这样的:
double q = Math.Sqrt(Math.Pow((x2-x1),2) + Math.Pow((y2-y1),2));
double y3 = (y1+y2)/2;
double x3 = (x1+x2)/2;
double basex = Math.Sqrt(Math.Pow(r,2)-Math.Pow((q/2),2))*(y1-y2)/q; //calculate once
double basey = Math.Sqrt(Math.Pow(r,2)-Math.Pow((q/2),2))*(x2-x1)/q; //calculate once
double centerx1 = x3 + basex; //center x of circle 1
double centery1 = y3 + basey; //center y of circle 1
double centerx2 = x3 - basex; //center x of circle 2
double centery2 = y3 - basey; //center y of circle 2
来源:http://mathforum.org/library/drmath/view/53027.html
【讨论】:
我会在几个小时内拿出一个 c# 版本。 感谢克里斯的回复。我必须非常局限于线性思维方式。当 X3 和 Y3 在等式的右侧时,我很难求解它们。 我试着把它全部放在一个方程简化器(wolfram)中,看看它是否看起来更好。拆分方程可能是我所做的最好的事情。我会将方程的 c# 版本放在我的答案中 太完美了。我完全可以理解!谢谢!【参考方案2】:在 C# 中:
private double CenterX(double x1,double y1, double x2, double y2,double radius)
double radsq = radius * radius;
double q = Math.Sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
double x3 = (x1 + x2) / 2;
return x3 + Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((y1 - y2) / q);
private double CenterY(double x1, double y1, double x2, double y2, double radius)
double radsq = radius * radius;
double q = Math.Sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
double y3 = (y1 + y2) / 2;
return y3 + Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((x2-x1) / q);
【讨论】:
【参考方案3】:你不一定总能找到一个唯一的中心点,给出两个点和一个半径。实际上有三种不同的情况:
案例一:
当给定直径小于给定点之间的距离时发生。在这种情况下,没有解决方案。
案例2:
当给定的直径完全等于两点之间的距离时发生。在这种情况下,有一个简单的解决方案
案例 3:
当给定的直径大于两点之间的距离时发生。在这种情况下,方程有两个解:
您可以从 this page 中找到解决方案:
其中q
是两点之间的距离,[x3, y3]
是中间点。
在this Gist 中,我正在尝试在 C 中实现这些,但尚未完成。随意从我离开的地方继续。
【讨论】:
【参考方案4】:这是相同代码的 ruby 版本,如果有人需要它,(感谢 rookie1024 的 C# 代码)
def chord
@chord ||= begin
a = (point_1.x.to_f - point_2.x.to_f).abs ** 2
b = (point_1.y.to_f - point_2.y.to_f).abs ** 2
Math.sqrt(a + b)
end
end
def radius
@radius ||= begin
s = (chord / 2) * bulge
((chord/2) ** 2 + (s ** 2))/(2*s)
end.to_f
end
def center
x1 = point_1.x
y1 = point_1.y
x2 = point_2.x
y2 = point_2.y
x3 = (x1+x2)/2
y3 = (y1+y2)/2
basex = Math.sqrt((radius ** 2) - ((chord/2) ** 2)) * (y1-y2)/chord
basey = Math.sqrt((radius ** 2) - ((chord/2) ** 2)) * (x2-x1)/chord
centerx1 = x3 + basex
centery1 = y3 + basey
centerx2 = x3 - basex
centery2 = y3 - basey
bulge > 0 ? [centerx1, centery1] : [centerx2, centery2]
end
【讨论】:
以上是关于给定两个点和半径找到圆心的主要内容,如果未能解决你的问题,请参考以下文章
给定一个图像,一个像素点和一个以像素为单位的半径。如何找到它创建的圆形边框的像素坐标
LightOJ 1366 - Pair of Touching Circles (在矩形中只需要两个圆相外切,有多少种) 半径圆心均为整数)
1)定义一个Point类,其属性包括点的坐标,提供计算两点之间距离的方法; 2)定义一个圆形类,其属性包括圆心和半径; 3)创建两个圆形对象,提示用户输入圆心坐标和半径,判断两个圆是否相交,并输出结果