三次贝塞尔曲线的拐点和复数

问题描述 投票:0回答:1

计算三次贝塞尔曲线拐点的一般公式是这样的:

X' * Y'' - X'' * Y' = 0
我分析了在计算中使用复数的代码:

private static bool IsRealInflectionPoint(Complex t)
{
    return t.Imaginary == 0 && t.Real > 0 && t.Real < 1;
}

public List<Complex> InflectionPoints
{
    get
    {
        var solutions = new List<Complex>();

        // http://www.caffeineowl.com/graphics/2d/vectorial/cubic-inflexion.html
        // solve X' * Y'' - X'' * Y' = 0

        var A = C1 - P1;
        var B = C2 - C1 - A;
        var C = P2 - C2 - A - 2 * B;

        var a = new Complex(B.X * C.Y - B.Y * C.X, 0);
        var b = new Complex(A.X * C.Y - A.Y * C.X, 0);
        var c = new Complex(A.X * B.Y - A.Y * B.X, 0);

        if (a != 0)
        {
            // quadratic equation: a*t^2 + b*t + c = 0 
            var t1 = (-b + Complex.Sqrt(b * b - 4 * a * c)) / (2 * a);
            var t2 = (-b - Complex.Sqrt(b * b - 4 * a * c)) / (2 * a);

            if (IsRealInflexionPoint(t1)) solutions.Add(t1);
            if (IsRealInflexionPoint(t2)) solutions.Add(t2);
        } 
        else // b != 0, linear equation: b*t + c = 0
        {
            var t = -c / b;
            if (IsRealInflexionPoint(t)) solutions.Add(t);
        }

        return solutions;
    }
}

这里是贝塞尔曲线基本参数的含义:

  • P1 - 起点
  • C1 - 第一个控制点
  • C2 - 第二个控制点
  • P2 - 终点

请解释A、B、C、a、b、c参数的含义? 上述解决方案中复数的作用是什么? 是否可以在不使用复数的情况下找到拐点?

c# math graphics geometry bezier
1个回答
1
投票

如果你对贝塞尔曲线的X坐标(X',X'')和Y坐标进行一阶和二阶导数的表达式,然后组成

X' * Y'' - X'' * Y' = 0
公式,你将得到对
t
参数的二次方程实系数

a*t^2 + b*t + c = 0 

你可以用实数求解——只处理判别式 D>=0 的情况。

D = b * b - 4 * a * c
if D == 0:  //single solution
   t1 = -0.5*b/a
elif D > 0:
    t1 = (-b + Math.Sqrt(D)) / (2 * a);
    t2 = (-b - Math.Sqrt(D)) / (2 * a);
    and check range 0..1

private static bool IsValidInflectionPoint(Double t)
{
    return t > 0 && t < 1;
}

public List<Double> InflectionPoints
{
    get
    {
        var solutions = new List<Double>();

        // http://www.caffeineowl.com/graphics/2d/vectorial/cubic-inflexion.html
        // solve X' * Y'' - X'' * Y' = 0

        var A = C1 - P1;
        var B = C2 - C1 - A;
        var C = P2 - C2 - A - 2 * B;

        var a = B.X * C.Y - B.Y * C.X, 0;
        var b = A.X * C.Y - A.Y * C.X, 0;
        var c = A.X * B.Y - A.Y * B.X, 0;

        if (a != 0)
        {
            // quadratic equation: a*t^2 + b*t + c = 0 
            var D = b * b - 4 * a * c;
            if D >=0  {
                D = Math.Sqrt(D)  ;
                var t1 = (-b + D) / (2 * a);
                var t2 = (-b - D) / (2 * a);

                if (IsValidInflexionPoint(t1)) solutions.Add(t1);
                if (IsValidInflexionPoint(t2)) solutions.Add(t2);
             }
        } 
        else // b != 0, linear equation: b*t + c = 0
        {
            var t = -c / b;
            if (IsValidInflexionPoint(t)) solutions.Add(t);
        }

        return solutions;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.