【问题标题】:Find arc's mid-point given start, end, and center (of circle) points在给定起点、终点和圆心(圆)点的情况下找到弧的中点
【发布时间】:2018-11-08 22:23:39
【问题描述】:

我正在寻找有关如何找到圆弧中点的帮助。我有起点和终点、圆心和半径。我在网上到处搜索,找不到可以在任何地方转换成代码的答案。如果有人有任何想法,请告诉我。下图是我要找的(假设圆心已经找到)。

【问题讨论】:

  • This formula 似乎很容易实现。
  • 是否可以安全地假设所有值都是正数?
  • 是的,所有值都是正数。
  • 一如既往。到目前为止你有什么想法?圆和圆半径是什么意思??? 如果可以,请给我一张照片。
  • 我刚刚上传了一张图片。希望能帮助到你。如果没有,请告诉我。

标签: c# trigonometry


【解决方案1】:

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(平均值)因子,因为这不会改变角度。

更新:此方法将始终在周长上两点之间的最短圆弧上找到中点。这可能是您需要的,也可能不是。

【讨论】:

  • 约翰,这是否给了你中点?我给了我错误的结果。谢谢。
  • 它声称确实如此。您能否发布示例值以及您如何断定它是错误的?
【解决方案2】:

虽然此函数返回一个近似点,但它对实际用途很有用。这是我自己想出来的,效果很好。

先决条件:
- 此处假定圆弧中心为 (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;
}

【讨论】:

    【解决方案3】:

    取终点。

    (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
    

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

    EDIT3:另外,tan<sup>-1</sup>(y/x) 是正确的操作,但对于许多语言,您应该将其称为atan2(y, x) 而不是atan(y/x)atan2 就是为这种用途而设计的,它可以避免 x=0 时的错误,并且可能会给出更准确的结果。

    【讨论】:

    • 应该是 thetha1 和 theta2 的平均值,而不是区别
    • 这段代码有时会起作用,但我相信这可能是因为我计算角度和绘制弧线的方式。我将进行更多实验,当我确定这是我的错时,我会将其标记为正确,因为这应该有效。感谢您的所有帮助!
    • 我只是在没有使用我的角度计算的情况下对其进行了测试,但它仍然无法正常工作。所以这不仅仅是我的代码。我会继续努力的。
    • 最初,根据起点和终点所在的象限,它们可以在结果中反转。这应该是固定的。
    • x2 从未被分配。您应该将:let ( y1 , y2) = (end.x - center.x, end.y - center.y) 替换为:let ( x2 , y2) = (end.x - center.x, end.y - center.y)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    相关资源
    最近更新 更多