Exemplo n.º 1
0
void gleExtrusion (int ncp,               /* number of contour points */
                gleDouble contour[][2],    /* 2D contour */
                gleDouble cont_normal[][2], /* 2D contour normals */
                gleDouble up[3],           /* up vector for contour */
                int npoints,           /* numpoints in poly-line */
                gleDouble point_array[][3],        /* polyline */
                gleColor color_array[])        /* color of polyline */
{   
   gleSuperExtrusion (ncp, contour, cont_normal, up,
                    npoints,
                    point_array, color_array,
                    NULL);
}
Exemplo n.º 2
0
void gleTwistExtrusion (int ncp,         /* number of contour points */
                gleDouble contour[][2],    /* 2D contour */
                gleDouble cont_normal[][2], /* 2D contour normals */
                gleDouble up[3],           /* up vector for contour */
                int npoints,           /* numpoints in poly-line */
                gleDouble point_array[][3],        /* polyline */
                gleColor color_array[],        /* color of polyline */
                gleDouble twist_array[])   /* countour twists (in degrees) */

{
   int j;
   double angle;
   double si, co;

   gleAffine *xforms;

   /* build 2D affine matrices from radius array */
   xforms = (gleAffine *) malloc (npoints * sizeof(gleAffine));

   for (j=0; j<npoints; j++) {
      angle = (M_PI/180.0) * twist_array[j];
      si = sin (angle);
      co = cos (angle);
      AVAL(xforms,j,0,0) = co;
      AVAL(xforms,j,0,1) = -si;
      AVAL(xforms,j,0,2) = 0.0;
      AVAL(xforms,j,1,0) = si;
      AVAL(xforms,j,1,1) = co;
      AVAL(xforms,j,1,2) = 0.0;
   }

   gleSuperExtrusion (ncp,               /* number of contour points */
                contour,    /* 2D contour */
                cont_normal, /* 2D contour normals */
                up,           /* up vector for contour */
                npoints,           /* numpoints in poly-line */
                point_array,        /* polyline */
                color_array,        /* color of polyline */
                xforms);

   free (xforms);
}
void gleTaper (int ncp,
               gleDouble contour[][2],
               gleDouble cont_normal[][2],
               gleDouble up[3],
               int npoints,
               gleDouble point_array[][3],
               float color_array[][3],
               gleDouble taper[],
               gleDouble twist[])
{
    int j;
    gleAffine *xforms;
    double co, si, angle;

    /* malloc the extrusion array and the twist array */
    xforms = (gleAffine *) malloc (npoints * sizeof(gleAffine));

    for (j=0; j<npoints; j++) {
        angle = (M_PI/180.0) * twist[j];
        si = sin (angle);
        co = cos (angle);
        xforms[j][0][0] = taper[j] * co;
        xforms[j][0][1] = - taper[j] * si;
        xforms[j][0][2] = 0.0;
        xforms[j][1][0] = taper[j] * si;
        xforms[j][1][1] = taper[j] * co;
        xforms[j][1][2] = 0.0;
    }

    gleSuperExtrusion (ncp,               /* number of contour points */
                       contour,    /* 2D contour */
                       cont_normal, /* 2D contour normals */
                       up,           /* up vector for contour */
                       npoints,           /* numpoints in poly-line */
                       point_array,        /* polyline */
                       color_array,        /* color of polyline */
                       xforms);

    free (xforms);
}
Exemplo n.º 4
0
void gleSpiral (int ncp,               /* number of contour points */
             gleDouble contour[][2],    /* 2D contour */
             gleDouble cont_normal[][2], /* 2D contour normals */
             gleDouble up[3],           /* up vector for contour */
             gleDouble startRadius,
             gleDouble drdTheta,        /* change in radius per revolution */
             gleDouble startZ,
             gleDouble dzdTheta,        /* change in Z per revolution */
             gleDouble startXform[2][3],
             gleDouble dXformdTheta[2][3], /* tangent change xform per revolution */
             gleDouble startTheta,	      /* start angle, in degrees */
             gleDouble sweepTheta)        /* sweep angle, in degrees */
{
   int npoints;
   gleDouble deltaAngle;
   char * mem_anchor;
   gleDouble *pts;
   gleAffine *xforms;
   double delta;

   int saved_style;
   double ccurr, scurr;
   double cprev, sprev;
   double cdelta, sdelta;
   double mA[2][2], mB[2][2];
   double run[2][2];
   double deltaTrans[2];
   double trans[2];
   int i;

   INIT_GC();
   /* allocate sufficient memory to store path */
   npoints = (int) ((((double) __TESS_SLICES) /360.0) * fabs(sweepTheta)) + 4;

   if (startXform == NULL) {
      mem_anchor = malloc (3*npoints * sizeof (gleDouble));
      pts = (gleDouble *) mem_anchor;
      xforms = NULL;
   } else {
      mem_anchor = malloc ((1+2)* 3*npoints * sizeof (gleDouble));
      pts = (gleDouble *) mem_anchor;
      xforms = (gleAffine *) (pts + 3*npoints);
   }

   /* compute delta angle based on number of points */
   deltaAngle = (M_PI / 180.0) * sweepTheta / ((gleDouble) (npoints-3));
   startTheta *= M_PI / 180.0;
   startTheta -= deltaAngle;

   /* initialize factors */
   cprev = cos ((double) startTheta);
   sprev = sin ((double) startTheta);

   cdelta = cos ((double) deltaAngle);
   sdelta = sin ((double) deltaAngle);

   /* renormalize differential factors */
   delta = deltaAngle / (2.0 * M_PI);
   dzdTheta *= delta;
   drdTheta *= delta;

   /* remember, the first point is hidden, so back-step */
   startZ -=  dzdTheta;
   startRadius -=  drdTheta;

   /* draw spiral path using recursion relations for sine, cosine */
   for (i=0; i<npoints; i++) {
      pts [3*i] =  startRadius * cprev;
      pts [3*i+1] =  startRadius * sprev;
      pts [3*i+2] = (gleDouble) startZ;

      startZ +=  dzdTheta;
      startRadius +=  drdTheta;
      ccurr = cprev * cdelta - sprev * sdelta;
      scurr = cprev * sdelta + sprev * cdelta;
      cprev = ccurr;
      sprev = scurr;
   }

   /* If there is a deformation matrix specified, then a deformation
    * path must be generated also */
   if (startXform != NULL) {
      if (dXformdTheta == NULL) {
         for (i=0; i<npoints; i++) {
            xforms[i][0][0] = startXform[0][0];
            xforms[i][0][1] = startXform[0][1];
            xforms[i][0][2] = startXform[0][2];
            xforms[i][1][0] = startXform[1][0];
            xforms[i][1][1] = startXform[1][1];
            xforms[i][1][2] = startXform[1][2];
         }
      } else {
         /* 
          * if there is a differential matrix specified, treat it a 
          * a tangent (algebraic, infinitessimal) matrix.  We need to
          * project it into the group of real 2x2 matricies.  (Note that
          * the specified matrix is affine.  We treat the translation 
          * components linearly, and only treat the 2x2 submatrix as an 
          * algebraic tangenet).
          *
          * For exponentiaition, we use the well known approx:
          * exp(x) = lim (N->inf) (1+x/N) ** N
          * and take N=32. 
          */

         /* initialize translation and delta translation */
         deltaTrans[0] = delta * dXformdTheta[0][2];
         deltaTrans[1] = delta * dXformdTheta[1][2];
         trans[0] = startXform[0][2];
         trans[1] = startXform[1][2];
   
         /* prepare the tangent matrix */
         delta /= 32.0;
         mA[0][0] = 1.0 + delta * dXformdTheta[0][0];
         mA[0][1] = delta * dXformdTheta[0][1];
         mA[1][0] = delta * dXformdTheta[1][0];
         mA[1][1] = 1.0 + delta * dXformdTheta[1][1];
   
         /* compute exponential of matrix */
         MATRIX_PRODUCT_2X2 (mB, mA, mA);  /* squared */
         MATRIX_PRODUCT_2X2 (mA, mB, mB);  /* 4th power */
         MATRIX_PRODUCT_2X2 (mB, mA, mA);  /* 8th power */
         MATRIX_PRODUCT_2X2 (mA, mB, mB);  /* 16th power */
         MATRIX_PRODUCT_2X2 (mB, mA, mA);  /* 32nd power */
   
         /* initialize running matrix */
         COPY_MATRIX_2X2 (run, startXform);
   
         /* remember, the first point is hidden -- load some, any 
          * xform for the first point */
         xforms[0][0][0] = startXform[0][0];
         xforms[0][0][1] = startXform[0][1];
         xforms[0][0][2] = startXform[0][2];
         xforms[0][1][0] = startXform[1][0];
         xforms[0][1][1] = startXform[1][1];
         xforms[0][1][2] = startXform[1][2];

         for (i=1; i<npoints; i++) {
#ifdef FUNKY_C
            xforms[6*i] = run[0][0];
            xforms[6*i+1] = run[0][1];
            xforms[6*i+3] = run[1][0];
            xforms[6*i+4] = run[1][1];
#endif /* FUNKY_C */
            xforms[i][0][0] = run[0][0];
            xforms[i][0][1] = run[0][1];
            xforms[i][1][0] = run[1][0];
            xforms[i][1][1] = run[1][1];

            /* integrate to get exponential matrix */
            /* (Note that the group action is a left-action --
             * i.e. multiply on the left (not the right)) */
            MATRIX_PRODUCT_2X2 (mA, mB, run);
            COPY_MATRIX_2X2 (run, mA);
         
#ifdef FUNKY_C
            xforms[6*i+2] = trans [0];
            xforms[6*i+5] = trans [1];
#endif /* FUNKY_C */
            xforms[i][0][2] = trans [0];
            xforms[i][1][2] = trans [1];
            trans[0] += deltaTrans[0];
            trans[1] += deltaTrans[1];

         }
      }
   }

   /* save the current join style */
   saved_style = extrusion_join_style;

   /* Allow only angle joins (for performance reasons).
    * The idea is that if the tesselation is fine enough, then an angle
    * join should be sufficient to get the desired visual quality.  A 
    * raw join would look terrible, an cut join would leave garbage 
    * everywhere, and a round join will over-tesselate (and thus 
    * should be avoided for performance reasons). 
    */
   extrusion_join_style  &= ~TUBE_JN_MASK; 
   extrusion_join_style  |= TUBE_JN_ANGLE;

   gleSuperExtrusion (ncp, contour, cont_normal, up,
                  npoints, (gleVector *) pts, NULL, xforms);

   /* restore the join style */
   extrusion_join_style = saved_style;

   free (mem_anchor);

}
Exemplo n.º 5
0
static void 
gen_polycone (int npoints,
               gleDouble point_array[][3],
               gleColor color_array[],
               gleDouble radius,
               gleDouble xform_array[][2][3])
{
   int saved_style;
   gleTwoVec *circle, *norm;
   int i, nslices;
   double v21[3];
   double len;
   gleDouble up[3];

   INIT_GC();
   nslices = __TESS_SLICES;
   circle = __TESS_CIRCLE;
   norm = __TESS_NORM;

   /* this if statement forces this routine into double-duty for
    * both the polycone and the polycylinder routines */
   if (xform_array != NULL) radius = 1.0;

   /* draw a norm using recursion relations */
   for (i=0; i<nslices; i++) {
      circle [i][0] = radius * norm[i][0];
      circle [i][1] = radius * norm[i][1];
   }

   /* avoid degenerate vectors */
   /* first, find a non-zero length segment */
   i=0;
   FIND_NON_DEGENERATE_POINT(i,npoints,len,v21,point_array)
   if (i == npoints) return;

   /* next, check to see if this segment lies along x-axis */
   if ((v21[0] == 0.0) && (v21[2] == 0.0)) {
      up[0] = up[1] = up[2] = 1.0;
   } else {
      up[0] = up[2] = 0.0;
      up[1] = 1.0;
   }

   /* save the current join style */
   saved_style = extrusion_join_style;
   extrusion_join_style |= TUBE_CONTOUR_CLOSED;

   /* if lighting is not turned on, don't send normals.  
    * MMODE is a good indicator of whether lighting is active */
   if (!__IS_LIGHTING_ON) {
       gleSuperExtrusion (nslices, circle, NULL, up,
                     npoints, point_array, color_array,
                     xform_array);
   } else {
       gleSuperExtrusion (nslices, circle, norm, up,
                     npoints, point_array, color_array,
                     xform_array);
   }
   
   /* restore the join style */
   extrusion_join_style = saved_style;
}