axis.c

Go to the documentation of this file.
00001 /*                          A X I S . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** \addtogroup axis */
00023 /*@{*/
00024 /** @file axis.c
00025  * @brief
00026  *      This routine is used to generate an axis for a graph.
00027  * It draws an axis with a linear scale, places tic marks every inch,
00028  * labels the tics, and uses the supplied title for the axis.
00029  *
00030  *      The strategy behind this routine is to split the axis
00031  * into SEGMENTS, which run from one tick to the next.  The
00032  * origin of the first segment (x,y), the origin of the bottom
00033  * of the first tick (xbott,ybott), and the origin of the first
00034  * tick label (xnum,ynum) are computed along with the delta x
00035  * and delta y (xincr,yincr) which describes the interval to
00036  * the start of the next tick.
00037  *
00038  *  @author
00039  *      Michael John Muuss
00040  *@n    August 01, 1978
00041  *
00042  *  @par Source -
00043  *      SECAD/VLD Computing Consortium, Bldg 394
00044  *@n    The U. S. Army Ballistic Research Laboratory
00045  *@n    Aberdeen Proving Ground, Maryland  21005-5066
00046  *
00047  */
00048 /*@}*/
00049 
00050 #ifndef lint
00051 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbn/axis.c,v 14.10 2006/09/02 14:02:14 lbutler Exp $ (BRL)";
00052 #endif
00053 
00054 #include "common.h"
00055 
00056 
00057 
00058 #include <stdio.h>
00059 #include <math.h>
00060 #ifdef HAVE_STRING_H
00061 #include <string.h>
00062 #else
00063 #include <strings.h>
00064 #endif
00065 
00066 #include "machine.h"
00067 #include "vmath.h"
00068 #include "plot3.h"
00069 
00070 #define TICK_YLEN       (char_width)    /**< @brief tick is 1 character height */
00071 #define NUM_YOFF        (3*char_width)  /**< @brief numbers offset from line */
00072 #define TITLE_YOFF      (5*char_width)  /**< @brief title offset from line */
00073 
00074 void
00075 /**
00076  *
00077  */
00078 tp_3axis(FILE *fp,
00079          char *string,          /**< label for axis */
00080          fastf_t *origin,
00081          fastf_t *rot,
00082          double length,         /**< length of axis */
00083          int ccw,               /**< 0=clockwise, !0=counter clockwise (ccw) */
00084          int ndigits,           /**< # digits wide */
00085          double label_start,    /**< label starting value */
00086          double label_incr,     /**< label increment between ticks */
00087          double tick_separation,/**< plot distance between ticks */
00088          double char_width)     /**< character scale (size) */
00089 {
00090         register int i;
00091         int     nticks;
00092         point_t tick_bottom;                    /* -Y point of tick */
00093         vect_t  axis_incr;                      /* +X vect between ticks */
00094         vect_t  axis_dir;
00095         point_t title_left;                     /* left edge of title */
00096         point_t cur_point;
00097         point_t num_start;
00098         point_t num_center;                     /* center point of number */
00099         point_t num_last_end;                   /* end of last number */
00100         vect_t  temp;
00101         vect_t  diff;
00102         mat_t   xlate_to_0;
00103         mat_t   mat;                            /* combined transform */
00104         char    fmt[32];
00105         char    str[64];
00106 
00107         /* Determine direction for ticks */
00108         if( ccw )
00109                 ccw = -1;                       /* counter clockwise */
00110         else
00111                 ccw = 1;                        /* clockwise */
00112 
00113         if( NEAR_ZERO(tick_separation, SMALL) )  tick_separation = 1;
00114 
00115         /*
00116          *  The point "origin" will be the center of the axis rotation.
00117          *  On the assumption that this origin point is not at (0,0,0),
00118          *  translate origin to (0,0,0) & apply the provided rotation matrix.
00119          *  If the user provides translation or
00120          *  scaling in his matrix, it will also be applied, but in most
00121          *  cases that would not be useful.
00122          */
00123         MAT_IDN( xlate_to_0 );
00124         MAT_DELTAS( xlate_to_0,  origin[X],  origin[Y],  origin[Z] );
00125         bn_mat_mul( mat, rot, xlate_to_0 );
00126         VMOVE( cur_point, origin );
00127 
00128         /* Compute the bottom of the first tick */
00129         VSET( temp, 0, -TICK_YLEN * ccw, 0 );
00130         MAT4X3PNT( tick_bottom, mat, temp );
00131 
00132         /* Compute the start of this tick's label */
00133         VSET( temp, 0, -NUM_YOFF * ccw, 0 );
00134         MAT4X3PNT( num_center, mat, temp );
00135         temp[X] = -char_width*ndigits;
00136         MAT4X3PNT( num_last_end, mat, temp );
00137 
00138         /* Determine the increment between ticks */
00139         VSET( temp, 1, 0, 0 );
00140         MAT4X3VEC( axis_dir, mat, temp );
00141         VSCALE( axis_incr, axis_dir, tick_separation );
00142 
00143         /* Center the title, and find left edge */
00144         VSET( temp, 0.5*(length - strlen(string)*char_width), -TITLE_YOFF*ccw, 0 );
00145         MAT4X3PNT( title_left, mat, temp );
00146         tp_3symbol(fp, string, title_left, rot, char_width );
00147 
00148         nticks = length/tick_separation+0.5;
00149         pdv_3move( fp, cur_point );
00150         for( i=0; i<=nticks; i++) {
00151                 /*
00152                  *  First, draw a tick.
00153                  *  Then, if room, draw a numeric label.
00154                  *  If last tick, done.
00155                  *  Otherwise, advance in axis_dir direction.
00156                  */
00157                 pdv_3cont( fp, tick_bottom );
00158 
00159                 if( ndigits > 0 )  {
00160                         double f;
00161                         sprintf( fmt, "%%%dg", ndigits);
00162                         sprintf( str, fmt, label_start );
00163                         f = strlen(str) * char_width * 0.5;
00164                         VJOIN1( num_start, num_center, -f, axis_dir );
00165 
00166                         /* Only label this tick if the number will not
00167                          * overlap with the previous number.
00168                          */
00169                         VSUB2( diff, num_start, num_last_end );
00170                         if( VDOT( diff, axis_dir ) >= 0 )  {
00171                                 tp_3symbol( fp, str, num_start, rot, char_width );
00172                                 VJOIN1( num_last_end, num_center, f, axis_dir );
00173                         }
00174                 }
00175 
00176                 if( i == nticks )  break;
00177 
00178                 /* Advance, and draw next axis segment */
00179                 pdv_3move( fp, cur_point );
00180                 VADD2( cur_point, cur_point, axis_incr );
00181                 VADD2( tick_bottom, tick_bottom, axis_incr );
00182                 VADD2( num_center, num_center, axis_incr );
00183 
00184                 label_start += label_incr;
00185 
00186                 pdv_3cont( fp, cur_point);              /* draw axis */
00187         }
00188 }
00189 
00190 void
00191 PL_FORTRAN(f3axis, F3AXIS)(fp, string, x, y, z, length, theta, ccw,
00192         ndigits, label_start, label_incr, tick_separation, char_width )
00193 FILE            **fp;
00194 char            *string;        /* label for axis */
00195 float           *x,*y,*z;               /* start coordinates for axis */
00196 float           *length;        /* length of axis */
00197 float           *theta;         /* rotation off X-axis, in degrees */
00198 int             *ccw;
00199 int             *ndigits;       /* # digits wide */
00200 float           *label_start;   /* minimum value on axis */
00201 float           *label_incr;            /* increment for each tick */
00202 float           *tick_separation;               /* distance between ticks */
00203 float           *char_width;    /* character scale (size) */
00204 {
00205         char buf[128];
00206         mat_t   mat;
00207         vect_t  pnt;
00208 
00209         VSET( pnt, *x, *y, *z );
00210         MAT_IDN(mat);
00211         bn_mat_angles( mat, 0.0, 0.0, *theta );
00212         strncpy( buf, string, sizeof(buf)-1 );
00213         buf[sizeof(buf)-1] = '\0';
00214         tp_3axis( *fp, buf, pnt, mat, *length, *ccw,
00215                 *ndigits, *label_start, *label_incr,
00216                 *tick_separation, *char_width );
00217 }
00218 /*@}*/
00219 /*
00220  * Local Variables:
00221  * mode: C
00222  * tab-width: 8
00223  * c-basic-offset: 4
00224  * indent-tabs-mode: t
00225  * End:
00226  * ex: shiftwidth=4 tabstop=8
00227  */

Generated on Mon Sep 18 01:24:47 2006 for BRL-CAD by  doxygen 1.4.6