Cubic Bezier反向GetPoint方程:float for Vector< =>浮动的矢量

时间:2014-11-08 23:00:10

标签: c# math computational-geometry vector-graphics bezier

在给定结果值和四个点的情况下,是否有可能获得浮动? 如果是这样,怎么样?

public static Vector3 GetPoint (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
    t = Mathf.Clamp01(t);
    float oneMinusT = 1f - t;
    return
        oneMinusT * oneMinusT * oneMinusT * p0 +
        3f * oneMinusT * oneMinusT * t * p1 +
        3f * oneMinusT * t * t * p2 +
        t * t * t * p3;
}

Code from this Tutorial by Jasper Flick

2 个答案:

答案 0 :(得分:0)

它是,并涉及实现三阶函数的根查找。一种直接的方法是实现Cardano's Algorithm来查找三度多项式的根 - 可以找到here的JavaScript实现。根据曲线的参数,您将获得最多三个相同的相关答案,因此,根据您尝试查找t值的内容,您将需要做更多工作以找出其中的哪些 - 你需要的三个值。

// Not in every toolbox, so: how to implement the cubic root
// equivalent of the sqrt function (note that there are actually
// three roots: one real, two complex, and we don't care about the latter):
function crt(v) { if (v<0) return -pow(-v,1/3); return pow(v,1/3); } 

// Cardano's algorithm, based on
// http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm
function cardano(curve, line) {
  // align curve with the intersecting line, translating/rotating
  // so that the first point becomes (0,0), and the last point
  // ends up lying on the line we're trying to use as root-intersect.
  var aligned = align(curve, line),
      // rewrite from [a(1-t)^3 + 3bt(1-t)^2 + 3c(1-t)t^2 + dt^3] form...
      pa = aligned[0].y,
      pb = aligned[1].y,
      pc = aligned[2].y,
      pd = aligned[3].y,
      // ...to [t^3 + at^2 + bt + c] form:
      d = (  -pa + 3*pb - 3*pc + pd),
      a = ( 3*pa - 6*pb + 3*pc) / d,
      b = (-3*pa + 3*pb) / d,
      c = pa / d,
      // then, determine p and q:
      p = (3*b - a*a)/3,
      p3 = p/3,
      q = (2*a*a*a - 9*a*b + 27*c)/27,
      q2 = q/2, 
      // and determine the discriminant:
      discriminant = q2*q2 + p3*p3*p3,
      // and some reserved variables for later
      u1,v1,x1,x2,x3;

  // If the discriminant is negative, use polar coordinates
  // to get around square roots of negative numbers
  if (discriminant < 0) {
    var mp3 = -p/3,
        mp33 = mp3*mp3*mp3,
        r = sqrt( mp33 ),
        t = -q/(2*r),
        // deal with IEEE rounding yielding <-1 or >1
        cosphi = t<-1 ? -1 : t>1 ? 1 : t,
        phi = acos(cosphi),
        crtr = crt(r),
        t1 = 2*crtr;
    x1 = t1 * cos(phi/3) - a/3;
    x2 = t1 * cos((phi+tau)/3) - a/3;
    x3 = t1 * cos((phi+2*tau)/3) - a/3;
    return [x1, x2, x3];
  }

  else if(discriminant === 0) {
    u1 = q2 < 0 ? crt(-q2) : -crt(q2);
    x1 = 2*u1-a/3;
    x2 = -u1 - a/3;
    return [x1,x2];
  }

  // one real root, and two imaginary roots
  else {
    var sd = sqrt(discriminant),
        tt = -q2+sd;
    u1 = crt(-q2+sd);
    v1 = crt(q2+sd);
    x1 =  u1 - v1 - a/3;
    return [x1];
  }
}

答案 1 :(得分:-1)

求解下面的三次多项式应该揭示原始的t:

(p3 - (3 * p2) + (3 * p1) - p0) * t^3
+ ((3 * p2) - (6 * p1) + (3 * p0)) * t^2
+ ((3 * p1) - (3 * p0)) * t
+ p0
= 0

我把它放在标准格式中,这样你就可以很容易地从系数中得到根源。