/* curves.c 1.1 */ /* Copyright 1992, 1993 O'Reilly and Associates, Inc. Permission to use, copy, and modify this program is hereby granted, as long as this copyright notice appears in each copy of the program source code. */ #include "book_utils.h" static void redraw( dpy, window, renderer ) Display *dpy; Window window; PEXRenderer renderer; { static PEXCoord control_points[] = { {.1,.8,0},{.35,.9,0},{.6,.9,0},{.4,.7,0},{.7,.7,0},{.9,.88,0}}; static float knots_2ord[] = {1,1,2,3,4,5,6,6}; static float knots_3ord[] = {1,1,1,2,3,4,5,5,5}; static float knots_6ord[] = {1,1,1,1,1,1,2,2,2,2,2,2}; int order, num_knots, i; unsigned int num_points = 6; double tmin, tmax; PEXArrayOfCoord cpts; PEXColor color; XClearWindow( dpy, window ); PEXBeginRendering( dpy, window, renderer ); { SET_COLOR( 1, 1, 1, color ); PEXSetLineColor( dpy, renderer, PEXOCRender, PEXColorTypeRGB, &color ); PEXSetMarkerColor( dpy, renderer, PEXOCRender, PEXColorTypeRGB, &color ); /* Assign the control-point list. */ cpts.point = control_points; /* Second order curve. */ order = 2; num_knots = sizeof(knots_2ord)/sizeof(knots_2ord[0]); tmin = knots_2ord[order-1]; tmax = knots_2ord[num_knots - order]; PEXNURBCurve( dpy, renderer, PEXOCRender, PEXNonRational, order, knots_2ord, num_points, cpts, tmin, tmax ); /* Use markers to show the control points. */ PEXMarkers( dpy, renderer, PEXOCRender, 6, control_points ); /* Set the approximation criteria for the other curves. */ PEXSetCurveApprox( dpy, renderer, PEXOCRender, PEXApproxConstantBetweenKnots, (double)20 ); /* Third order curve. */ order = 3; num_knots = sizeof(knots_3ord)/sizeof(knots_3ord[0]); tmin = knots_3ord[order-1]; tmax = knots_3ord[num_knots - order]; for ( i = 0; i < 6; i++ ) /* shift it down a bit */ control_points[i].y -= 0.3; PEXNURBCurve( dpy, renderer, PEXOCRender, PEXNonRational, order, knots_3ord, num_points, cpts, tmin, tmax ); PEXMarkers( dpy, renderer, PEXOCRender, 6, control_points ); /* Sixth order curve. */ order = 6; num_knots = sizeof(knots_6ord)/sizeof(knots_6ord[0]); tmin = knots_6ord[order-1]; tmax = knots_6ord[num_knots - order]; for ( i = 0; i < 6; i++ ) /* shift it down a bit */ control_points[i].y -= 0.3; PEXNURBCurve( dpy, renderer, PEXOCRender, PEXNonRational, order, knots_6ord, num_points, cpts, tmin, tmax ); PEXMarkers( dpy, renderer, PEXOCRender, 6, control_points ); } PEXEndRendering( dpy, renderer, True ); XFlush( dpy ); } #define WIN_GEOM "500x500+50+50" main( argc, argv ) int argc; char *argv[]; { Display *dpy; Window window; XEvent event; XVisualInfo vis_info; XStandardColormap cmap_info; XColor bkgd_color; PEXColorApproxEntry capx_info; PEXRenderer renderer; PEXRendererAttributes rattrs; PEXExtensionInfo *pexinfo; int done = 0; /* Open a display and initialize PEX. */ dpy = ora_init_pex( argv, &pexinfo ); if ( !dpy ) exit(1); /* Determine the best visual to use. */ ora_find_best_visual( dpy, &vis_info ); /* Get a standard colormap for the visual. */ if ( !ora_get_standard_colormap( dpy, &vis_info, &cmap_info ) ) { fprintf ( stderr, "Cannot find a standard colormap\n" ); exit(1); } ora_set_stdcmap_approx( &vis_info, &cmap_info, &capx_info ); /* Create the window, giving it a gray background. */ bkgd_color.red = bkgd_color.green = bkgd_color.blue = 0x5555; bkgd_color.flags = DoRed | DoGreen | DoBlue; window = ora_create_window( dpy, &vis_info, &cmap_info, WIN_GEOM, &bkgd_color ); if ( IMMED_MODE_SPT( pexinfo ) ) { renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); } else { fprintf( stderr, "No immediate mode.\n" ); exit(1); } /* Read and respond to X events. */ XSelectInput( dpy, window, ExposureMask | ButtonPressMask ); while ( !done ) { XNextEvent( dpy, &event ); switch ( event.type ) { case Expose: /* Flush remaining Expose events, then redraw. */ while ( XCheckTypedWindowEvent( dpy, window, Expose, &event ) ) ; /* empty statement */ redraw( dpy, window, renderer ); break; case ButtonPress: done = 1; break; } } XCloseDisplay( dpy ); return 0; }