BRL-CAD
axis.c
Go to the documentation of this file.
1 /* A X I S . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <stdio.h>
24 #include <math.h>
25 #include <string.h>
26 
27 #include "bu/log.h"
28 #include "bu/str.h"
29 #include "vmath.h"
30 #include "plot3.h"
31 
32 
33 #define TICK_YLEN (char_width) /**< @brief tick is 1 character height */
34 #define NUM_YOFF (3*char_width) /**< @brief numbers offset from line */
35 #define TITLE_YOFF (5*char_width) /**< @brief title offset from line */
36 
37 
38 void
39 tp_3axis(FILE *fp, /**< output file */
40  char *string, /**< label for axis */
41  fastf_t *origin, /**< simple 3d point */
42  fastf_t *rot, /**< rotation angle */
43  double length, /**< length of axis */
44  int ccw, /**< 0=clockwise, !0=counter clockwise (ccw) */
45  int ndigits, /**< # digits wide */
46  double label_start, /**< label starting value */
47  double label_incr, /**< label increment between ticks */
48  double tick_separation, /**< plot distance between ticks */
49  double char_width) /**< character scale (size) */
50 {
51  register int i;
52  int nticks;
53  point_t tick_bottom; /* -Y point of tick */
54  vect_t axis_incr; /* +X vect between ticks */
55  vect_t axis_dir;
56  point_t title_left; /* left edge of title */
57  point_t cur_point;
58  point_t num_start;
59  point_t num_center; /* center point of number */
60  point_t num_last_end; /* end of last number */
61  vect_t temp;
62  vect_t diff;
63  mat_t xlate_to_0;
64  mat_t mat; /* combined transform */
65  char fmt[32];
66  char str[64];
67 
68  /* Determine direction for ticks */
69  if (ccw)
70  ccw = -1; /* counter clockwise */
71  else
72  ccw = 1; /* clockwise */
73 
74  if (ZERO(tick_separation)) tick_separation = 1;
75 
76  /*
77  * The point "origin" will be the center of the axis rotation.
78  * On the assumption that this origin point is not at (0, 0, 0),
79  * translate origin to (0, 0, 0) & apply the provided rotation matrix.
80  * If the user provides translation or
81  * scaling in his matrix, it will also be applied, but in most
82  * cases that would not be useful.
83  */
84  MAT_IDN(xlate_to_0);
85  MAT_DELTAS_VEC(xlate_to_0, origin);
86  bn_mat_mul(mat, rot, xlate_to_0);
87  VMOVE(cur_point, origin);
88 
89  /* Compute the bottom of the first tick */
90  VSET(temp, 0, -TICK_YLEN * ccw, 0);
91  MAT4X3PNT(tick_bottom, mat, temp);
92 
93  /* Compute the start of this tick's label */
94  VSET(temp, 0, -NUM_YOFF * ccw, 0);
95  MAT4X3PNT(num_center, mat, temp);
96  temp[X] = -char_width*ndigits;
97  MAT4X3PNT(num_last_end, mat, temp);
98 
99  /* Determine the increment between ticks */
100  VSET(temp, 1, 0, 0);
101  MAT4X3VEC(axis_dir, mat, temp);
102  VSCALE(axis_incr, axis_dir, tick_separation);
103 
104  /* Center the title, and find left edge */
105  VSET(temp, 0.5*(length - strlen(string)*char_width), -TITLE_YOFF*ccw, 0);
106  MAT4X3PNT(title_left, mat, temp);
107  tp_3symbol(fp, string, title_left, rot, char_width);
108 
109  nticks = length/tick_separation+0.5;
110  pdv_3move(fp, cur_point);
111  for (i=0; i<=nticks; i++) {
112  /*
113  * First, draw a tick.
114  * Then, if room, draw a numeric label.
115  * If last tick, done.
116  * Otherwise, advance in axis_dir direction.
117  */
118  pdv_3cont(fp, tick_bottom);
119 
120  if (ndigits > 64) {
121  bu_bomb("ERROR: Number of digits exceeds available buffer space");
122  }
123 
124  if (ndigits > 0) {
125  double f;
126  snprintf(fmt, 32, "%%%dg", ndigits);
127  snprintf(str, 64, fmt, label_start);
128  f = strlen(str) * char_width * 0.5;
129  VJOIN1(num_start, num_center, -f, axis_dir);
130 
131  /* Only label this tick if the number will not
132  * overlap with the previous number.
133  */
134  VSUB2(diff, num_start, num_last_end);
135  if (VDOT(diff, axis_dir) >= 0) {
136  tp_3symbol(fp, str, num_start, rot, char_width);
137  VJOIN1(num_last_end, num_center, f, axis_dir);
138  }
139  }
140 
141  if (i == nticks) break;
142 
143  /* Advance, and draw next axis segment */
144  pdv_3move(fp, cur_point);
145  VADD2(cur_point, cur_point, axis_incr);
146  VADD2(tick_bottom, tick_bottom, axis_incr);
147  VADD2(num_center, num_center, axis_incr);
148 
149  label_start += label_incr;
150 
151  pdv_3cont(fp, cur_point); /* draw axis */
152  }
153 }
154 
155 
156 void
157 PL_FORTRAN(f3axis, F3AXIS)(FILE **fp,
158  char *string /* label for axis */,
159  float *x, float *y, float *z /* start coordinates for axis */,
160  float *length /* length of axis */,
161  float *theta /* rotation off X-axis, in degrees */,
162  int *ccw,
163  int *ndigits /* # digits wide */,
164  float *label_start /* minimum value on axis */,
165  float *label_incr /* increment for each tick */,
166  float *tick_separation /* distance between ticks */,
167  float *char_width /* character scale (size) */)
168 {
169  char buf[128];
170  mat_t mat;
171  vect_t pnt;
172 
173  VSET(pnt, *x, *y, *z);
174  MAT_IDN(mat);
175  bn_mat_angles(mat, 0.0, 0.0, *theta);
176  bu_strlcpy(buf, string, sizeof(buf));
177 
178  tp_3axis(*fp, buf, pnt, mat, *length, *ccw,
179  *ndigits, *label_start, *label_incr,
180  *tick_separation, *char_width);
181 }
182 
183 /*
184  * Local Variables:
185  * mode: C
186  * tab-width: 8
187  * indent-tabs-mode: t
188  * c-file-style: "stroustrup"
189  * End:
190  * ex: shiftwidth=4 tabstop=8
191  */
#define TICK_YLEN
tick is 1 character height
Definition: axis.c:33
void pdv_3move(register FILE *plotfp, const fastf_t *pt)
Definition: plot3.c:618
#define VSET(a, b, c, d)
Definition: color.c:53
Header file for the BRL-CAD common definitions.
void PL_FORTRAN(f3axis, F3AXIS)
Definition: axis.c:157
Definition: color.c:49
#define NUM_YOFF
numbers offset from line
Definition: axis.c:34
void tp_3axis(FILE *fp, char *string, fastf_t *origin, fastf_t *rot, double length, int ccw, int ndigits, double label_start, double label_incr, double tick_separation, double char_width)
Definition: axis.c:39
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
#define TITLE_YOFF
title offset from line
Definition: axis.c:35
void pdv_3cont(register FILE *plotfp, const fastf_t *pt)
Definition: plot3.c:630
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
void bn_mat_angles(mat_t mat, double alpha, double beta, double ggamma)
#define ZERO(val)
Definition: units.c:38
void tp_3symbol(FILE *fp, char *string, fastf_t *origin, fastf_t *rot, double scale)
Definition: symbol.c:51
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
double fastf_t
Definition: defines.h:300