代码之家  ›  专栏  ›  技术社区  ›  Asperger

计算具有给定角度的bezier曲线控制点

  •  1
  • Asperger  · 技术社区  · 8 年前

    enter image description here 假设我们有一条bezier曲线,起点p0为(0,0),终点p4为(100,0)。现在它基本上是一条没有曲线的直线。现在让我们假设我想根据给定角度计算两个缺失的控制点(p1和p2)。实现这一目标的最佳方式是什么?

    假设我想要这样的东西:

    https://1.bp.blogspot.com/_W3ZUYKgeEpk/SDcAerq1xkI/AAAAAAAAAAc/W9OnovkzgPI/s400/RectanglularControlPoly.jpg

    我的意思是,根据控制点的位置,它形成某种三角形,这就是为什么我想知道这是否可能。

    1 回复  |  直到 8 年前
        1
  •  2
  •   Community CDub    7 年前

    控制以给定角度穿过Bezier点的点位于该角度的切线上。

    选择的控制点越远,产生的弯曲越软,因此有许多不同的解决方案,具有相同的角度和不同的曲率。。

    enter image description here

    要找到两个贝塞尔点具有相同软曲率的控制点,只需找到两条切线的交点!将交叉点用作两段的公共控制点,即C1=C2。

    对于任何类型的对称曲线,需要保持交叉点的偏差对称,即50%、10%等。。

    注意,为了优化整体形状,还需要查看相邻点;一般来说,提供的GDI功能表现良好;因此,值得考虑简单地添加更多贝塞尔点来控制形状;当然,使用一组完美的控制点是最经济的解决方案。

    更新: 我已经添加了一个示例,演示了中的数学如何很好地近似圆(橙色) this interesting post .

    简而言之:精确的解决方案不太可能,但四分之一圆的最佳拟合是将控制点移动到交叉点的约0.55%。( d=r*4*(sqrt(2)-1)/3 ). 有时,为了更接近近似,使用8段解代替4段解。。

    private void button_Click(object sender, EventArgs e)
    {
        int w = Math.Abs(P2.Left - P1.Left);
        int h = Math.Abs(P2.Top - P1.Top);
        C2.Left =  (int) (P2.Left + w * 0.5523f);
        C2.Top = P2.Top;
        C1.Left = P1.Left;
        C1.Top = (int) (P1.Top + h * 0.5523f);
        C1.Parent.Invalidate();
    }
    

    代码使用 Labels 对于点和控制点。。

    顺便说一句:将椭圆/圆添加到 GraphicsPath 将创建看起来像那样近似的贝塞尔曲线。