给定圆的起点,终点和中心点,找到圆弧的中点

4
我需要一些关于如何找到弧中点的帮助。 我有起点和终点、圆心以及半径。 我在网上搜索了很多地方,但找不到任何可转换为代码的答案。 如果有人有任何想法,请告诉我。下图是我试图找到的内容(假设已经找到了圆的中心)。

2
这个公式似乎很简单,可以轻松实现。 - Paul Phillips
所有的值都是正数,这个假设是安全的吗? - Kevin DiTraglia
1
一如既往。你到目前为止想出了什么?圆和圆半径是什么意思?如果可以的话,请提供一张图片。 - r4.
如果给定起点和终点,如何确定它是更大的弧还是更小的弧?(它可以朝任何方向走) - Kevin DiTraglia
这也是我一直在努力解决的问题。获取起始/结束角度是否有帮助?我有这些数据,但我不愿使用它们,因为我使用了很多奇怪的计算来使弧线能够在两个方向上绘制。 - Just Ask
显示剩余2条评论
3个回答

2

使用x1,x2的平均值和y1,y2的平均值来计算Atan2()函数,可以得到中点的角度。因此,在弧线上找到中点的方法如下:

double c=Math.Atan2(y1+y2, x1+x2);
double x_mid=R*Math.Cos(c);
double y_mid=R*Math.Sin(c);

请注意,我从Atan2的两个参数中都删除了1/2的因子(用于均值),因为这并不会改变角度。
更新:该方法总是会在周长上两点之间的最短弧线上找到中点。这可能是您需要的,也可能不是。

Johan,这个给你中点吗?我得到了错误的结果。谢谢。 - Robert Smith
它声称它是正确的。你能否发布示例值以及你如何得出它是错误的结论? - Johan Lundberg

0

获取终点。

(x1, y1), (x2, y2)

将它们关于圆心归一化。然后转换为极坐标。

(r, theta1), (r, theta2)

圆弧的半径将相同。 圆弧的中心是

(r, (theta2 + theta1) / 2)

将坐标转换为笛卡尔坐标并加上中心坐标。

编辑:类似于这样:

def Point CenterOfArc(Point start, end, center)
    let (x1, y1) = (start.x - center.x, start.y - center.y)
    let (x2, y2) = (end.x   - center.x, end.y   - center.y)

    let (r1, theta1) = (sqrt(x1^2 + y1^2), atan(y1/x1))
    let (r2, theta2) = (sqrt(x2^2 + y2^2), atan(y2/x2))
    if (theta1 > theta2) theta2 += 2 * pi

    let (r, theta) = ((r1 + r2) / 2, (theta1 + theta2) / 2) // averaging in case of rounding error

    let (x, y) = (r * cos(theta), r * sin(theta))

    return (x + center.x, y + center.y)
end

编辑2:当你转换为极坐标时,需要确保theta2>theta1,否则就像弧线是向后的。

编辑3:此外,tan<sup>-1</sup>(y/x)是正确的操作,但对于许多语言,您应该将其称为atan2(y, x)而不是atan(y/x)atan2是为此用途设计的,并且在x=0时避免错误并可能提供更准确的结果。


1
应该是theta1和theta2的平均值,而不是差值。 - Johan Lundberg
这段代码有时候可以工作,但我认为可能是因为我计算角度和绘制弧线的方式不对。我会进行更多实验,当我确定是我的问题时,我会将其标记为正确,因为这应该可以工作。感谢您的所有帮助! - Just Ask
1
我刚刚测试了一下,没有使用我的角度计算,但它仍然无法工作。所以问题不仅仅出在我的代码上。我会继续努力解决它。 - Just Ask
@ThomSmith 我用你的公式计算弧中点时遇到了问题。起点、终点和中点分别为{200.4,312.413333333333}、{218.651309974701,374.31673171666}、{166.4,356.08}。 - SHEKHAR SHETE
1
x2从未被赋值。您应该将以下代码替换为: let ( x2 , y2) = (end.x - center.x, end.y - center.y) - Michaël Corriveau-Côté
显示剩余2条评论

0

虽然此函数返回的是一个近似点,但它对实际目的非常有用。我自己刚刚弄明白了这个问题,它运行得很好。

先决条件:
- 这里假定圆弧中心为 (0, 0),尽管可以修改为使用中心点参数
- 您必须知道圆弧开始的角度(例如270)
- 您必须知道圆弧的角度测量值(例如90度)

以下代码是用 Objective-C 编写的:

#define   DEGREES_TO_RADIANS(degrees)  ((M_PI * degrees)/ 180)
- (CGPoint)getApproximateMidPointForArcWithStartAngle:(CGFloat)startAngle andDegrees:(CGFloat)degrees {

CGFloat midPointDegrees = fmodf(startAngle + degrees / 2, 360);
CGFloat midStartAngle = midPointDegrees - .1f;
CGFloat midEndAngle = midPointDegrees + .1f;

UIBezierPath *midPointPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:self.radius startAngle:DEGREES_TO_RADIANS(midStartAngle) endAngle:DEGREES_TO_RADIANS(midEndAngle) clockwise:YES];

CGRect midPointPathFrame = CGPathGetPathBoundingBox(midPointPath.CGPath);
CGPoint approximateMidPointCenter = CGPointMake(CGRectGetMidX(midPointPathFrame), CGRectGetMidY(midPointPathFrame));
return approximateMidPointCenter;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接