计算Bezier曲线的中点

时间:2014-05-11 19:12:58

标签: c# wpf point bezier

我有一个通过三点绘制Bezier Curve的功能。我已经有2点(开始和结束) - A和B.我如何计算这两点之间的中点,因为中点总是比这两点的线性函数稍高或低一点。

示例

enter image description here

任何公式,想法都会很棒!

4 个答案:

答案 0 :(得分:5)

我认为这就是你要找的东西:

http://blog.sklambert.com/finding-the-control-points-of-a-bezier-curve/

详细介绍了贝塞尔曲线上各点的计算方法。

您可能还对此应用程序的更具体示例感兴趣:

http://www.codeproject.com/Articles/223159/Midpoint-Algorithm-Divide-and-Conquer-Method-for-D

如果你真的想进入它,那么我建议使用这本入门书:

http://pomax.github.io/bezierinfo/

Bezier曲线比简单弧更复杂。对于弧线,您可以使用以下公式:

R = H/2 + W^2/8H

...绝对不适用于Bezier曲线。例如,在二次贝塞尔曲线上,要计算一个点,必须使用:

enter image description here

来源:http://en.wikipedia.org/wiki/B%C3%A9zier_curveQuadratic Bezier Curve: Calculate Point

答案 1 :(得分:4)

以下是我用来获得四边形贝塞尔曲线控制点的方法。它应该适用于控制点在曲线上的问题。它在Swift中,但您应该能够轻松地将其转换为另一种语言。基本上在线的中点(其点是point1和point2),我计算出具有给定长度的垂直线。顺时针参数确定该点应该落在哪一侧。

func getControlPointWithPoint1(point1:CGPoint, point2:CGPoint, length:CGFloat, clockwise:Bool) -> CGPoint {
  let angle = getAngleWithPoint1(point1, point2:point2)
  let direction = clockwise ? 1 : -1
  let perpendicularAngle = angle + (CGFloat(direction) * CGFloat((M_PI / 2)))
  let midPoint = getMidPointWithPoint1(point1, point2:point2)
  return CGPointMake(midPoint.x + (cos(perpendicularAngle) * length), midPoint.y + (sin(perpendicularAngle) * length))
}

func getAngleWithPoint1(point1:CGPoint, point2:CGPoint) -> CGFloat {
  return atan2((point2.y - point1.y), (point2.x - point1.x))
}

func getMidPointWithPoint1(point1:CGPoint, point2:CGPoint) -> CGPoint {
  return CGPointMake((point1.x + point2.x) / 2, (point1.y + point2.y) / 2)
}

下面是它如何映射到你的图表字母:

c = getControlPointWithPoint1(a, point2:b, length:h, clockwise:true)

答案 2 :(得分:0)

根据Mark的回答,这是C#中的片段

IntSummaryStatistics

答案 3 :(得分:0)

如果能帮助您,我会很高兴。

这是我的解决办法。

    Vector2 posA = sphereA.transform.position;
    Vector2 posB = sphereB.transform.position;

    Gizmos.color = Color.blue;
    Gizmos.DrawLine(posA, posB);

    float distance = Vector2.Distance(posA, posB);
    Vector2 direction = (posB - posA).normalized;

    Vector2 v2 = end - start;
    var angle = Mathf.Atan2(v2.y, v2.x) * Mathf.Rad2Deg;      

    var midStartPos = posA + direction * (distance / 2f);

    Gizmos.color = Color.red;
    Gizmos.DrawSphere(midStartPos, 0.02f);

    var height = 0.3f;

    height = Mathf.Clamp(height, 0f, Vector2.Distance(posA, posB) * 0.5f);

    angle = 90f + angle;

    var goalDirection = new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad));

    if (goalDirection.y < 0f)
    {
        goalDirection.x = -goalDirection.x;
        goalDirection.y = Mathf.Abs(goalDirection.y);
    }

    var midEndPos = midStartPos + goalDirection * height;

    Gizmos.color = Color.blue;
    Gizmos.DrawLine(midStartPos, midEndPos);

    Gizmos.color = Color.red;
    Gizmos.DrawSphere(midEndPos, 0.02f);