/* * MODULE: extrude.c * * FUNCTION: * Provides code for the cylinder, cone and extrusion routines. * The cylinders/cones/etc. are built on top of general purpose * extrusions. The code that handles the general purpose extrusions * is in other modules. * * AUTHOR: * written by Linas Vepstas August/September 1991 * added polycone, February 1993 */ #include #include #include #include /* for the memcpy() subroutine */ #include "gle.h" #include "port.h" #include "vvector.h" #include "tube_gc.h" #include "extrude.h" #include "intersect.h" /* ============================================================ */ /* The routine below determines the type of join style that will be * used for tubing. */ void gleSetJoinStyle (int style) { INIT_GC(); extrusion_join_style = style; } int gleGetJoinStyle (void) { INIT_GC(); return (extrusion_join_style); } /* ============================================================ */ /* * draw a general purpose extrusion */ void gleSuperExtrusion (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 */ float color_array[][3], /* color of polyline */ gleDouble xform_array[][2][3]) /* 2D contour xforms */ { INIT_GC(); _gle_gc -> ncp = ncp; _gle_gc -> contour = contour; _gle_gc -> cont_normal = cont_normal; _gle_gc -> up = up; _gle_gc -> npoints = npoints; _gle_gc -> point_array = point_array; _gle_gc -> color_array = color_array; _gle_gc -> xform_array = xform_array; switch (__TUBE_STYLE) { case TUBE_JN_RAW: (void) extrusion_raw_join (ncp, contour, cont_normal, up, npoints, point_array, color_array, xform_array); break; case TUBE_JN_ANGLE: (void) extrusion_angle_join (ncp, contour, cont_normal, up, npoints, point_array, color_array, xform_array); break; case TUBE_JN_CUT: case TUBE_JN_ROUND: /* This routine used for both cut and round styles */ (void) extrusion_round_or_cut_join (ncp, contour, cont_normal, up, npoints, point_array, color_array, xform_array); break; default: break; } } /* ============================================================ */ 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 */ float color_array[][3]) /* color of polyline */ { gleSuperExtrusion (ncp, contour, cont_normal, up, npoints, point_array, color_array, NULL); } /* ============================================================ */ /* should really make this an adaptive algorithm ... */ static void gen_polycone (int npoints, gleDouble point_array[][3], float color_array[][3], 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; iinf) (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