圆角:如何计算圆角半径?

时间:2014-02-26 21:22:02

标签: ios math core-graphics geometry

如何找到我可以应用于任一角落的最大舍入,以便在另一个角落进行任何数量的舍入?

评论中的问题答案:

1)内部和外部大弧(这里宽度为90度)始终具有相同的中心

2)当你要求进行最大舍入时,对另一个较小的圈有什么约束?是否需要至少某个半径?否则你最终只能进行一次舍入。

给出了两个圆弧半径中的一个。除了我找不到的另一个圆圈的最大值之外,没有其他限制。 如果我所指的“固定”角落没有舍入,那么我正在搜索只能在另一个角落应用的最大路由。

3)什么构成最大舍入?您是否尝试在上述两个示例之间进行选择?或者发现这些案例中的任何一个都被视为解决方案?

所示的案例中的任何一个都是完美的解决方案。例如。在第一个图像中,可以给出较小圆的半径。然后我正在寻找较大半径的最大半径。 这些图像只是完美​​解决方案的例子。

4)两个弧有任何限制吗?如果弧线不能适合整圆,会发生什么?答案是最适合的吗?

你究竟意味着弧线不能适合整圆?

所有圆圈都是完美的圆圈,但我无法弄清楚圆角的最大尺寸,或者如何计算它的位置。这是描述问题的一些图像。

2 个答案:

答案 0 :(得分:0)

如果没有显示线段的两端,则问题不正确。假设一个时刻,每个线段都是一个数据结构,不仅保持端点,而且还保持每个点的帽半径,并且还知道到该线将连接到的下一个端点的角度。每个上限半径将从必须作为矩形描边的线段的长度中减去。假设您在点B和C之间有一条感兴趣的线,其中B连接到另一个(更长的)线段A,并且C连接到另一个(更长的)线段D.如果线BC的长度为10,则具有帽半径B和帽半径C两者都设置为4,那么你只会为线段的直线部分渲染长度为2的矩形,而长度4用于将弧线绘制到A,另一个长度4用于将弧线绘制到D.

此外,C的最大帽半径不仅受BC和B的帽半径的约束,还受CD和D的帽半径的限制。

答案 1 :(得分:0)

鉴于坐标系的原点位于内部和外部大弧的中心点......

对于大圆与外边相切的第一种情况,大圆的中心点是

x = R cos(t) / (1 + cos(t))
y = R sin(t) / (1 + cos(t))

其中R是外弧段的半径,t是x轴和从原点穿过大圆心的光线之间的角度。

对于大圆与内边相切的第二种情况,大圆的中心点是

x = R cos(t) / (1 - cos(t))
y = R sin(t) / (1 - cos(t))

其中R是内弧段的半径,t是角度......

在这两种情况下,圆的半径等于其x坐标。 t的范围介于某个最小角度和PI / 2之间。在PI / 2处,圆圈非常小。在最小角度,y值等于相反的半径。换句话说,对于大圆与外边缘相切的第一种情况,最小角度使得y等于内半径。然而,如果圆与内边缘相切,则最小角度使得y等于外半径。在数学上可以证明,对于两种情况,最小角度是相同的(与内部相切并且与外部相切,对于给定的内半径和外半径具有相同的最小角度)。但是,计算最小角度有点挑战。我知道如何做的唯一方法是玩高/低游戏,例如

- (CGFloat)computeAngleForOuterTangentGivenY:(CGFloat)Y
{
    CGFloat y;
    double high = M_PI_2;
    double low  = 0;
    double mid  = M_PI_4;

    while ( high - low > 1e-9 )
    {
        y = (self.outerRadius * sin( mid )) / (1.0 + cos( mid ));
        if ( y > Y )
            high = mid;
        else
            low = mid;
        mid = (low + high) / 2.0;
    }

    return( mid );
}

- (CGFloat)computeAngleForInnerTangentGivenY:(CGFloat)Y
{
    CGFloat y;
    double high = M_PI_2;
    double low  = 0;
    double mid  = M_PI_4;

    while ( high - low > 1e-9 )
    {
        y = (self.innerRadius * sin( mid )) / (1.0 - cos( mid ));
        if ( y > Y )
            low = mid;
        else
            high = mid;
        mid = (low + high) / 2.0;
    }

    return( mid );
}

循环需要大约30次传递才能收敛到答案。

要查找小圆的坐标,请注意小圆与大圆具有相同的y值,并且与圆弧的相对边相切。因此,使用适当的高/低算法,根据y值计算小圆的角度t,然后使用上面的公式计算x值。

QED