简体   繁体   English

计算给定角度的贝塞尔曲线控制点

[英]Calculate bezier curve control points with given angle

在此处输入图片说明 Lets assume we have a bezier curve with a start p0 of (0, 0) and an end p4 of (100, 0). 假设我们有一个贝塞尔曲线,其起点p0为(0,0),终点p4为(100,0)。 Right now it would basically be a line with no curve yet. 现在基本上是一条没有曲线的线。 Now lets assume I want to calculate the two missing control points (p1 p2) based on a given angle. 现在假设我要基于给定角度计算两个缺失的控制点(p1 p2)。 What is the best way to achieve this? 实现此目标的最佳方法是什么?

Lets assume I wanted something like this: 假设我想要这样的东西:

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

I mean depending on the position of the control points it forms a triangle of some sort, that is why I was wondering if its possible. 我的意思是,根据控制点的位置,它会形成某种三角形,这就是为什么我想知道它是否可能。

Controls points that go through a Bezier point with a given angle, lie on the tangent with that angle. 控制以给定角度经过贝塞尔曲线点的点,该点位于该角度的切线上。

The resulting bending will be the softer the farther away the control point is chosen, so there are many different solutions with the same angle and different curvature.. 所选择的控制点越远,弯曲越柔和,因此存在许多具有相同角度和不同曲率的不同解决方案。

在此处输入图片说明

To find control points with equally soft curvatures for two Bezier points simply find the crossing of the two tangents! 要找到两个贝塞尔曲线点具有相同曲率的控制点,只需找到两个切线的交点即可! Use the crossing as the common control point for both segments, ie have C1 = C2. 将交叉点用作两个线段的公共控制点,即C1 = C2。

For any sort of symmetrical curve you need to keep the deviations from the crossing symmetrical, ie 50%, 10% etc.. 对于任何种类的对称曲线,都需要保持与交叉对称的偏差,即50%,10%等。

Note that for optimizing the overall shape one also needs to look at the neighbouring points; 请注意,为了优化整体形状,还需要查看相邻点。 in general the provided GDI function does a good job; 通常,提供的GDI功能可以很好地完成工作; so it is worth considering simply adding more Bezier points for controlling the shape; 因此值得考虑的是,只需添加更多的贝塞尔曲线点来控制形状; but of course using the perfect set of control points is the most economic solution. 但是,当然,使用最理想的控制点集是最经济的解决方案。

Update: I have added an example of how well a circle (orange) gets approximated by the math in this interesting post . 更新:这个有趣的帖子中,我添加了一个示例,说明数学对圆(橙色)的近似程度如何。

Short version: An exact solution isn't really possible but the best fit for a quarter circle is to move the control point to ~0.55% of the crossing point. 简短版本:确切的解决方案实际上是不可能的,但最适合四分之一圆的方法是将控制点移至交叉点的〜0.55%。 ( d=r*4*(sqrt(2)-1)/3 ). d=r*4*(sqrt(2)-1)/3 )。 Sometimes instead of using a 4 segment solution an 8 segment solution is used for even closer approximation.. 有时,不是使用4段解,而是使用8段解进行更接近的近似。

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();
}

The code uses Labels for the points and control points.. 该代码使用Labels作为点和控制点。

Btw: Adding ellipses/circles to a GraphicsPath will create bezier curves that seem to be approximated just like that. 顺便说一句:在GraphicsPath添加椭圆/圆将创建贝塞尔曲线,看起来就像这样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM