/* $Id: hpgl.c,v 1.1 2007/05/24 18:20:43 Kevin Bacon Exp $ */ /* A program to drive a couple of stepper motors */ /* HPGL reader */ #include #include #include #include #include "libesketch.h" #define NPOINTS 200000 #define POINT_DONE 0 #define POINT_START 1 #define POINT_MIDDLE 2 #define POINT_END 3 struct point { int x; int y; int flags; }; void small_remove( struct point *points, int n_points, int min_size ) { int i; int j; int start_i; int min_x, min_y, max_x, max_y; printf( "small_remove\n" ); for( i = 0; i < n_points; i++ ) { if( points[i].flags == POINT_START ) { start_i = i; min_x = max_x = points[i].x; min_y = max_y = points[i].y; } min_x = MIN( min_x, points[i].x ); max_x = MAX( max_x, points[i].x ); min_y = MIN( min_y, points[i].y ); max_y = MAX( max_y, points[i].y ); if( points[i].flags == POINT_END ) { if((( max_x - min_x ) < min_size ) && (( max_y - min_y ) < min_size )) { printf( "size_x=%d, size_y=%d removing %d-%d\n", max_x - min_x, max_y - min_y, start_i, i ); for( j = start_i; j <= i; j++ ) { points[j].flags = POINT_DONE; } } } } } int main( int argc, char **argv ) { int a, b; int x, y; int i; struct point *points; int current_point = 0; int dist, min; int min_i; float scale = 0.1; int down = 0; int sort = 0; int min_size = 100; points = malloc( NPOINTS * sizeof( struct point )); if( points == NULL ) { printf( "Error: Can't allocate %d points\n", NPOINTS ); exit( 1 ); } printf( "Usage: hpgl [scale [stretch]][sort] (default is %g %d)\n", scale, stretch ); if( argc >= 2 ) scale = atof( argv[1] ); if( argc >= 3 ) stretch = atoi( argv[2] ); for( i = 1; i < argc; i++ ) { if( strcmp( argv[i], "sort" ) == 0 ) sort = 1; } printf( "scale=%g, stretch=%d, sort=%d\n", scale, stretch, sort ); /* Init libesketch */ init(); while( 1 ) { if( current_point >= NPOINTS ) { printf( "ERROR: too many points\n" ); break; } // Read command characters a = getchar(); b = getchar(); if( a == EOF || b == EOF ) break; // Check for plot absolute command if(( tolower( a ) == 'p' ) && ( tolower( b ) == 'a' )) { while( 1 ) { // Read coordinates i = scanf( "%d,%d", &x, &y ); if( i != 2 ) break; if( down ) { points[ current_point ].x = x; points[ current_point ].y = y; points[ current_point ].flags = POINT_MIDDLE; //printf( "%c (%d,%d) %d\n", c, points[current_point].x, points[current_point].y, points[current_point].flags ); current_point++; } a = getchar(); if( a == ';' || a == EOF ) break; } } else if(( tolower( a ) == 'p' ) && ( tolower( b ) == 'd' )) { // Mark point as start points[ current_point ].x = x; points[ current_point ].y = y; points[ current_point ].flags = POINT_START; //printf( "%c (%d,%d) %d\n", c, points[current_point].x, points[current_point].y, points[current_point].flags ); current_point++; down = 1; a = getchar(); continue; } else if(( tolower( a ) == 'p' ) && ( tolower( b ) == 'u' )) { // Mark point as end points[ current_point ].x = x; points[ current_point ].y = y; points[ current_point ].flags = POINT_END; //printf( "%c (%d,%d) %d\n", c, points[current_point].x, points[current_point].y, points[current_point].flags ); current_point++; down = 0; a = getchar(); continue; } // else discard the rest of the line else { while( 1 ) { a = getchar(); if( a == ';' || a == EOF ) break; } } } printf( "total points = %d\n", current_point ); // Remove small regions small_remove( points, current_point, min_size ); if( !sort ) { for( i = 0; i < current_point; i++ ) { // printf( "(%d,%d) %d\n", points[i].x, points[i].y, points[i].flags ); if( points[i].flags != POINT_DONE ) { drawto( scale * points[i].x, scale * points[i].y ); } } } else { // Loop until all points drawn x = y = 0; while( 1 ) { // Find nearest start/end point to current point min = 10000 * 10000; min_i = -1; for( i = 0; i < current_point; i++ ) { if( points[i].flags == POINT_START || points[i].flags == POINT_END ) { dist = ( points[i].x - x ) * ( points[i].x - x ) + ( points[i].y - y ) * ( points[i].y - y ); if( dist < min ) { min = dist; min_i = i; } } } // Stop when no start/end found if( min_i == -1 ) break; // Draw this path forwards or backwards if( points[min_i].flags == POINT_START ) { while( 1 ) { x = points[min_i].x; y = points[min_i].y; drawto( scale * x, scale * y ); if( points[min_i].flags == POINT_END ) break; points[min_i].flags = POINT_DONE; min_i++; } // Set the last flag points[min_i].flags = POINT_DONE; } else { while( 1 ) { x = points[min_i].x; y = points[min_i].y; drawto( scale * x, scale * y ); if( points[min_i].flags == POINT_START ) break; points[min_i].flags = POINT_DONE; min_i--; } // Set the last flag points[min_i].flags = POINT_DONE; } } } /* Turn off motor drivers */ stop(); return 0; }