三次贝塞尔曲线逆 GetPoint 方程:float for Vector <=> Vector for float

2024-05-05

给定结果值和四个点是否可以取回 float t ? 如果是这样,怎么办?

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

本教程中的代码,作者:Jasper Flick http://catlikecoding.com/unity/tutorials/curves-and-splines/


确实如此,并且涉及对三次函数进行求根。一种直接的方法是实施卡尔达诺算法 http://www.trans4mind.com/personal_development/mathematics/polynomials/cubicAlgebra.htm用于求三阶多项式的根 - 可以找到该函数的 JavaScript 实现here http://jsbin.com/mutaracihafi/1/edit?js,output。根据曲线的参数,您将获得最多三个同样正确的答案,因此取决于您试图找到的内容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];
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三次贝塞尔曲线逆 GetPoint 方程:float for Vector <=> Vector for float 的相关文章

随机推荐