version 1.1.1.2, 2000/01/22 14:15:57 |
version 1.1.1.3, 2003/09/15 07:09:24 |
Line 37 static char *RCSid = "$Id$"; |
|
Line 37 static char *RCSid = "$Id$"; |
|
|
|
#include "plot.h" |
#include "plot.h" |
#include "setshow.h" |
#include "setshow.h" |
|
#include "alloc.h" |
|
|
/* key placement is calculated in boundary, so we need file-wide variables |
/* key placement is calculated in boundary, so we need file-wide variables |
* To simplify adjustments to the key, we set all these once [depends on |
* To simplify adjustments to the key, we set all these once [depends on |
Line 137 static double make_tics __PROTO((int axis, int guide)) |
|
Line 138 static double make_tics __PROTO((int axis, int guide)) |
|
/* widest2d_callback keeps longest so far in here */ |
/* widest2d_callback keeps longest so far in here */ |
static int widest_tic; |
static int widest_tic; |
|
|
static void widest2d_callback __PROTO((int axis, double place, char *text, |
/* HBB 20010118: these should be static, but can't --- HP-UX assembler bug */ |
struct lp_style_type grid)); |
void widest2d_callback __PROTO((int axis, double place, char *text, |
static void ytick2d_callback __PROTO((int axis, double place, char *text, |
struct lp_style_type grid)); |
struct lp_style_type grid)); |
void ytick2d_callback __PROTO((int axis, double place, char *text, |
static void xtick2d_callback __PROTO((int axis, double place, char *text, |
struct lp_style_type grid)); |
struct lp_style_type grid)); |
void xtick2d_callback __PROTO((int axis, double place, char *text, |
|
struct lp_style_type grid)); |
|
int histeps_compare __PROTO((SORTFUNC_ARGS p1, SORTFUNC_ARGS p2)); |
static void map_position __PROTO((struct position * pos, unsigned int *x, |
static void map_position __PROTO((struct position * pos, unsigned int *x, |
unsigned int *y, char *what)); |
unsigned int *y, char *what)); |
static void mant_exp __PROTO((double log_base, double x, int scientific, |
static void mant_exp __PROTO((double log_base, double x, int scientific, |
Line 244 static double scale[AXIS_ARRAY_SIZE]; /* scale factors |
|
Line 247 static double scale[AXIS_ARRAY_SIZE]; /* scale factors |
|
|
|
/* (DFK) Watch for cancellation error near zero on axes labels */ |
/* (DFK) Watch for cancellation error near zero on axes labels */ |
/* less than one hundredth of a tic mark */ |
/* less than one hundredth of a tic mark */ |
#define SIGNIF (0.01) |
|
#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x)) |
#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x)) |
#define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF)) |
#define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF)) |
/*}}} */ |
/*}}} */ |
Line 425 char *axis_name; |
|
Line 427 char *axis_name; |
|
/* we determine widest tick label by getting gen_ticks to call this |
/* we determine widest tick label by getting gen_ticks to call this |
* routine with every label |
* routine with every label |
*/ |
*/ |
|
/* HBB 20010118: all the *_callback() functions made non-static. This |
|
* is necessary to work around a bug in HP's assembler shipped with |
|
* HP-UX 10 and higher, if GCC tries to use it */ |
|
|
static void widest2d_callback(axis, place, text, grid) |
void widest2d_callback(axis, place, text, grid) |
int axis; |
int axis; |
double place; |
double place; |
char *text; |
char *text; |
Line 461 struct lp_style_type grid; |
|
Line 466 struct lp_style_type grid; |
|
*/ |
*/ |
|
|
static void boundary(scaling, plots, count) |
static void boundary(scaling, plots, count) |
TBOOLEAN scaling; /* TRUE if terminal is doing the scaling */ |
TBOOLEAN scaling; /* TRUE if terminal is doing the scaling */ |
struct curve_points *plots; |
struct curve_points *plots; |
int count; |
int count; |
{ |
{ |
int ytlen; |
int ytlen; |
int yticlin = 0, y2ticlin = 0, timelin = 0; |
int yticlin = 0, y2ticlin = 0, timelin = 0; |
|
|
/* compute ytop from the various components |
/* compute ytop from the various components |
* unless tmargin is explicitly specified */ |
* unless tmargin is explicitly specified */ |
|
|
ytop = (int) ((ysize + yoffset) * (t->ymax)); |
/* HBB 20020426: fix round-off bug --- in 3.8 since 20010118 ;-[ */ |
|
ytop = (int) (0.5 + (ysize + yoffset) * (t->ymax)); |
|
|
if (tmargin < 0) { |
if (tmargin < 0) { |
int top_margin = x2label_textheight + title_textheight; |
int top_margin = x2label_textheight + title_textheight; |
|
|
/* compute ybot from the various components |
/* compute ybot from the various components |
* unless bmargin is explicitly specified */ |
* unless bmargin is explicitly specified */ |
|
|
ybot = (int) ((t->ymax) * yoffset); |
ybot = (int) (0.5 + (t->ymax) * yoffset); |
|
|
if (bmargin < 0) { |
if (bmargin < 0) { |
ybot += xtic_height + xtic_textheight; |
ybot += xtic_height + xtic_textheight; |
|
|
if (key_entry_height < (t->v_char)) |
if (key_entry_height < (t->v_char)) |
key_entry_height = (t->v_char) * key_vert_factor; |
key_entry_height = (t->v_char) * key_vert_factor; |
|
|
|
/* HBB 20020122: safeguard to prevent division by zero later */ |
|
if (key_entry_height == 0) |
|
key_entry_height = 1; |
|
|
/* count max_len key and number keys with len > 0 */ |
/* count max_len key and number keys with len > 0 */ |
max_ptitl_len = find_maxl_keys(plots, count, &ptitl_cnt); |
max_ptitl_len = find_maxl_keys(plots, count, &ptitl_cnt); |
if ((ytlen = label_width(key_title, &ktitl_lines)) > max_ptitl_len) |
if ((ytlen = label_width(key_title, &ktitl_lines)) > max_ptitl_len) |
|
|
/* compute xleft from the various components |
/* compute xleft from the various components |
* unless lmargin is explicitly specified */ |
* unless lmargin is explicitly specified */ |
|
|
xleft = (int) ((t->xmax) * xoffset); |
xleft = (int) (0.5 + (t->xmax) * xoffset); |
|
|
if (lmargin < 0) { |
if (lmargin < 0) { |
xleft += (timelabel_textwidth > ylabel_textwidth ? timelabel_textwidth : ylabel_textwidth) |
xleft += (timelabel_textwidth > ylabel_textwidth ? timelabel_textwidth : ylabel_textwidth) |
|
|
/* compute xright from the various components |
/* compute xright from the various components |
* unless rmargin is explicitly specified */ |
* unless rmargin is explicitly specified */ |
|
|
xright = (int) ((t->xmax) * (xsize + xoffset)); |
xright = (int) (0.5 + (t->xmax) * (xsize + xoffset)); |
|
|
if (rmargin < 0) { |
if (rmargin < 0) { |
/* xright -= y2label_textwidth + y2tic_width + y2tic_textwidth; */ |
/* xright -= y2label_textwidth + y2tic_width + y2tic_textwidth; */ |
|
|
|
|
if (vertical_timelabel) { |
if (vertical_timelabel) { |
if (timelabel_bottom) |
if (timelabel_bottom) |
time_y = xlabel_y - timebot_textheight + xlabel_textheight; |
time_y = ybot - xtic_height - xtic_textheight - xlabel_textheight - timebot_textheight + t->v_char; |
else { |
else { |
time_y = title_y + timetop_textheight - title_textheight - x2label_textheight; |
time_y = title_y + timetop_textheight - title_textheight - x2label_textheight; |
} |
} |
Line 1175 double amin, amax; |
|
Line 1185 double amin, amax; |
|
*/ |
*/ |
|
|
double set_tic(l10, guide) |
double set_tic(l10, guide) |
double l10; |
double l10; |
int guide; |
int guide; |
{ |
{ |
double xnorm, tics, posns; |
double xnorm, tics, posns; |
|
|
|
|
|
|
/*{{{ make_tics() */ |
/*{{{ make_tics() */ |
static double make_tics(axis, guide) |
static double make_tics(axis, guide) |
int axis, guide; |
int axis, guide; |
{ |
{ |
register double xr, tic, l10; |
register double xr, tic, l10; |
|
|
Line 1285 int axis, guide; |
|
Line 1295 int axis, guide; |
|
|
|
|
|
void do_plot(plots, pcount) |
void do_plot(plots, pcount) |
struct curve_points *plots; |
struct curve_points *plots; |
int pcount; /* count of plots in linked list */ |
int pcount; /* count of plots in linked list */ |
{ |
{ |
|
|
/* BODGES BEFORE I FIX IT UP */ |
|
#define ytic ticstep[y_axis] |
|
#define xtic ticstep[x_axis] |
|
|
|
register struct termentry *t = term; |
register struct termentry *t = term; |
register int curve; |
register int curve; |
int axis_zero[AXIS_ARRAY_SIZE]; /* axes in terminal coords for FIRST_X_AXIS, etc */ |
int axis_zero[AXIS_ARRAY_SIZE]; /* axes in terminal coords for FIRST_X_AXIS, etc */ |
Line 1369 int pcount; /* count of plots in linked list */ |
|
Line 1374 int pcount; /* count of plots in linked list */ |
|
|
|
/* label first y axis tics */ |
/* label first y axis tics */ |
if (ytics) { |
if (ytics) { |
int axis = map_x(ZERO); |
|
/* set the globals ytick2d_callback() needs */ |
/* set the globals ytick2d_callback() needs */ |
|
|
if (rotate_ytics && (*t->text_angle) (1)) { |
if (rotate_ytics && (*t->text_angle) (1)) { |
Line 1388 int pcount; /* count of plots in linked list */ |
|
Line 1392 int pcount; /* count of plots in linked list */ |
|
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
|
|
if ((ytics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(axis, xleft, xright)) { |
if ((ytics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(0.0, x_min, x_max)) { |
tic_start = axis; |
tic_start = map_x(0.0); |
tic_direction = -1; |
tic_direction = -1; |
if (ytics & TICS_MIRROR) |
if (ytics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1409 int pcount; /* count of plots in linked list */ |
|
Line 1413 int pcount; /* count of plots in linked list */ |
|
} |
} |
/* label first x axis tics */ |
/* label first x axis tics */ |
if (xtics) { |
if (xtics) { |
int axis = map_y(ZERO); |
|
/* set the globals xtick2d_callback() needs */ |
/* set the globals xtick2d_callback() needs */ |
|
|
if (rotate_xtics && (*t->text_angle) (1)) { |
if (rotate_xtics && (*t->text_angle) (1)) { |
Line 1426 int pcount; /* count of plots in linked list */ |
|
Line 1429 int pcount; /* count of plots in linked list */ |
|
tic_mirror = ytop; |
tic_mirror = ytop; |
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
if ((xtics & TICS_ON_AXIS) && !log_array[FIRST_Y_AXIS] && inrange(axis, ybot, ytop)) { |
if ((xtics & TICS_ON_AXIS) && !log_array[FIRST_Y_AXIS] && inrange(0.0, y_min, y_max)) { |
tic_start = axis; |
tic_start = map_y(0.0); |
tic_direction = -1; |
tic_direction = -1; |
if (xtics & TICS_MIRROR) |
if (xtics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1454 int pcount; /* count of plots in linked list */ |
|
Line 1457 int pcount; /* count of plots in linked list */ |
|
/* label second y axis tics */ |
/* label second y axis tics */ |
if (y2tics) { |
if (y2tics) { |
/* set the globalss ytick2d_callback() needs */ |
/* set the globalss ytick2d_callback() needs */ |
int axis = map_x(ZERO); |
|
|
|
if (rotate_y2tics && (*t->text_angle) (1)) { |
if (rotate_y2tics && (*t->text_angle) (1)) { |
tic_hjust = CENTRE; |
tic_hjust = CENTRE; |
Line 1470 int pcount; /* count of plots in linked list */ |
|
Line 1472 int pcount; /* count of plots in linked list */ |
|
tic_mirror = xleft; |
tic_mirror = xleft; |
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
if ((y2tics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(axis, xleft, xright)) { |
if ((y2tics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(0.0, x_min, x_max)) { |
tic_start = axis; |
tic_start = map_x(0.0); |
tic_direction = 1; |
tic_direction = 1; |
if (y2tics & TICS_MIRROR) |
if (y2tics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1490 int pcount; /* count of plots in linked list */ |
|
Line 1492 int pcount; /* count of plots in linked list */ |
|
} |
} |
/* label second x axis tics */ |
/* label second x axis tics */ |
if (x2tics) { |
if (x2tics) { |
int axis = map_y(ZERO); |
|
/* set the globals xtick2d_callback() needs */ |
/* set the globals xtick2d_callback() needs */ |
|
|
if (rotate_x2tics && (*t->text_angle) (1)) { |
if (rotate_x2tics && (*t->text_angle) (1)) { |
Line 1507 int pcount; /* count of plots in linked list */ |
|
Line 1508 int pcount; /* count of plots in linked list */ |
|
tic_mirror = ybot; |
tic_mirror = ybot; |
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
if ((x2tics & TICS_ON_AXIS) && !log_array[SECOND_Y_AXIS] && inrange(axis, ybot, ytop)) { |
if ((x2tics & TICS_ON_AXIS) && !log_array[SECOND_Y_AXIS] && inrange(0.0, y_min, y_max)) { |
tic_start = axis; |
tic_start = map_y(0.0); |
tic_direction = 1; |
tic_direction = 1; |
if (x2tics & TICS_MIRROR) |
if (x2tics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1560 int pcount; /* count of plots in linked list */ |
|
Line 1561 int pcount; /* count of plots in linked list */ |
|
|
|
x_axis = FIRST_X_AXIS; |
x_axis = FIRST_X_AXIS; |
y_axis = FIRST_Y_AXIS; /* chose scaling */ |
y_axis = FIRST_Y_AXIS; /* chose scaling */ |
axis_zero[FIRST_Y_AXIS] = map_y(0.0); |
|
axis_zero[FIRST_X_AXIS] = map_x(0.0); |
|
|
|
if (axis_zero[FIRST_Y_AXIS] < ybot || is_log_y) |
if (y_min >= 0.0 && y_max >= 0.0 || is_log_y) |
axis_zero[FIRST_Y_AXIS] = ybot; /* save for impulse plotting */ |
axis_zero[FIRST_Y_AXIS] = ybot; /* save for impulse plotting */ |
else if (axis_zero[FIRST_Y_AXIS] >= ytop) |
else if (y_min <= 0.0 && y_max <= 0.0) |
axis_zero[FIRST_Y_AXIS] = ytop; |
axis_zero[FIRST_Y_AXIS] = ytop; |
else if (xzeroaxis.l_type > -3) { |
else { |
term_apply_lp_properties(&xzeroaxis); |
axis_zero[FIRST_Y_AXIS] = map_y(0.0); |
(*t->move) (xleft, axis_zero[FIRST_Y_AXIS]); |
if (xzeroaxis.l_type > -3) { |
(*t->vector) (xright, axis_zero[FIRST_Y_AXIS]); |
term_apply_lp_properties(&xzeroaxis); |
|
(*t->move) (xleft, axis_zero[FIRST_Y_AXIS]); |
|
(*t->vector) (xright, axis_zero[FIRST_Y_AXIS]); |
|
} |
} |
} |
if ((yzeroaxis.l_type > -3) && !is_log_x |
if (x_min >= 0.0 && x_max >= 0.0) |
&& axis_zero[FIRST_X_AXIS] >= xleft |
axis_zero[FIRST_X_AXIS] = xleft; |
&& axis_zero[FIRST_X_AXIS] < xright) { |
else if (x_min <= 0.0 && x_max <= 0.0) |
term_apply_lp_properties(&yzeroaxis); |
axis_zero[FIRST_X_AXIS] = xright; |
(*t->move) (axis_zero[FIRST_X_AXIS], ybot); |
else { |
(*t->vector) (axis_zero[FIRST_X_AXIS], ytop); |
axis_zero[FIRST_X_AXIS] = map_x(0.0); |
|
if ((yzeroaxis.l_type > -3) && !is_log_x) { |
|
term_apply_lp_properties(&yzeroaxis); |
|
(*t->move) (axis_zero[FIRST_X_AXIS], ybot); |
|
(*t->vector) (axis_zero[FIRST_X_AXIS], ytop); |
|
} |
} |
} |
|
|
x_axis = SECOND_X_AXIS; |
x_axis = SECOND_X_AXIS; |
y_axis = SECOND_Y_AXIS; /* chose scaling */ |
y_axis = SECOND_Y_AXIS; /* chose scaling */ |
axis_zero[SECOND_Y_AXIS] = map_y(0.0); |
|
axis_zero[SECOND_X_AXIS] = map_x(0.0); |
|
|
|
if (axis_zero[SECOND_Y_AXIS] < ybot || is_log_y2) |
if (is_log_y2 || y_min >= 0.0 && y_max >= 0.0) |
axis_zero[SECOND_Y_AXIS] = ybot; /* save for impulse plotting */ |
axis_zero[SECOND_Y_AXIS] = ybot; /* save for impulse plotting */ |
else if (axis_zero[SECOND_Y_AXIS] >= ytop) |
else if (y_min <= 0.0 && y_max <= 0.0) |
axis_zero[SECOND_Y_AXIS] = ytop; |
axis_zero[SECOND_Y_AXIS] = ytop; |
else if (x2zeroaxis.l_type > -3) { |
else { |
term_apply_lp_properties(&x2zeroaxis); |
axis_zero[SECOND_Y_AXIS] = map_y(0.0); |
(*t->move) (xleft, axis_zero[SECOND_Y_AXIS]); |
if (x2zeroaxis.l_type > -3) { |
(*t->vector) (xright, axis_zero[SECOND_Y_AXIS]); |
term_apply_lp_properties(&x2zeroaxis); |
|
(*t->move) (xleft, axis_zero[SECOND_Y_AXIS]); |
|
(*t->vector) (xright, axis_zero[SECOND_Y_AXIS]); |
|
} |
} |
} |
if ((y2zeroaxis.l_type > -3) && !is_log_x2 && |
if (y_min >= 0.0 && y_max >= 0.0) |
axis_zero[SECOND_X_AXIS] >= xleft && |
axis_zero[SECOND_X_AXIS] = xleft; |
axis_zero[SECOND_X_AXIS] < xright) { |
else if (x_min <= 0.0 && x_max <= 0.0) |
term_apply_lp_properties(&y2zeroaxis); |
axis_zero[SECOND_X_AXIS] = xright; |
(*t->move) (axis_zero[SECOND_X_AXIS], ybot); |
else { |
(*t->vector) (axis_zero[SECOND_X_AXIS], ytop); |
axis_zero[SECOND_X_AXIS] = map_x(0.0); |
|
if ((y2zeroaxis.l_type > -3) && !is_log_x2) { |
|
term_apply_lp_properties(&y2zeroaxis); |
|
(*t->move) (axis_zero[SECOND_X_AXIS], ybot); |
|
(*t->vector) (axis_zero[SECOND_X_AXIS], ytop); |
|
} |
} |
} |
/* DRAW PLOT BORDER */ |
/* DRAW PLOT BORDER */ |
if (draw_border) { |
if (draw_border) { |
Line 1755 int pcount; /* count of plots in linked list */ |
|
Line 1769 int pcount; /* count of plots in linked list */ |
|
(*t->put_text) (xl + key_text_right, yl, s); |
(*t->put_text) (xl + key_text_right, yl, s); |
} else { |
} else { |
int x = xl + key_text_right - (t->h_char) * strlen(s); |
int x = xl + key_text_right - (t->h_char) * strlen(s); |
if (key_hpos == TOUT || inrange(x, xleft, xright)) |
if (key_hpos == TOUT || |
|
key_vpos == TUNDER || /* HBB 990327 */ |
|
inrange(x, xleft, xright)) |
(*t->put_text) (x, yl, s); |
(*t->put_text) (x, yl, s); |
} |
} |
} |
} |
Line 1808 int pcount; /* count of plots in linked list */ |
|
Line 1824 int pcount; /* count of plots in linked list */ |
|
} else { |
} else { |
int x = xl + key_text_right - (t->h_char) * strlen(this_plot->title); |
int x = xl + key_text_right - (t->h_char) * strlen(this_plot->title); |
if (key_hpos == TOUT || |
if (key_hpos == TOUT || |
|
key_vpos == TUNDER || /* HBB 990327 */ |
i_inrange(x, xleft, xright)) |
i_inrange(x, xleft, xright)) |
(*t->put_text) (x, yl, this_plot->title); |
(*t->put_text) (x, yl, this_plot->title); |
} |
} |
Line 1958 int pcount; /* count of plots in linked list */ |
|
Line 1975 int pcount; /* count of plots in linked list */ |
|
} |
} |
|
|
|
|
/* BODGES */ |
|
#undef ytic |
|
#undef xtic |
|
|
|
/* plot_impulses: |
/* plot_impulses: |
* Plot the curves in IMPULSES style |
* Plot the curves in IMPULSES style |
*/ |
*/ |
Line 2213 struct curve_points *plot; |
|
Line 2226 struct curve_points *plot; |
|
} |
} |
} |
} |
|
|
|
/* HBB 20010625: replaced homegrown bubblesort in plot_histeps() by |
|
* call of standard routine qsort(). Need to tell the compare function |
|
* about the plotted dataset via this file scope variable: */ |
|
static struct curve_points *histeps_current_plot; |
|
|
|
/* NOTE: I'd have made the comp.function 'static', but the HP-sUX gcc |
|
* bug seems to forbid that :-( */ |
|
int |
|
histeps_compare(p1, p2) |
|
SORTFUNC_ARGS p1; |
|
SORTFUNC_ARGS p2; |
|
{ |
|
double x1=histeps_current_plot->points[*(int *)p1].x; |
|
double x2=histeps_current_plot->points[*(int *)p2].x; |
|
|
|
if (x1 < x2) |
|
return -1; |
|
else |
|
return (x2 > x1); |
|
} |
|
|
/* CAC */ |
/* CAC */ |
/* plot_histeps: |
/* plot_histeps: |
* Plot the curves in HISTEPS style |
* Plot the curves in HISTEPS style |
Line 2221 static void plot_histeps(plot) |
|
Line 2255 static void plot_histeps(plot) |
|
struct curve_points *plot; |
struct curve_points *plot; |
{ |
{ |
int i; /* point index */ |
int i; /* point index */ |
int hold, bigi; /* indices for sorting */ |
|
int xl, yl; /* cursor position in terminal coordinates */ |
int xl, yl; /* cursor position in terminal coordinates */ |
struct termentry *t = term; |
struct termentry *t = term; |
double x, y, xn, yn; /* point position */ |
double x, y, xn, yn; /* point position */ |
|
double y_null; /* y coordinate of histogram baseline */ |
int *gl, goodcount; /* array to hold list of valid points */ |
int *gl, goodcount; /* array to hold list of valid points */ |
|
|
/* preliminary count of points inside array */ |
/* preliminary count of points inside array */ |
Line 2236 struct curve_points *plot; |
|
Line 2270 struct curve_points *plot; |
|
if (goodcount < 2) |
if (goodcount < 2) |
return; /* cannot plot less than 2 points */ |
return; /* cannot plot less than 2 points */ |
|
|
gl = (int *) gp_alloc(goodcount * sizeof(int), "histeps valid point mapping"); |
gl = gp_alloc(goodcount * sizeof(int), "histeps valid point mapping"); |
if (gl == NULL) |
if (gl == NULL) |
return; |
return; |
|
|
Line 2248 struct curve_points *plot; |
|
Line 2282 struct curve_points *plot; |
|
gl[goodcount] = i; |
gl[goodcount] = i; |
++goodcount; |
++goodcount; |
} |
} |
/* sort the data */ |
|
for (bigi = i = 1; i < goodcount;) { |
|
if (plot->points[gl[i]].x < plot->points[gl[i - 1]].x) { |
|
hold = gl[i]; |
|
gl[i] = gl[i - 1]; |
|
gl[i - 1] = hold; |
|
if (i > 1) { |
|
i--; |
|
continue; |
|
} |
|
} |
|
i = ++bigi; |
|
} |
|
|
|
|
/* sort the data --- tell histeps_compare about the plot |
|
* datastructure to look at, then call qsort() */ |
|
histeps_current_plot = plot; |
|
qsort(gl, goodcount, sizeof(*gl), histeps_compare); |
|
/* play it safe: invalidate the static pointer after usage */ |
|
histeps_current_plot = NULL; |
|
|
|
/* HBB 20010625: log y axis must treat 0.0 as -infinity. Define |
|
* the correct y position for the histogram's baseline once. It'll |
|
* be used twice (once for each endpoint of the histogram). */ |
|
if (log_array[y_axis]) |
|
y_null = GPMIN(min_array[y_axis], max_array[y_axis]); |
|
else |
|
y_null = 0.0; |
|
|
x = (3.0 * plot->points[gl[0]].x - plot->points[gl[1]].x) / 2.0; |
x = (3.0 * plot->points[gl[0]].x - plot->points[gl[1]].x) / 2.0; |
y = 0.0; |
y = y_null; |
|
|
xl = map_x(x); |
xl = map_x(x); |
yl = map_y(y); |
yl = map_y(y); |
(*t->move) (xl, yl); |
(*t->move) (xl, yl); |
|
|
for (i = 0; i < goodcount - 1; i++) { /* loop over all points except last */ |
for (i = 0; i < goodcount - 1; i++) { /* loop over all points except last */ |
|
|
yn = plot->points[gl[i]].y; |
yn = plot->points[gl[i]].y; |
xn = (plot->points[gl[i]].x + plot->points[gl[i + 1]].x) / 2.0; |
xn = (plot->points[gl[i]].x + plot->points[gl[i + 1]].x) / 2.0; |
histeps_vertical(&xl, &yl, x, y, yn); |
histeps_vertical(&xl, &yl, x, y, yn); |
Line 2284 struct curve_points *plot; |
|
Line 2319 struct curve_points *plot; |
|
xn = (3.0 * plot->points[gl[i]].x - plot->points[gl[i - 1]].x) / 2.0; |
xn = (3.0 * plot->points[gl[i]].x - plot->points[gl[i - 1]].x) / 2.0; |
histeps_vertical(&xl, &yl, x, y, yn); |
histeps_vertical(&xl, &yl, x, y, yn); |
histeps_horizontal(&xl, &yl, x, xn, yn); |
histeps_horizontal(&xl, &yl, x, xn, yn); |
histeps_vertical(&xl, &yl, xn, yn, 0.0); |
histeps_vertical(&xl, &yl, xn, yn, y_null); |
|
|
free(gl); |
free(gl); |
} |
} |
Line 2734 struct curve_points *plot; |
|
Line 2769 struct curve_points *plot; |
|
* Plot the curves in VECTORS style |
* Plot the curves in VECTORS style |
*/ |
*/ |
static void plot_vectors(plot) |
static void plot_vectors(plot) |
struct curve_points *plot; |
struct curve_points *plot; |
{ |
{ |
int i; |
int i; |
int x1, y1, x2, y2; |
int x1, y1, x2, y2; |
struct termentry *t = term; |
struct termentry *t = term; |
|
TBOOLEAN head; |
|
struct coordinate points[2]; |
|
double ex, ey; |
|
double lx[2], ly[2]; |
|
|
for (i = 0; i < plot->p_count; i++) { |
for (i = 0; i < plot->p_count; i++) { |
if (plot->points[i].type == INRANGE) { |
points[0] = plot->points[i]; |
x1 = map_x(plot->points[i].xlow); |
points[1].x = plot->points[i].xhigh; |
y1 = map_y(plot->points[i].ylow); |
points[1].y = plot->points[i].yhigh; |
x2 = map_x(plot->points[i].xhigh); |
if (inrange(points[1].x, x_min, x_max) && |
y2 = map_y(plot->points[i].yhigh); |
inrange(points[1].y, y_min, y_max)) { |
(*t->arrow) (x1, y1, x2, y2, TRUE); |
/* to inrange */ |
|
points[1].type = INRANGE; |
|
x2 = map_x(points[1].x); |
|
y2 = map_y(points[1].y); |
|
head = TRUE; |
|
if (points[0].type == INRANGE) { |
|
x1 = map_x(points[0].x); |
|
y1 = map_y(points[0].y); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} else if (points[0].type == OUTRANGE) { |
|
/* from outrange to inrange */ |
|
if (clip_lines1) { |
|
edge_intersect(points, 1, &ex, &ey); |
|
x1 = map_x(ex); |
|
y1 = map_y(ey); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} |
|
} |
|
} else { |
|
/* to outrange */ |
|
points[1].type = OUTRANGE; |
|
head = FALSE; |
|
if (points[0].type == INRANGE) { |
|
/* from inrange to outrange */ |
|
if (clip_lines1) { |
|
x1 = map_x(points[0].x); |
|
y1 = map_y(points[0].y); |
|
edge_intersect(points, 1, &ex, &ey); |
|
x2 = map_x(ex); |
|
y2 = map_y(ey); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} |
|
} else if (points[0].type == OUTRANGE) { |
|
/* from outrange to outrange */ |
|
if (clip_lines2) { |
|
if (two_edge_intersect(points, 1, lx, ly)) { |
|
x1 = map_x(lx[0]); |
|
y1 = map_y(ly[0]); |
|
x2 = map_x(lx[1]); |
|
y2 = map_y(ly[1]); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
Line 3724 char *font; /* NULL or "" means use default */ |
|
Line 3806 char *font; /* NULL or "" means use default */ |
|
|
|
} |
} |
|
|
|
/* HBB 20010118: all the *_callback() functions made non-static. This |
|
* is necessary to work around a bug in HP's assembler shipped with |
|
* HP-UX 10 and higher, if GCC tries to use it */ |
|
|
/* display a x-axis ticmark - called by gen_ticks */ |
/* display a x-axis ticmark - called by gen_ticks */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
static void xtick2d_callback(axis, place, text, grid) |
void xtick2d_callback(axis, place, text, grid) |
int axis; |
int axis; |
double place; |
double place; |
char *text; |
char *text; |
Line 3799 struct lp_style_type grid; /* linetype or -2 for no gr |
|
Line 3885 struct lp_style_type grid; /* linetype or -2 for no gr |
|
|
|
/* display a y-axis ticmark - called by gen_ticks */ |
/* display a y-axis ticmark - called by gen_ticks */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
static void ytick2d_callback(axis, place, text, grid) |
void ytick2d_callback(axis, place, text, grid) |
int axis; |
int axis; |
double place; |
double place; |
char *text; |
char *text; |
|
|
|
|
|
|
void setup_tics(axis, ticdef, format, max) |
void setup_tics(axis, ticdef, format, max) |
int axis; |
int axis; |
struct ticdef *ticdef; |
struct ticdef *ticdef; |
char *format; |
char *format; |
int max; /* approx max number of slots available */ |
int max; /* approx max number of slots available */ |
{ |
{ |
double tic = 0; /* HBB: shut up gcc -Wall */ |
double tic = 0; /* HBB: shut up gcc -Wall */ |
|
|
Line 3900 int max; /* approx max number of slots available */ |
|
Line 3986 int max; /* approx max number of slots available */ |
|
ticstep[axis] = tic = ticdef->def.series.incr; |
ticstep[axis] = tic = ticdef->def.series.incr; |
fixmin &= (ticdef->def.series.start == -VERYLARGE); |
fixmin &= (ticdef->def.series.start == -VERYLARGE); |
fixmax &= (ticdef->def.series.end == VERYLARGE); |
fixmax &= (ticdef->def.series.end == VERYLARGE); |
|
if (log_array[axis]) |
|
tic = fabs(log(fabs(tic))) / log_base_array[axis]; |
} else if (ticdef->type == TIC_COMPUTED) { |
} else if (ticdef->type == TIC_COMPUTED) { |
ticstep[axis] = tic = make_tics(axis, max); |
ticstep[axis] = tic = make_tics(axis, max); |
} else { |
} else { |
Line 3982 char *dest, *format; |
|
Line 4070 char *dest, *format; |
|
size_t count; |
size_t count; |
double log_base, x; /* we print one number in a number of different formats */ |
double log_base, x; /* we print one number in a number of different formats */ |
{ |
{ |
#define LOC_PI 3.14159265358979323846 /* local definition of PI */ |
|
char temp[MAX_LINE_LEN]; |
char temp[MAX_LINE_LEN]; |
char *t; |
char *t; |
|
|
Line 4147 double log_base, x; /* we print one number in a numbe |
|
Line 4234 double log_base, x; /* we print one number in a numbe |
|
{ |
{ |
t[0] = 'f'; |
t[0] = 'f'; |
t[1] = 0; |
t[1] = 0; |
sprintf(dest, temp, x / LOC_PI); |
sprintf(dest, temp, x / M_PI); |
dest += strlen(dest); |
dest += strlen(dest); |
++format; |
++format; |
break; |
break; |
Line 4159 double log_base, x; /* we print one number in a numbe |
|
Line 4246 double log_base, x; /* we print one number in a numbe |
|
/*}}} */ |
/*}}} */ |
} |
} |
} |
} |
#undef LOC_PI /* local definition of PI */ |
|
/*}}} */ |
/*}}} */ |
#ifdef HAVE_SNPRINTF |
#ifdef HAVE_SNPRINTF |
# undef sprintf |
# undef sprintf |
Line 4176 double log_base, x; /* we print one number in a numbe |
|
Line 4262 double log_base, x; /* we print one number in a numbe |
|
*/ |
*/ |
|
|
void gen_tics(axis, def, grid, minitics, minifreq, callback) |
void gen_tics(axis, def, grid, minitics, minifreq, callback) |
int axis; /* FIRST_X_AXIS, etc */ |
int axis; /* FIRST_X_AXIS, etc */ |
struct ticdef *def; /* tic defn */ |
struct ticdef *def; /* tic defn */ |
int grid; /* GRID_X | GRID_MX etc */ |
int grid; /* GRID_X | GRID_MX etc */ |
int minitics; /* minitics - off/default/auto/explicit */ |
int minitics; /* minitics - off/default/auto/explicit */ |
double minifreq; /* frequency */ |
double minifreq; /* frequency */ |
tic_callback callback; /* fn to call to actually do the work */ |
tic_callback callback; /* fn to call to actually do the work */ |
{ |
{ |
/* seperate main-tic part of grid */ |
/* seperate main-tic part of grid */ |
struct lp_style_type lgrd, mgrd; |
struct lp_style_type lgrd, mgrd; |
Line 4226 tic_callback callback; /* fn to call to actually do t |
|
Line 4312 tic_callback callback; /* fn to call to actually do t |
|
return; /* NO MINITICS FOR USER-DEF TICS */ |
return; /* NO MINITICS FOR USER-DEF TICS */ |
/*}}} */ |
/*}}} */ |
} |
} |
|
|
/* series-tics |
/* series-tics |
* need to distinguish user co-ords from internal co-ords. |
* need to distinguish user co-ords from internal co-ords. |
* - for logscale, internal = log(user), else internal = user |
* - for logscale, internal = log(user), else internal = user |
Line 4237 tic_callback callback; /* fn to call to actually do t |
|
Line 4324 tic_callback callback; /* fn to call to actually do t |
|
* If step>1, we are looking at 1,1e6,1e12 for example, so |
* If step>1, we are looking at 1,1e6,1e12 for example, so |
* minitics are 10,100,1000,... - done in internal co-ords |
* minitics are 10,100,1000,... - done in internal co-ords |
*/ |
*/ |
|
|
{ |
{ |
double tic; /* loop counter */ |
double tic; /* loop counter */ |
double internal; /* in internal co-ords */ |
double internal; /* in internal co-ords */ |
Line 4257 tic_callback callback; /* fn to call to actually do t |
|
Line 4343 tic_callback callback; /* fn to call to actually do t |
|
lmin = lmax; |
lmin = lmax; |
lmax = temp; |
lmax = temp; |
} |
} |
|
|
/*{{{ choose start, step and end */ |
/*{{{ choose start, step and end */ |
switch (def->type) { |
switch (def->type) { |
case TIC_SERIES: |
case TIC_SERIES: |
|
start = def->def.series.start; |
|
step = def->def.series.incr; |
|
end = def->def.series.end; |
|
|
if (log_array[axis]) { |
if (log_array[axis]) { |
/* we can tolerate start <= 0 if step and end > 0 */ |
step = fabs(log(fabs(step))) / log_base_array[axis]; |
if (def->def.series.end <= 0 || |
|
def->def.series.incr <= 0) |
|
return; /* just quietly ignore */ |
|
step = log(def->def.series.incr) / log_base_array[axis]; |
|
end = log(def->def.series.end) / log_base_array[axis]; |
|
start = def->def.series.start > 0 ? |
|
log(def->def.series.start) / log_base_array[axis] : |
|
step; |
|
} else { |
|
start = def->def.series.start; |
|
step = def->def.series.incr; |
|
end = def->def.series.end; |
|
if (start == -VERYLARGE) |
|
start = step * floor(lmin / step); |
|
if (end == VERYLARGE) |
|
end = step * ceil(lmax / step); |
|
} |
} |
|
|
|
/* NOTE: lmin/lmax already are already logarithms, if |
|
* applicable */ |
|
if (start == -VERYLARGE) |
|
start = step * floor(lmin / step); |
|
else if (log_array[axis]) |
|
start = log(fabs(start)) / log_base_array[axis]; |
|
|
|
if (end == VERYLARGE) |
|
end = step * ceil(lmax / step); |
|
else if (log_array[axis]) |
|
end = log(fabs(end)) / log_base_array[axis]; |
|
|
break; |
break; |
case TIC_COMPUTED: |
case TIC_COMPUTED: |
/* round to multiple of step */ |
/* round to multiple of step */ |
Line 4365 tic_callback callback; /* fn to call to actually do t |
|
Line 4453 tic_callback callback; /* fn to call to actually do t |
|
minitics = 0; /* dont get stuck in infinite loop */ |
minitics = 0; /* dont get stuck in infinite loop */ |
/*}}} */ |
/*}}} */ |
} |
} |
|
|
/*{{{ a few tweaks and checks */ |
/*{{{ a few tweaks and checks */ |
/* watch rounding errors */ |
/* watch rounding errors */ |
end += SIGNIF * step; |
end += SIGNIF * step; |
|
|
case screen: |
case screen: |
{ |
{ |
register struct termentry *t = term; |
register struct termentry *t = term; |
*x = pos->x * (t->xmax) + 0.5; |
/* HBB 20000914: Off-by-one bug. Max. allowable result is |
|
* t->xmax - 1, not t->xmax ! */ |
|
*x = pos->x * (t->xmax - 1) + 0.5; |
break; |
break; |
} |
} |
} |
} |
|
|
case screen: |
case screen: |
{ |
{ |
register struct termentry *t = term; |
register struct termentry *t = term; |
*y = pos->y * (t->ymax) + 0.5; |
/* HBB 20000914: Off-by-one bug. Max. allowable result is |
|
* t->ymax - 1, not t->ymax ! */ |
|
*y = pos->y * (t->ymax -1) + 0.5; |
return; |
return; |
} |
} |
} |
} |