【问题标题】:Calculate points on an arc of a circle using center, radius and 3 points on the circle使用圆心、半径和圆上的 3 个点计算圆弧上的点
【发布时间】:2021-04-09 12:48:49
【问题描述】:

给定圆上的圆心、半径和 3 个点,我想通过指定开始绘制的角度和角度量来绘制从第一个点开始,经过第二个点并在第三个点结束的圆弧旋转。为此,我需要计算弧上的点。我希望计算出的点数是可变的,这样我就可以调整计算出的弧线的精度,所以这意味着我可能需要一个循环,在计算出一个点后通过旋转一点来计算每个点。我已经阅读了这个问题的答案Draw arc with 2 points and center of the circle,但它只解决了计算角度的问题,因为我不知道 'canvas.drawArc' 是如何实现的。

【问题讨论】:

    标签: algorithm math geometry


    【解决方案1】:

    这个问题有两个部分:

    1. 如何找到通过第三点的两点之间的弧?
    2. 如何在找到的弧上生成一组点?

    让我们从第一部分开始。给定(O, r) 圆上的三个点ABC,我们希望找到通过BAC 之间的弧。要找到圆弧的内角,我们需要计算ABAC 圆弧的oriented angles。如果AB 的角度大于AC,则方向错误:

    Va.x = A.x - O.x;
    Va.y = A.y - O.y;
    Vb.x = B.x - O.x;
    Vb.y = B.y - O.y;
    Vc.x = C.x - O.x;
    Vc.y = C.y - O.y;
    
    tb = orientedAngle(Va.x, Va.y, Vb.x, Vb.y);
    tc = orientedAngle(Va.x, Va.y, Vc.x, Vc.y);
    
    if tc<tb
        tc = tc - 2 * pi;
    end
    
    
    function t = orientedAngle(x1, y1, x2, y2)
        t = atan2(x1*y2 - y1*x2, x1*x2 + y1*y2);
        if t<0
            t = t + 2 * pi;
        end
    end
    

    现在是第二部分。你说:

    我可能需要一个循环,通过旋转一点来计算每个点 在它计算了一个点之后。

    但问题是,有多少?由于圆的周长随着半径的增加而增加,因此您无法以固定的角度达到固定的精度。换句话说,要绘制两条角度相同、半径不同的圆弧,我们需要不同数量的点。我们可以假设[几乎]恒定的是这些点之间的距离,或者我们为模拟弧线而绘制的线段的长度:

    segLen = someConstantLength;
    arcLen = abs(tc)*r;
    segNum = ceil(arcLen/segLen);
    segAngle = tc / segNum;
    t = atan2(Va.y, Va.x); 
    
    for i from 0 to segNum
        P[i].x = O.x + r * cos(t);
        P[i].y = O.y + r * sin(t);
        t = t + segAngle;
    end
    

    请注意,虽然在此方法中AC 肯定会创建,但B 不一定是创建的点之一。但是,这个点到最近的线段的距离会很小。

    【讨论】:

    • 为什么需要计算定向角度?我不能只计算 Va、Vb 的点积,然后将结果除以 Va 和 Vb 的长度的乘积吗?然后我会得到角度的 cos 值,然后我可以使用 acos 得到实际的角度。
    • @palapapa 点积方法将为您提供两个向量的(较小的)内角,并最终为您提供两点之间可能的最短弧。但是,有时B 位于AC 之间的较长弧上,就像我回答中的图像一样。所以我们需要一个既能给出方向又能给出(角度)距离的测量值。
    • 我不明白如果它是负数,你为什么要在 t 中添加 2pi。定向角度不应该从-pi到pi吗?你想得到从A到B和C的逆时针角度吗?或者您是否想让比较更容易编写?如果我理解正确,我不能使用点积方法的原因是因为我无法判断从 A 到 B 的角度和从 A 到 C 的角度是否具有相同的方向.因此,如果结果为负数,则使用定向角度并在结果中添加 2pi,如果 tb > tc 则逆时针旋转是错误的。
    • @pala 让我用我的话解释一下。角度范围没有应该。在三角圆中,角度a 等于a+2*pi。另一方面,逆时针角度的负值实际上是顺时针角度的正值。通过将其添加到2*pi,我保证函数的输出始终为正,而不会改变角度。既然我们确定tbtc 角度都是正的并且在A 的同一侧,我们可以安全地比较它们,看看我们是否朝这个方向移动,我们将首先到达BC。如果我们先到达C,我们会反转方向。
    猜你喜欢
    • 2014-05-12
    • 2012-05-11
    • 2020-09-16
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    相关资源
    最近更新 更多