Пример #1
0
void* KB_PosInitialize(int numKeys, PositionKey* key)
{
   assert(numKeys >= 4);

   float omt0, omc0, opc0, omb0, opb0, adj0, out0, out1;
   float omt1, omc1, opc1, omb1, opb1, adj1, in0, in1;
   Point3 Tout, Tin;
   Point3 DP;
      
   SplineInfo* info = (SplineInfo*) calloc(1, sizeof(SplineInfo));
   info->numPolys = numKeys-3;
   info->poly = (CubicPolynomial*)
      calloc(info->numPolys, sizeof(CubicPolynomial));

   int i0 = 0, i1 = 1, i2 = 2, i3 = 3;
   for (; i0 < info->numPolys; i0++, i1++, i2++, i3++)
   {
      /* Build P[i2] - P[i1]. */
      DP.x = key[i2].P.x - key[i1].P.x;
      DP.y = key[i2].P.y - key[i1].P.y;
      DP.z = key[i2].P.z - key[i1].P.z;

      /* Build multipliers at point P[i1]. Names are derived as follows:
       * one - minus / plus - t / c / b */
      omt0 = 1 - key[i1].tension;      //1 - p1.t
      omc0 = 1 - key[i1].continuity;   //1 - p1.c
      opc0 = 1 + key[i1].continuity;   //1 + p1.c
      omb0 = 1 - key[i1].bias;         //1 - p1.b
      opb0 = 1 + key[i1].bias;         //1 + p1.b
      /* I don't get this adjustment. It differs from the explanation on
      Wikpedia, and the * 2 cancels with the / 2 later. */
      adj0 = 2 * (key[i2].t - key[i1].t) / (key[i2].t - key[i0].t);
         //2 * (t2 - t1) / (t2 - t0)
      out0 = (adj0 * omt0 * opc0 * opb0) / 2;
      out1 = (adj0 * omt0 * omc0 * omb0) / 2;

      /* Build outgoing tangent at P[i1]. */
      Tout.x = out1 * (DP.x) + out0 * (key[i1].P.x - key[i0].P.x);
      Tout.y = out1 * (DP.y) + out0 * (key[i1].P.y - key[i0].P.y);
      Tout.z = out1 * (DP.z) + out0 * (key[i1].P.z - key[i0].P.z);

      /* Build multipliers at point P[i2]. */
      omt1 = 1 - key[i2].tension;      //1 - p2.t
      omc1 = 1 - key[i2].continuity;   //1 - p2.c
      opc1 = 1 + key[i2].continuity;   //1 + p2.c
      omb1 = 1 - key[i2].bias;         //1 - p2.b
      opb1 = 1 + key[i2].bias;         //1 + p2.b
      adj1 = 2 * (key[i2].t - key[i1].t) / (key[i3].t - key[i1].t);
         //2 * (t2 - t1) / (t3 - t1)
      in0 = (adj1 * omt1 * omc1 * opb1) / 2;
      in1 = (adj1 * omt1 * opc1 * omb1) / 2;

      /* Build incoming tangent at P[i2]. */
      Tin.x = in1 * (key[i3].P.x - key[i2].P.x) + in0 * (DP.x);
      Tin.y = in1 * (key[i3].P.y - key[i2].P.y) + in0 * (DP.y);
      Tin.z = in1 * (key[i3].P.z - key[i2].P.z) + in0 * (DP.z);

      info->poly[i0].C0.x = key[i1].P.x;
      info->poly[i0].C0.y = key[i1].P.y;
      info->poly[i0].C0.z = key[i1].P.z;

      info->poly[i0].C1.x = Tout.x;
      info->poly[i0].C1.y = Tout.y;
      info->poly[i0].C1.z = Tout.z;

      info->poly[i0].C2.x = 3 * DP.x - 2 * Tout.x - Tin.x;
      info->poly[i0].C2.y = 3 * DP.y - 2 * Tout.y - Tin.y;
      info->poly[i0].C2.z = 3 * DP.z - 2 * Tout.z - Tin.z;

      info->poly[i0].C3.x = -2 * DP.x + Tout.x + Tin.x;
      info->poly[i0].C3.y = -2 * DP.y + Tout.y + Tin.y;
      info->poly[i0].C3.z = -2 * DP.z + Tout.z + Tin.z;

      info->poly[i0].tmin = key[i1].t;
      info->poly[i0].tmax = key[i2].t;
      info->poly[i0].trange = info->poly[i0].tmax - info->poly[i0].tmin;
   }

   ComputeArcLength(info);

   return info;
}
Пример #2
0
/*-------------------------------------------------------------------------*/
void* KB_PosInitialize (int numKeys, PositionKey* key)
{
  /* assert:  numKeys >= 4 */

    double omt0, omc0, opc0, omb0, opb0, adj0, out0, out1;
    double omt1, omc1, opc1, omb1, opb1, adj1, in0, in1;
    Point3 Tout, Tin;
    Point3 DP;
    int i0 = 0, i1 = 1, i2 = 2, i3 = 3;
    SplineInfo* info = (SplineInfo*)calloc(1, sizeof(SplineInfo));
    info->numPolys = numKeys-3;
    info->poly = (CubicPolynomial*)calloc(info->numPolys, sizeof(CubicPolynomial));

    for (/**/; i0 < info->numPolys; i0++, i1++, i2++, i3++)
    {
      /* build P[i2]-P[i1]; */
        DP.x = key[i2].P.x - key[i1].P.x;
        DP.y = key[i2].P.y - key[i1].P.y;
        DP.z = key[i2].P.z - key[i1].P.z;

        /* build multipliers at point P[i1] */
        omt0 = 1-key[i1].tension;
        omc0 = 1-key[i1].continuity;
        opc0 = 1+key[i1].continuity;
        omb0 = 1-key[i1].bias;
        opb0 = 1+key[i1].bias;
        adj0 = 2*(key[i2].t-key[i1].t)/(key[i2].t-key[i0].t);
        out0 = 0.5*adj0*omt0*opc0*opb0;
        out1 = 0.5*adj0*omt0*omc0*omb0;

        /* build outgoing tangent at P[i1] */
        Tout.x = out1*(DP.x)+out0*(key[i1].P.x-key[i0].P.x);
        Tout.y = out1*(DP.y)+out0*(key[i1].P.y-key[i0].P.y);
        Tout.z = out1*(DP.z)+out0*(key[i1].P.z-key[i0].P.z);

        /* build multipliers at point P[i2] */
        omt1 = 1-key[i2].tension;
        omc1 = 1-key[i2].continuity;
        opc1 = 1+key[i2].continuity;
        omb1 = 1-key[i2].bias;
        opb1 = 1+key[i2].bias;
        adj1 = 2*(key[i2].t-key[i1].t)/(key[i3].t-key[i1].t);
        in0 = 0.5*adj1*omt1*omc1*opb1;
        in1 = 0.5*adj1*omt1*opc1*omb1;

        /* build incoming tangent at P[i2] */
        Tin.x = in1*(key[i3].P.x-key[i2].P.x)+in0*(DP.x);
        Tin.y = in1*(key[i3].P.y-key[i2].P.y)+in0*(DP.y);
        Tin.z = in1*(key[i3].P.z-key[i2].P.z)+in0*(DP.z);

        info->poly[i0].C0.x = key[i1].P.x;
        info->poly[i0].C0.y = key[i1].P.y;
        info->poly[i0].C0.z = key[i1].P.z;

        info->poly[i0].C1.x = Tout.x;
        info->poly[i0].C1.y = Tout.y;
        info->poly[i0].C1.z = Tout.z;

        info->poly[i0].C2.x = 3*DP.x-2*Tout.x-Tin.x;
        info->poly[i0].C2.y = 3*DP.y-2*Tout.y-Tin.y;
        info->poly[i0].C2.z = 3*DP.z-2*Tout.z-Tin.z;

        info->poly[i0].C3.x = -2*DP.x+Tout.x+Tin.x;
        info->poly[i0].C3.y = -2*DP.y+Tout.y+Tin.y;
        info->poly[i0].C3.z = -2*DP.z+Tout.z+Tin.z;

        info->poly[i0].tmin = key[i1].t;
        info->poly[i0].tmax = key[i2].t;
        info->poly[i0].trange = info->poly[i0].tmax-info->poly[i0].tmin;
    }

    ComputeArcLength(info);

    return info;
}