2.0.0-b7 - 7/25/00
Finished support for dmallocxx library
Fixed bug in SignalFilter::convertFilterMethodNameToID()
+ Rewrote SGP & EZPlot to use C++ object-oriented. SGP can now write to
+ G2 windows and well as WXWindows.
+ Now, "Create Phantom" in ctsim shows phantom object
2.0.0-b6 - 7/22/00
ctsim program: improved initial size and scroll area for image
New Features of CTSim version 2.0:
-- Entire code-base, except for SGP & EZPlot, cleaned up,
- re-written, and converted from C to C++.
+- Entire code-base cleaned up, re-written, and converted from C to C++.
- Integrated G2 library for graphical display from command line tools
(UNIX only)
-EXTRA_DIST=sgp.doc ctsim.tex texhelp.sty
+docs=sgp.doc ctsim.tex texhelp.sty
+info_INFO=ctsim.texi
+EXTRA_DIST = ${docs} $(info_INFO)
dvi: ctsim.tex
latex ctsim.tex
-\documentstyle[a4,texhelp]{report}
+\documentclass[11pt,texhelp]{report}
+\usepackage[dvips]{graphics}
+
+\begin{document}
+
+\newcommand{\ctsim}{{\tt ctsim}}
+
+
\title{CTSim - An Open-Source Computed Tomography Simulator}
-\author{Kevin Rosenberg}
+\author{Kevin Rosenberg, MD\footnote{San Juan Regional Medical Center, 801 W. Maple, Farmington NM 87401. Phone: (505) 599-6103. E-mail: kevin@rosenberg.net}}
\date{July 2000}
-\begin{document}
\maketitle
\chapter{Introduction}
-Welcome to CT.
-\section{Theory}
-Theory of CT.
+Computed Tomography is the process of taking projection of X-ray data
+though and object and using sophisticated mathematics to estimate
+information about the interior of that object.
+
+\chapter{Installation}
+\subsection{Requirements}
+\begin{itemize}
+
+ \item Apache or other CGI compatible web server
+
+ \item Perl (version 4.0 or higher)
+
+ \item A client web browser than can display PNG files. Most
+ current web browswer do support PNG.
+
+\end{itemize}
+
+\subsection{Download}
+\subsection{Install Binary Distribution}
+\subsection{Build From Sources}
+
+\chapter{The Programs}
-\chapter{The Programs}
\section{ctsim - The Graphical User Interface}
-{\tt ctsim} is the graphical shell for the CTSim project. {\tt ctsim} has most of the capabilities of the CTSim project. There are still functions that are only available to the command line tools.
+\ctsim\ is the graphical shell for the CTSim project. It is
+written using the wxLibrary for cross-platform compatibility with GTK,
+Motif, and Microsoft Windows.
+
+\ctsim\ incorporates most of the capabilities of the CTSim
+project. There are still functions that are only available to the
+command line tools.
+
+\subsection{Usage}
+ctsim [OPTIONS] [files to open...]
+
+\ctsim\ can open projection files and image files.
\section{The Web Browser CGI Interface}
\subsection{Overview}
+The CGI program {\tt ctsim.cgi} takes projections of a standard
+phantom object, performs reconstruction, and then compares the
+rasterized phantom object with the reconstruction. The comparison is
+performed both visually by an image subtraction as well as by standard
+statistics as described by Herman\cite{HERMAN80}.
-\subsection{Requirements}
-
-\section{tools - The Command Line Lnterface}
+\section{tools - The Command Line Interface}
\subsection{phm2pj}
-\begin{description}
Converts a phantom object to a set of projections
-\end{description}
{\tt phm2pj} simulates the process of collection of X-Ray projection data
such as collected by a CT scanner.
\subsection{pjrec}
\subsection{phm2if}
-\centerline{This is a centered line}
-\begin{center}
-This is a
-centered paragraph.
-\end{center}
-{\bf This is in bold font}
+\bibliographystyle{abbrv}
+\bibliography{yes}
+
\end{document}
-noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream scanner.h projections.h ctsupport.h filter.h array2dfile.h trace.h
+noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream scanner.h projections.h ctsupport.h filter.h array2dfile.h trace.h transformmatrix.h
+
/*****************************************************************************
+** FILE IDENTIFICATION
+**
+** Name: ezplot.h
+** Purpose: Header file for EZplot library
+**
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ezplot.h,v 1.9 2000/07/15 08:36:13 kevin Exp $
+** $Id: ezplot.h,v 1.10 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/
-/*----------------------------------------------------------------------*/
-/* EZPLOT */
-/* */
-/*----------------------------------------------------------------------*/
#ifndef __H_EZPLOT
#define __H_EZPLOT
-
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include "ctsupport.h"
#include "sgp.h"
-#define MAXLABEL 40 /* maximum length of axis label */
-#define MAXTITLE 40 /* maximum length of a title */
-#define MAXLEGEND 20 /* maximum length of a legend */
-#define MAXCURVES 10 /* maximum number of curves that can be plotted */
-#define MAXPTS 200 /* max number of points that can be read with
- DATA command in INTERACTIVE mode */
-
-struct ezp_curve_st {
- int numpts;
- double *x, *y;
- int linestyle;
- int symbol;
- int symfreq;
- int color;
- char legend[MAXLEGEND+1];
+
+class EZPlotCurve {
+ public:
+ double *x;
+ double *y;
+ int m_iPointCount;
+ int m_iLineStyle;
+ int m_iSymbol;
+ int m_iSymbolFreq;
+ int m_iColor;
+ string m_sLegend;
+
+ EZPlotCurve (const double* x, const double* y, int n, int color, int linestyle, int symbol, int sumbolFreq, const string& legend);
+
+ ~EZPlotCurve();
};
-#define XBUF_DEF 600
-#define YBUF_DEF 600
-#define PRTMODE_DEF 1
+/*----------------------------------------------------------------------*/
+/* GLOBAL VARIABLES */
+/*----------------------------------------------------------------------*/
+
+/* axis definitions */
+#define LINEAR 1 /* linear axis */
+#define LOG 2 /* logrithmic axis */
+#define NOAXIS 3 /* don't plot axis */
+
+/* tick definitions */
+#define ABOVE 1
+#define BELOW 2
+#define RIGHT 4
+#define LEFT 8
+
+/* line types */
+#define NOLINE 0
+#define SOLID 1
+#define DASH 2
+#define DASH1 10
+#define DASH2 11
+#define DASH3 12
+#define DASH4 13
+
+/* symbol definitions */
+#define SB_CROSS 1
+#define SB_PLUS 2
+#define SB_BOX 3
+#define SB_CIRCLE 4
+#define SB_ERRORBAR 5
+#define MAXSYMBOL 5
+
+#define INSIDE 1 /* values of o_legendbox */
+#define OUTSIDE 2
+#define NOLEGEND 3
+
+/*-----------------------------------------------------------------------------
+ * GLOBAL VARIABLES
+ *
+ * Naming Convention:
+ * i_ Internal variable
+ * Not user changable
+ * o_ Option variable
+ * Normal variable that is user modifiable
+ * These variables must always have a valid value
+ * d_ Device variable
+ * Variables controlling devices
+ * clr_ Color variable
+ * Holds a color value
+ * c_ Character string variable
+ * Contains a character string
+ * v_ Value variable
+ * User modifiable variable associated with the set variable (s_)
+ * These variables do not always have a valid value
+ * These variables change assumption EZPLOT makes about the plot
+ * s_ Set variable.
+ * TRUE if associated value variable (v_) has been set by the user
+ *---------------------------------------------------------------------------*/
+
+#include <vector>
+using namespace std;
+
+typedef vector<EZPlotCurve*>::iterator EZPlotCurveIterator;
+typedef vector<EZPlotCurve*>::const_iterator EZPlotCurveConstIterator;
+
+class SGP;
+class EZPlot {
+ private:
+ vector<class EZPlotCurve*> m_vecCurves;
+
+ // Colors
+ int clr_axis; /* color of all axis lines */
+ int clr_title; /* color of main title */
+ int clr_label; /* color of axis labels */
+ int clr_legend; /* color of legend box */
+ int clr_grid; /* color of grid lines */
+ int clr_number; /* color of axis number labels */
+
+ // Options
+ int o_reqcurves; /* # of curves specified in CURVES command */
+ /* default value is 1, so that a call to EZPLOT
+ will force a plot */
+ bool o_unknowncurves; /* TRUE when the user specifies that the
+ number of curves is unknown */
+
+ double o_xporigin, o_yporigin; /* origin of plot frame in NDC */
+ double o_xlength, o_ylength; /* length of plot frame in NDC */
+
+ string c_xlabel; /* label for x axis */
+ string c_ylabel; /* label for y axis */
+ string c_title; /* title to print above graph */
+ string c_legend;; /* current legend specified */
+
+ int o_linestyle, o_color; /* style to use for curves all subsequent curves to EZPLOT */
+ bool o_xaxis, o_yaxis; /* Specifies where axis & labels are drawn */
+ bool o_grid; /* Flag to draw a grid at major ticks */
+ bool o_box; /* Flag to draw a box around the graph */
+
+ int o_xticks, o_yticks; /* direction to draw tick marks */
+ bool o_xtlabel, o_ytlabel; /* TRUE if label tick marks */
+
+ int o_xmajortick, o_ymajortick; /* number of major ticks to draw */
+ int o_xminortick, o_yminortick; /* number of minor ticks between major ticks */
+
+ int o_symbol; /* Symbol type, (0 = no symbol) */
+ int o_symfreq; /* frequency to draw symbols at curve points */
+
+ int o_legendbox; /* controls whether legend is inside or outside of the axis extents */
+ int o_tag; /* controls whether to draw tag at end of axes */
+
+ // VALUE & SET variables
+ double v_xmin, v_xmax, v_ymin, v_ymax; /* user supplied axis endpoints */
+ bool s_xmin, s_xmax, s_ymin, s_ymax; /* TRUE is endpoint has been set */
+ double v_xtitle, v_ytitle; /* NDC position to plot title */
+ bool s_xtitle, s_ytitle; /* TRUE if set position for title */
+ double v_xcross, v_ycross; /* position that axes cross */
+ bool s_xcross, s_ycross; /* TRUE if set axes cross position */
+ double v_xlegend, v_ylegend; /* upper-left position of legend box in NDC */
+ bool s_xlegend, s_ylegend; /* TRUE if set position of legend box */
+ int v_lxfrac, v_lyfrac; /* number of digits to right of decimal place */
+ bool s_lxfrac, s_lyfrac; /* TRUE if set number of fractional digits */
+ double v_textsize; /* size of text in NDC */
+ bool s_textsize; /* TRUE if user set size of text */
+
+ // Global variables
+ double charheight; /* Height of characters in NDC */
+ double charwidth; /* Height of characters in NDC */
+ double xp_min, xp_max, yp_min, yp_max; /* boundry of plot frame in NDC */
+ double xa_min, xa_max, ya_min, ya_max; /* extent of axes in NDC */
+ double xgw_min, xgw_max, ygw_min, ygw_max; /* boundary of graph in input coords */
+ double xgn_min, xgn_max, ygn_min, ygn_max; /* boundy of graph in NDC */
+ double xt_min, xt_max, yt_min, yt_max; /* boundary of axis ticks */
+ double xl_min, xl_max, yl_min, yl_max; /* boundary of legend box */
+ double title_row; /* y-coord of title row */
+ double xtl_ofs; /* Offset y-coord of x tick labels from axis */
+ double ytl_ofs; /* Offset x-coord of y tick labels from axis */
+ double xlbl_row; /* row of x label in world coord */
+ double ylbl_col; /* column of y label in world coord */
+ double xw_tickinc, yw_tickinc; /* increment between major ticks in WC */
+ double xn_tickinc, yn_tickinc; /* increment between major ticks in NDC */
+ int x_nint, y_nint; /* number of intervals along x & y axes */
+ int x_fldwid, x_frac; /* numeric field sizes & number of digits */
+ int y_fldwid, y_frac; /* in fraction of number, used for printf() */
+ double xtl_wid, ytl_wid; /* length of ticks labels in NDC */
+ double tl_height; /* height of tick labels in NDC */
+ char x_numfmt[20]; /* format to print x tick labels */
+ char y_numfmt[20]; /* format to print y tick labels */
+
+ void drawAxes(void);
+ void symbol (int sym, double symwidth, double symheight);
+ void make_numfmt(char *fmtstr, int *fldwid, int *nfrac, double min, double max, int nint);
+ int axis_scale (double min, double max, int nint, double *minp, double *maxp, int *nintp);
+
+ SGP& rSGP;
+
+ void clearCurves ();
+
+ bool ezcmd (char *comm);
+ int do_cmd(int lx);
+ void bad_option(char *opt);
+ static void initkw(void);
+
+ int curveinteract;
+ static bool ezset_initialized;
+
+ public:
+ EZPlot (SGP& sgp);
+ ~EZPlot ();
+
+ int ezset (char *command);
+
+ void addCurve (const float* x, const double* y, int num);
+ void addCurve (const double* x, const double* y, int num);
+ void addCurve (const double* y, int n);
+
+ void plot ();
+};
/*----------------------------------------------------------------------*/
/* Codes from LEX */
#define S_CLEAR -61
#define S_STORE -62
#define S_RESTORE -63
-#define S_USTART -64
-#define S_UFINISH -65
#define S_AMARK -66
#define S_NO -67
#define S_INTERACTIVE -68
#define S_LEGENDBOX -107
#define S_TAG -108
-#define S_EPSON -110
-#define S_CRT -111
-
#define S_TEXTSIZE -120
-#define S_XBUF -121
-#define S_YBUF -122
-#define S_PRTMODE -123
-
-/*----------------------------------------------------------------------*/
-/* GLOBAL VARIABLES */
-/*----------------------------------------------------------------------*/
-
-/* axis definitions */
-#define LINEAR 1 /* linear axis */
-#define LOG 2 /* logrithmic axis */
-#define NOAXIS 3 /* don't plot axis */
-
-/* tick definitions */
-#define ABOVE 1
-#define BELOW 2
-#define RIGHT 4
-#define LEFT 8
-
-/* line types */
-#define NOLINE 0
-#define SOLID 1
-#define DASH 2
-#define DASH1 10
-#define DASH2 11
-#define DASH3 12
-#define DASH4 13
-
-/* symbol definitions */
-#define SB_CROSS 1
-#define SB_PLUS 2
-#define SB_BOX 3
-#define SB_CIRCLE 4
-#define SB_ERRORBAR 5
-#define MAXSYMBOL 5
-
-#define INSIDE 1 /* values of o_legendbox */
-#define OUTSIDE 2
-#define NOLEGEND 3
-
-/*-----------------------------------------------------------------------------
- * GLOBAL VARIABLES
- *
- * Naming Convention:
- * i_ Internal variable
- * Not user changable
- * o_ Option variable
- * Normal variable that is user modifiable
- * These variables must always have a valid value
- * d_ Device variable
- * Variables controlling devices
- * clr_ Color variable
- * Holds a color value
- * c_ Character string variable
- * Contains a character string
- * v_ Value variable
- * User modifiable variable associated with the set variable (s_)
- * These variables do not always have a valid value
- * These variables change assumption EZPLOT makes about the plot
- * s_ Set variable.
- * TRUE if associated value variable (v_) has been set by the user
- *---------------------------------------------------------------------------*/
-
-
-struct ezplot_var {
-
-/*-------------*/
-/* USER CURVES */
-/*-------------*/
-
-struct ezp_curve_st curve[MAXCURVES];
-
-/*--------------------*/
-/* INTERNAL VARIABLES */
-/*--------------------*/
-
-bool i_plotimmediate; /* indicates that a call to EZPLOT is a signal
- to print all received arrays. EZSET uses
- this variable to force EZPLOT to replot
- its stored curves */
-int i_numcurves; /* number of curves received by EZPLOT */
-
-/*------------------*/
-/* DEVICE VARIABLES */
-/*------------------*/
-
-bool d_usecrt; /* TRUE if want to use CRT as output device */
-bool d_useprt; /* TRUE if wamt to use printer as output device */
-
-int d_crtmode; /* Controls which crt mode to use for plot */
-int d_prtmode; /* Controls mode of printer output */
-
-int d_xprtbuf, d_yprtbuf; /* Size of printer buffer in pixels */
-
-/*-----------------*/
-/* COLOR VARIABLES */
-/*-----------------*/
-
-int clr_axis; /* color of all axis lines */
-int clr_title; /* color of main title */
-int clr_label; /* color of axis labels */
-int clr_legend; /* color of legend box */
-int clr_grid; /* color of grid lines */
-int clr_number; /* color of axis number labels */
-
-/*------------------*/
-/* OPTION VARIABLES */
-/*------------------*/
-
-int o_reqcurves; /* # of curves specified in CURVES command */
- /* default value is 1, so that a call to EZPLOT
- will force a plot */
-bool o_unknowncurves; /* TRUE when the user specifies that the
- number of curves is unknown */
-
-bool o_ustart, o_ufinish; /* TRUE if user initiates or terminate sgp */
-
-double o_xporigin, o_yporigin; /* origin of plot frame in NDC */
-double o_xlength, o_ylength; /* length of plot frame in NDC */
-
-char c_xlabel[MAXLABEL+1]; /* label for x axis */
-char c_ylabel[MAXLABEL+1]; /* label for y axis */
-char c_title[MAXTITLE+1]; /* title to print above graph */
-char c_legend[MAXLEGEND+1]; /* current legend specified */
-
-int o_linestyle, o_color; /* style to use for curves all subsequent */
- /* curves to EZPLOT */
-bool o_xaxis, o_yaxis; /* Specifies where axis & labels are drawn */
-bool o_grid; /* Flag to draw a grid at major ticks */
-bool o_box; /* Flag to draw a box around the graph */
-
-int o_xticks, o_yticks; /* direction to draw tick marks */
-bool o_xtlabel, o_ytlabel; /* TRUE if label tick marks */
-
-int o_xmajortick, o_ymajortick; /* number of major ticks to draw */
-int o_xminortick, o_yminortick; /* number of minor ticks between major ticks */
-
-int o_symbol; /* Symbol type, (0 = no symbol) */
-int o_symfreq; /* frequency to draw symbols at curve points */
-
-int o_legendbox; /* controls whether legend is inside */
- /* or outside of the axis extents */
-int o_tag; /* controls whether to draw tag at end of axes */
-
-/*-----------------------*/
-/* VALUE & SET variables */
-/*-----------------------*/
-
-double v_xmin, v_xmax, v_ymin, v_ymax; /* user supplied axis endpoints */
-bool s_xmin, s_xmax, s_ymin, s_ymax; /* TRUE is endpoint has been set */
-
-double v_xtitle, v_ytitle; /* NDC position to plot title */
-bool s_xtitle, s_ytitle; /* TRUE if set position for title */
-double v_xcross, v_ycross; /* position that axes cross */
-bool s_xcross, s_ycross; /* TRUE if set axes cross position */
-
-double v_xlegend, v_ylegend; /* upper-left position of legend box in NDC */
-bool s_xlegend, s_ylegend; /* TRUE if set position of legend box */
-
-int v_lxfrac, v_lyfrac; /* number of digits to right of decimal place */
-bool s_lxfrac, s_lyfrac; /* TRUE if set number of fractional digits */
-
-double v_textsize; /* size of text in NDC */
-bool s_textsize; /* TRUE if user set size of text */
-
-}; /* end of EZPLOT VARIABLES */
-
-
-
-extern struct ezplot_var ez;
-extern bool ezplot_firstcall; /* set to false on first call to EZSET or EZPLOT */
-
-
-/* ezplot.cpp */
-SGP_ID ezplot (const float x[], const double y[], int num);
-SGP_ID ezplot (const double x[], const double y[], int num);
-void ezinit(void);
-void ezfree(void);
-void ezclear(void);
-
-/* ezset.cpp */
-int ezset(char *command);
-
-/* ezplot1d.cpp */
-void ezplot_1d(double *y, int n);
-
-/* makefmt.cpp */
-void make_numfmt(char *fmtstr, int *fldwid, int *nfrac, double min, double max, int nint);
-
-/* axis.cpp */
-int axis_scale (double min, double max, int nint, double *minp, double *maxp, int *nintp);
-
#endif
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: phantom.h,v 1.10 2000/07/22 15:45:33 kevin Exp $
+** $Id: phantom.h,v 1.11 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#include <slist>
#include "ctsupport.h"
-#include "backprojectors.h"
-class ImageFile;
using namespace std;
// Phantom Class Declaration
//////////////////////////////////////////////////////
+class SGP;
+class ImageFile;
class Phantom
{
public:
#if HAVE_SGP
void show () const;
- void draw () const;
+ void draw (SGP& sgp) const;
#endif
void addStdHerman ();
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: scanner.h,v 1.8 2000/07/22 15:45:33 kevin Exp $
+** $Id: scanner.h,v 1.9 2000/07/28 08:28:08 kevin Exp $
**
**
** This program is free software; you can redistribute it and/or modify
#ifndef SCANNER_H
#define SCANNER_H
+#include "trace.h"
+
class Projections;
class Phantom;
class PhantomElement;
+class SGP;
// Projections are collected along an array of ndet detectors. The data
// for these detectors is stored in the class DetectorArray
Scanner (const Phantom& phm, const char* const geometryName, int nDet, int nView, int nSample, const double rot_anglen);
~Scanner();
- void collectProjections (Projections& proj, const Phantom& phm, const int start_view, const int trace);
+ void collectProjections (Projections& proj, const Phantom& phm, const int start_view, const int trace = TRACE_NONE, SGP* pSGP = NULL);
void setNView (int nView);
static const int s_iGeometryCount;
static const int N_EXTRA_DETECTORS=4; /* Number of extra detectors widths when calculating detlen */
- void projectSingleView (const Phantom& phm, DetectorArray& darray, const double xd1, const double yd1, const double xd2, const double yd2, const double xs1, const double ys1, const double xs2, const double ys2);
+ void projectSingleView (const Phantom& phm, DetectorArray& darray, const double xd1, const double yd1, const double xd2, const double yd2, const double xs1, const double ys1, const double xs2, const double ys2, SGP* pSGP);
- double projectSingleLine (const Phantom& phm, const double x1, const double y1, const double x2, const double y2);
+ double projectSingleLine (const Phantom& phm, const double x1, const double y1, const double x2, const double y2, SGP* pSGP);
- double projectLineAgainstPElem (const PhantomElement& pelem, const double x1, const double y1, const double x2, const double y2);
+ double projectLineAgainstPElem (const PhantomElement& pelem, const double x1, const double y1, const double x2, const double y2, SGP* pSGP);
void traceShowParam (const char *label, const char *fmt, int row, int color, ...);
/*****************************************************************************
+** FILE IDENTIFICATION
+**
+** Name: sgp.h
+** Purpose: Header file for Simple Graphics Package
+** Author: Kevin Rosenberg
+** Date Started: 1984
+**
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: sgp.h,v 1.10 2000/06/19 19:04:05 kevin Exp $
+** $Id: sgp.h,v 1.11 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/
-/*----------------------------------------------------------------------*/
-/* Standard Graphics Package Header File */
-/*----------------------------------------------------------------------*/
-
#ifndef __H_SGP
#define __H_SGP
#include "config.h"
#endif
-#include "ctsupport.h"
+#include "transformmatrix.h"
+
+#ifdef HAVE_WXWINDOWS
+#include <wx/wx.h>
+#endif
#if HAVE_G2_H
extern "C" {
}
#endif
-/* device names */
-
-#define CRTDEV 1
-#define PRTDEV 2
-#define MEMDEV 4
-#define FILEDEV 8
-
-/* linestyles */
-
-#define LS_NOLINE 0
-#define LS_SOLID 0xffff
-#define LS_DASH1 0xff00
-#define LS_DASH2 0xf0f0
-#define LS_DASH3 0xcccc
-#define LS_DASH4 0xff3e
-#define LS_DOTTED 0xaaaa
-
-#define MAXDASH 4
-#define MAXCOLOR 63
-
-/* data structures */
-
-struct sgp_window_st {
- int pw_xsize; /* Physical Window size */
- int pw_ysize;
- char title[256];
- int g2_id;
- double xw_min; /* Window extents */
- double yw_min;
- double xw_max;
- double yw_max;
- double xv_min; /* Viewport extents */
- double yv_min;
- double xv_max;
- double yv_max;
- double view[4]; /* Viewport array for clip_rect() */
- double curx; /* Current stylus position in world coords */
- double cury;
- int recalc_mc_to_ndc;
- int recalc_ndc_to_mc;
- GRFMTX_2D wc_to_ndc_x; /* World coord to NDC matrix */
- GRFMTX_2D mc_to_ndc_x; /* Master to NDC */
- GRFMTX_2D ndc_to_mc_x; /* NDC to Master */
- GRFMTX_2D ctm_2_x; /* Current transfromation matrix */
-
- int phys_curx;
- int phys_cury;
-};
+#include <string>
-typedef struct sgp_window_st SGP_WINDOW;
-typedef struct sgp_window_st *SGP_ID;
-
-struct device_st {
- int open; /* TRUE if device is open for output */
- int xsize, ysize; /* Size of device in pixels */
- int xmin, ymin; /* smallest coordinates */
- int xmax, ymax; /* Maximum coordinates */
- int colormax; /* Maximum color number of device */
- int style; /* Current linestyle of device */
- int width; /* Current width of device */
- int color; /* Current color of device */
- int icurx, icury; /* Current position */
- int icwidth, icheight; /* Size of characters in pixels */
- int cfore, cback; /* Character foregnd & backgnd colors */
- float asp; /* Aspect ratio. Multipy x coord */
- int (*dotfunc)(int x1, int y1, int color); /* Dot function for device */
- int (*linefunc)(int x1, int y1, int x2, int y2, int color); /* Line function for device */
- unsigned int nbytes; /* Size of buffer in bytes */
- char *buf; /* Pointer to buffer */
- unsigned int bufseg, bufoff; /* Buffer memory location */
- int mode; /* Device mode */
-};
-struct charsp_st {
- float width, height; /* size of characters in NDC */
- float textangle; /* text angle in radians */
- float charupangle; /* character up angle */
- int font; /* font for characters */
- int updir, textdir; /* text direct & character orientation */
- int fore, back; /* foreground & background color */
- /* if back = -1, then transparent back */
-};
+class SGPDriver {
+private:
+ int m_iPhysicalXSize;
+ int m_iPhysicalYSize;
+ string m_sWindowTitle;
+ int m_idDriver;
+
+#ifdef HAVE_WXWINDOWS
+ wxDC* m_pDC;
+#endif
+ int m_idG2;
+
+public:
+ enum {
+ SGPDRIVER_WXWINDOWS = 1,
+ SGPDRIVER_G2 = 2,
+ SGPDRIVER_OPENGL = 4,
+ };
+
+#ifdef HAVE_WXWINDOWS
+ SGPDriver (wxDC* pDC, const char* szWinTitle = "", int xsize = 640, int ysize = 480);
+#endif
+
+ SGPDriver (const char* szWinTitle = "", int xsize = 640, int ysize = 480);
+
+ ~SGPDriver ();
+
+ int getPhysicalXSize () const
+ { return m_iPhysicalXSize; }
+
+ int getPhysicalYSize () const
+ { return m_iPhysicalYSize; }
+
+ const string& getWindowTitle () const
+ { return m_sWindowTitle; }
-struct state_st {
- int foregnd, backgnd; /* current foregound & background colors */
- int linestyle; /* current 16 bit linestyle */
- int linewidth; /* current width of line (in pixels) */
- int marktype; /* current marker type */
- int markcolor; /* current marker color */
- float xndc, yndc; /* current position in NDC */
+ bool isWX () const
+ { return (m_idDriver & SGPDRIVER_WXWINDOWS); }
+
+ bool isG2 () const
+ { return (m_idDriver & SGPDRIVER_G2); }
+
+ int idG2 () const
+ { return m_idG2; }
+
+#ifdef HAVE_WXWINDOWS
+ wxDC* idWX () const
+ { return m_pDC; }
+#endif
};
-typedef struct device_st DEVICE;
-typedef struct charsp_st CHARSPEC;
-typedef struct state_st GRFSTATE;
-
-struct point {double x, y, z;};
-
-
-/* Constants */
-
-/* Flagcodes for motion directions */
-#define XPLUS 001 /* right */
-#define XMINUS 002 /* left */
-#define YPLUS 004 /* up */
-#define YMINUS 010 /* down */
-
-/* Codes for marker symbols */
-#define POINT 0 /* small dot */
-#define SQUARE 1 /* empty square */
-#define FSQUARE 2 /* filled square */
-#define DIAMOND 3 /* empty diamond */
-#define FDIAMOND 4 /* filled diamond */
-#define CROSS 5 /* cross */
-#define XCROSS 6 /* x */
-#define CERCLE 7 /* open circle */
-#define FCERCLE 8 /* filled circle */
-#define BSQUARE 9 /* big open square */
-#define BDIAMOND 10 /* big open diamond */
-
-#define NMARKERS 11 /* Number of available symbol types */
-
-/*-------------------------------------------------------------------------*/
-
-#define PSET 0 /* codes for raster merging */
-#define PRESET 1
-#define OR 2
-#define AND 3
-#define XOR 4
-
-/*-------------------------------------------------------------------------*/
-
-/* circle.cpp */
-void sgp2_draw_circle(const double r);
-void sgp2_draw_arc(double start, double stop, const double r);
-
-/* ctm.cpp */
-void ctm_xlat_pre_2(double x, double y);
-void ctm_xlat_post_2(double x, double y);
-void ctm_scale_pre_2(double sx, double sy);
-void ctm_scale_post_2(double sx, double sy);
-void ctm_rotate_pre_2(double theta);
-void ctm_rotate_post_2(double theta);
-void ctm_shear_pre_2(double shrx, double shry);
-void ctm_shear_post_2(double shrx, double shry);
-void xlat_gmtx_2(GRFMTX_2D m, double x, double y);
-void scale_gmtx_2(GRFMTX_2D m, double sx, double sy);
-void shear_gmtx_2(GRFMTX_2D m, double shrx, double shry);
-void rotate_gmtx_2(GRFMTX_2D m, double theta);
-void ident_gmtx_2(GRFMTX_2D m);
-void mult_gmtx_2(GRFMTX_2D a, GRFMTX_2D b, GRFMTX_2D c);
-void invert_gmtx_2(GRFMTX_2D a, GRFMTX_2D b);
-double determ_gmtx_2(GRFMTX_2D a);
-
-/* drawbox.cpp */
-void sgp2_draw_rect (double xmin, double ymin, double xmax, double ymax);
-
-/* sgp.cpp */
-SGP_ID sgp2_init (int xsize, int ysize, const char *title);
-void sgp2_close (SGP_ID gid);
-void sgp2_set_active_win (SGP_ID);
-SGP_ID sgp2_get_active_win (void);
-void sgp2_clear (void);
-void sgp2_window(double xmin, double ymin, double xmax, double ymax);
-void sgp2_viewport(double xmin, double ymin, double xmax, double ymax);
-void sgp2_frame_vpt(void);
-void calc_wc_to_ndc(void);
-void calc_ndc_to_mc(void);
-void wc_to_ndc(double xw, double yw, double *xn, double *yn);
-void ndc_to_wc(double xn, double yn, double *xw, double *yw);
-void sgp2_color(int icol);
-void sgp2_line_style(int style);
-void sgp2_line_abs(double x, double y);
-void sgp2_move_abs(double x, double y);
-void sgp2_line_rel(double x, double y);
-void sgp2_move_rel(double x, double y);
-void sgp2_draw_text(char *message);
-void sgp2_polyline_abs(double x[], double y[], int n);
-void sgp2_mark_abs(double x, double y);
-void sgp2_mark_rel(double x, double y);
-void sgp2_point_abs(double x, double y);
-void sgp2_point_rel(double x, double y);
-void charsize(double wid, double height);
-void textangle(double angle);
-void ctm_clr_2(void);
-void ctm_get_2(GRFMTX_2D m);
-void ctm_set_2(GRFMTX_2D m);
-void ctm_pre_mult_2(GRFMTX_2D m);
-void ctm_post_mult_2(GRFMTX_2D m);
-
-/* sgpdrive.cpp */
-int _sgp2_init_dev(SGP_ID gid);
-int initdevice(int dev, int mode, int xsize, int ysize);
-int opendevice(int dev);
-void closedevice(int dev);
-void termdevice(int dev);
-void _sgp2_stylus(SGP_ID gid, double x, double y, int beam);
-void pntndc (SGP_ID gid, double x, double y);
-void markndc (SGP_ID gid, double x, double y);
-GRFSTATE *inqstate(void);
-void gp_set_aspect(int dev, double asp);
-void setlinestyle(int style);
-void setlinewidth(int wid);
-DEVICE *inqdev(int dev);
-void _sgp2_set_text(SGP_ID gid, double width, double height, double textangle, int font);
-void settextclr(int fore, int back);
-void setcolor(int fore);
-void setbackg(int back);
-int initmarker(int marker, int color);
-int settextdir(int direction);
-void _sgp2_dev_text(SGP_ID gid, char *message);
-void termgrf2(void);
-void flushdevice(int dev);
-
-/* sgptext.cpp */
-void wrtsymbol(int sym, int x, int y, DEVICE *dev);
-void wrtchar(int ch, int x, int y, CHARSPEC *cspec, DEVICE *dev);
-void wrttext(char txtstr[], int x, int y, CHARSPEC *cspec, DEVICE *dev);
-void crtcolor(int mode, int *f, int *b);
+
+class SGP {
+private:
+ int m_iPhysicalXSize; // Physical Window size
+ int m_iPhysicalYSize;
+ const SGPDriver m_driver;
+
+ double xw_min; // Window extents
+ double yw_min;
+ double xw_max;
+ double yw_max;
+ double xv_min; // Viewport extents
+ double yv_min;
+ double xv_max;
+ double yv_max;
+ double viewNDC[4]; // Viewport array for clip_rect()
+
+ int m_iCurrentPhysicalX;
+ int m_iCurrentPhysicalY;
+ double m_dCurrentWorldX;
+ double m_dCurrentWorldY;
+ double m_dTextAngle;
+ bool m_bRecalcTransform;
+
+ // Master coordinates are coordinates before CTM transformation
+ // World coordinates are coordinates defined by setWindow()
+ // Normalized device coordinates range from 0. to 1. in both axes
+ TransformationMatrix2D wc_to_ndc; // World coord to NDC matrix
+ TransformationMatrix2D mc_to_ndc; // Master to NDC
+ TransformationMatrix2D ndc_to_mc; // NDC to Master
+ TransformationMatrix2D m_ctm; // Current transfromation matrix
+
+ void calc_transform ();
+
+public:
+ enum { // linestyles
+ LS_NOLINE = 0,
+ LS_SOLID = 0xffff,
+ LS_DASH1 = 0xff00,
+ LS_DASH2 = 0xf0f0,
+ LS_DASH3 = 0xcccc,
+ LS_DASH4 = 0xff3e,
+ LS_DOTTED = 0xaaaa,
+ };
+
+ enum { // Codes for marker symbols
+ MARK_POINT = 0, // small dot
+ MARK_SQUARE = 1, // empty square
+ MARK_FSQUARE = 2, // filled square
+ MARK_DIAMOND = 3, // empty diamond
+ MARK_FDIAMOND = 4, // filled diamond
+ MARK_CROSS = 5, // cross
+ MARK_XCROSS = 6, // x
+ MARK_CIRCLE = 7, // open circle
+ MARK_FCIRCLE = 8, // filled circle
+ MARK_BSQUARE = 9, // big open square
+ MARK_BDIAMOND = 10, // big open diamond
+ };
+ static const int MARK_COUNT = 11;
+ static const unsigned char MARKER_BITMAP[MARK_COUNT][5];
+
+ SGP (const SGPDriver& driver);
+
+ void drawCircle (const double r);
+ void drawArc (double start, double stop, const double r);
+ void drawRect (double xmin, double ymin, double xmax, double ymax);
+ void lineAbs(double x, double y);
+ void moveAbs(double x, double y);
+ void lineRel(double x, double y);
+ void moveRel(double x, double y);
+ void drawText(const char *szMessage);
+ void drawText(const string& rsMessage);
+ void polylineAbs(double x[], double y[], int n);
+ void markerAbs (double x, double y);
+ void markerRel(double x, double y);
+ void pointAbs(double x, double y);
+ void pointRel(double x, double y);
+
+ void eraseWindow ();
+ void setWindow (double xmin, double ymin, double xmax, double ymax);
+ void setViewport (double xmin, double ymin, double xmax, double ymax);
+ void frameViewport();
+
+ void setColor (int icol);
+ void setLineStyle (int style);
+ void setTextSize (double height);
+ void setTextAngle (double angle);
+ void setTextColor (int iFGcolor, int iBGcolor);
+ void setMarker (int idMarker, int color);
+
+ void ctmClear ();
+ void ctmSet (const TransformationMatrix2D& m);
+ void preTranslate (double x, double y);
+ void postTranslate (double x, double y);
+ void preScale (double sx, double sy);
+ void postScale (double sx, double sy);
+ void preRotate (double theta);
+ void postRotate (double theta);
+ void preShear (double shrx, double shry);
+ void postShear (double shrx, double shry);
+ void transformNDCtoMC (double* x, double* y);
+ void transformMCtoNDC (double* x, double* y);
+ void transformMCtoNDC (double xIn, double yIn, double* xOut, double* yOut);
+
+ void stylusNDC (double x, double y, bool beam);
+ void pointNDC (double x, double y);
+ void markerNDC (double x, double y);
+};
#endif
--- /dev/null
+/*****************************************************************************
+** FILE IDENTIFICATION
+**
+** Name: sgp.h
+** Purpose: Header file for Simple Graphics Package
+** Author: Kevin Rosenberg
+** Date Started: 1984
+**
+** This is part of the CTSim program
+** Copyright (C) 1983-2000 Kevin Rosenberg
+**
+** $Id: transformmatrix.h,v 1.1 2000/07/28 08:28:08 kevin Exp $
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License (version 2) as
+** published by the Free Software Foundation.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+******************************************************************************/
+
+#ifndef __H_TRANSFORMMATRIX
+#define __H_TRANSFORMMATRIX
+
+class ostream;
+class TransformationMatrix2D {
+public:
+ double mtx[3][3];
+
+ TransformationMatrix2D () {};
+ TransformationMatrix2D (double m[3][3]);
+
+ void setIdentity();
+ void setTranslate (double x, double y);
+ void setScale (double sx, double sy);
+ void setShear (double shrx, double shry);
+ void setRotate (double theta);
+
+ double determinant () const;
+
+ const TransformationMatrix2D invert () const;
+
+ void transformPoint (double *pX, double *pY) const;
+
+ void print (ostream& ostr) const;
+
+ friend const TransformationMatrix2D operator* (const TransformationMatrix2D& lhs, const TransformationMatrix2D& rhs);
+
+};
+
+
+const TransformationMatrix2D operator* (const TransformationMatrix2D& lhs, const TransformationMatrix2D& rhs);
+
+#endif
noinst_LIBRARIES = libctgraphics.a
-libctgraphics_a_SOURCES=ezplot.cpp ezsupport.cpp ezset.cpp ezpol.cpp ctm.cpp sgp.cpp sgpdriver.cpp sgptext.cpp
+libctgraphics_a_SOURCES=ezplot.cpp ezset.cpp ezpol.cpp sgp.cpp transformmatrix.cpp
INCLUDES=@my_includes@
EXTRA_DIST=Makefile.nt
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ezplot.cpp,v 1.6 2000/07/15 08:36:13 kevin Exp $
+** $Id: ezplot.cpp,v 1.7 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
******************************************************************************/
#include "ezplot.h"
-#include "algo.h"
+#include <algorithm>
-static int plot (SGP_ID *gid);
-static void drawaxis(void);
-static void symbol (int sym, double symwidth, double symheight);
+// Defaults
+static const double TICKRATIO = 0.4; // ratio of minor to major tick lengths
+static const int MAXNUMFMT = 15; // maximum length of a numeric format
+static const double DEF_CHARHEIGHT = (1./43.); //size of characters in NDC
+static const double DEF_CHARWIDTH = (1./80.); // size of characters in NDC
+static const int DEF_CURVE_CLR = C_YELLOW;
-/*-------------------------------------*/
-/* GLOBAL variables for EZPLOT & EZSET */
-/*-------------------------------------*/
-bool ezplot_firstcall = TRUE; /* set to false on first call to EZSET or EZPLOT */
-struct ezplot_var ez; /* ezplot variables */
-/*----------------*/
-/* DEFAULT values */
-/*----------------*/
-
-#define TICKRATIO 0.4 /* ratio of minor to major tick lengths */
-#define MAXNUMFMT 15 /* maximum length of a numeric format */
-
-#define DEF_CRTMODE 0 /*GM_HIGHRES*/ /* default crt mode */
-#define DEF_CHARHEIGHT (1./43.) /* default size of characters in NDC */
-#define DEF_CHARWIDTH (1./80.)
-
-#define DEF_CURVE_CLR C_YELLOW
-
-
-/*----------------------------------------------------------------------*/
-/* GLOBAL VARIABLES */
-/*----------------------------------------------------------------------*/
-
-static
-double charwidth, charheight; /* Size of characters in NDC */
-
-static
-double xp_min, xp_max,
- yp_min, yp_max; /* boundry of plot frame in NDC */
-static
-double xa_min, xa_max,
- ya_min, ya_max; /* extent of axes in NDC */
-static
-double xgw_min, xgw_max,
- ygw_min, ygw_max; /* boundary of graph in input coords */
-static
-double xgn_min, xgn_max,
- ygn_min, ygn_max; /* boundy of graph in NDC */
-static
-double xt_min, xt_max,
- yt_min, yt_max; /* boundary of axis ticks */
-
-static
-double xl_min, xl_max,
- yl_min, yl_max; /* boundary of legend box */
-
-static double title_row; /* y-coord of title row */
-
-static double xtl_ofs; /* Offset y-coord of x tick labels from axis */
-static double ytl_ofs; /* Offset x-coord of y tick labels from axis */
-
-static double xlbl_row; /* row of x label in world coord */
-static double ylbl_col; /* column of y label in world coord */
-
-static
-double xw_tickinc, yw_tickinc; /* increment between major ticks in WC */
-
-static
-double xn_tickinc, yn_tickinc; /* increment between major ticks in NDC */
+EZPlotCurve::EZPlotCurve (const double* xData, const double* yData, int n, int color, int linestyle, int symbol, int symfreq, const string& legend)
+ : x(NULL), y(NULL), m_sLegend (legend)
+{
+ x = new double [n];
+ y = new double [n];
+
+#if 1
+ for (int i = 0; i < n; i++) {
+ x[i] = xData[i];
+ y[i] = yData[i];
+ }
+#else
+ int copyCount = n * sizeof(double);
+ memcpy (x, xData, copyCount);
+ memcpy (y, yData, copyCount);
+#endif
+ m_iPointCount = n;
+ m_iColor = color;
+ m_iLineStyle = linestyle;
+ m_iSymbol = symbol;
+ m_iSymbolFreq = symfreq;
+}
-static int x_nint, y_nint; /* number of intervals along x & y axes */
-static int x_fldwid, x_frac; /* numeric field sizes & number of digits */
-static int y_fldwid, y_frac; /* in fraction of number, used for printf() */
+EZPlotCurve::~EZPlotCurve ()
+{
+ delete x;
+ delete y;
+}
-static double xtl_wid, ytl_wid; /* length of ticks labels in NDC */
-static double tl_height; /* height of tick labels in NDC */
-static char x_numfmt[20]; /* format to print x tick labels */
-static char y_numfmt[20]; /* format to print y tick labels */
+void
+EZPlot::addCurve (const double *y, int n)
+{
+ double x [n];
+ for (int i = 0; i < n; i++)
+ x[i] = i;
-/*----------------------------------------------------------------------
- * FUNCTION IDENTICIFATION
- *
- * Name: EZPLOT
- * Programmer: Kevin Rosenberg
- * Date: 5-83 Version 1
- * 11-84 Version 2
- *
- * SYNOPSIS
- * ezplot (x, y, n)
- * double x[] x-coordinates of point makeing up a curve
- * double y[] y-coordinates of points makeing up a curve
- * int n Number of points in curve
- *
- * DESCRIPTION
- * This is a sophisticated plotting program.
- *
- *----------------------------------------------------------------------*/
+ addCurve (x, y, n);
+}
-SGP_ID
-ezplot (const float x[], const double y[], int num)
+void
+EZPlot::addCurve (const float x[], const double y[], int num)
{
double dx [num];
for (int i = 0; i < num; i++)
dx[i] = x[i];
- return ezplot (dx, y, num);
+ addCurve (dx, y, num);
}
-SGP_ID
-ezplot (const double x[], const double y[], int num)
+void
+EZPlot::addCurve (const double x[], const double y[], int num)
{
- unsigned int size;
- SGP_ID gid = NULL;
+ if (num < 1)
+ return;
- if (ez.i_plotimmediate == TRUE) {
- plot (&gid);
- return (gid);
- }
+ int iNumCurves = m_vecCurves.size();
- if (num < 1)
- return (NULL);
+ if (o_unknowncurves == FALSE && iNumCurves >= o_reqcurves)
+ clearCurves ();
- if (ezplot_firstcall == TRUE)
- ezinit();
+ if (o_unknowncurves == TRUE || iNumCurves < o_reqcurves) {
+ EZPlotCurve* pCurve = new EZPlotCurve (x, y, num, o_color, o_linestyle, o_symbol, o_symfreq, c_legend);
+ m_vecCurves.push_back (pCurve);
+ }
+
+ iNumCurves = m_vecCurves.size(); // recalculate
+ if (o_unknowncurves == FALSE && iNumCurves >= o_reqcurves) {
+ plot ();
+ clearCurves ();
+ }
+}
- if (ez.o_unknowncurves == FALSE && ez.i_numcurves >= ez.o_reqcurves)
- ezclear ();
- if (ez.i_numcurves < MAXCURVES &&
- (ez.o_unknowncurves == TRUE || ez.i_numcurves < ez.o_reqcurves)) {
- size = num * sizeof(double);
- ez.curve[ez.i_numcurves].x = new double [size];
- ez.curve[ez.i_numcurves].y = new double [size];
- for (int i = 0; i < num; i++) {
- ez.curve[ez.i_numcurves].x[i] = x[i];
- ez.curve[ez.i_numcurves].y[i] = y[i];
- }
- ez.curve[ez.i_numcurves].numpts = num;
- ez.curve[ez.i_numcurves].color = ez.o_color;
- ez.curve[ez.i_numcurves].linestyle = ez.o_linestyle;
- ez.curve[ez.i_numcurves].symbol = ez.o_symbol;
- ez.curve[ez.i_numcurves].symfreq = ez.o_symfreq;
- strncpy (ez.curve[ez.i_numcurves].legend, ez.c_legend, MAXLEGEND);
- ++ez.i_numcurves;
- }
-
- if (ez.o_unknowncurves == FALSE && ez.i_numcurves >= ez.o_reqcurves) {
- plot (&gid);
- ezclear ();
- }
+EZPlot::~EZPlot ()
+{
+ for (EZPlotCurveIterator i = m_vecCurves.begin(); i != m_vecCurves.end(); i++)
+ delete *i;
+}
+
+void
+EZPlot::clearCurves ()
+{
+ for (EZPlotCurveIterator i = m_vecCurves.begin(); i != m_vecCurves.end(); i++) delete *i;
+ m_vecCurves.erase (m_vecCurves.begin(), m_vecCurves.end());
+}
+
- return (gid);
+EZPlot::EZPlot (SGP& sgp)
+ : rSGP (sgp)
+{
+ curveinteract = -1;
+
+ charwidth = DEF_CHARWIDTH;
+ charheight = DEF_CHARHEIGHT;
+
+ c_xlabel = "X axis";
+ c_ylabel = "Y axis";
+ c_title = "";
+ c_legend = "";
+
+ o_reqcurves = 1;
+ o_unknowncurves = FALSE;
+
+ o_xporigin = 0.0;
+ o_yporigin = 0.0;
+ o_xlength = 1.0;
+ o_ylength = 1.0;
+
+ o_xaxis = LINEAR;
+ o_yaxis = LINEAR;
+
+ o_grid = FALSE;
+ o_box = FALSE;
+
+ o_xmajortick = 10;
+ o_ymajortick = 8;
+ o_xminortick = 4;
+ o_yminortick = 4;
+
+ o_color = DEF_CURVE_CLR;
+ o_symfreq = 1;
+ o_symbol = -1;
+ o_linestyle = SGP::LS_SOLID;
+
+ o_xtlabel = TRUE;
+ o_ytlabel = TRUE;
+ o_xticks = BELOW;
+ o_yticks = LEFT;
+
+ o_legendbox = INSIDE;
+ o_tag = FALSE;
+
+ s_xtitle = FALSE;
+ s_ytitle = FALSE;
+ s_xcross = FALSE;
+ s_ycross = FALSE;
+ s_lxfrac = FALSE;
+ s_lyfrac = FALSE;
+ s_xlegend = FALSE;
+ s_ylegend = FALSE;
+ s_textsize = FALSE;
+
+ clr_axis = C_WHITE; /* set fixed colors */
+ clr_title = (C_CYAN+8);
+ clr_label = (C_CYAN+8);
+ clr_legend = (C_RED+8);
+ clr_number = (C_GREEN+8);
+ clr_grid = (C_BLACK+8);
}
* EZPLOT() only
*
* CALLS
- * drawaxis() & make_numfmt()
+ * drawAxes() & make_numfmt()
*/
-static int plot (SGP_ID *gid)
+void
+EZPlot::plot ()
{
- double xmin, xmax; /* extend of curves in world coord */
- double ymin, ymax;
- double x_added_ticks; /* number of tick spaces added to axis */
- double y_added_ticks;
- double symwidth, symheight; /* size of symbol in NDC */
- double leg_width, leg_height; /* size of legend box */
- int num_leg; /* number of legend titles */
- int max_leg; /* longest legend in characters */
- int i, j, ip, ic, n;
-
- if (ez.i_numcurves <= 0)
- return (FALSE);
-
- if (ez.o_ustart == FALSE && *gid == NULL) {
- *gid = sgp2_init (0, 0, "Ezplot");
+ double x_added_ticks; /* number of tick spaces added to axis */
+ double y_added_ticks;
+ double symwidth, symheight; /* size of symbol in NDC */
+ double leg_width, leg_height; /* size of legend box */
+ int i, j, ip, n;
+
+ if (m_vecCurves.size() <= 0)
+ return;
+
+ if (s_textsize == TRUE)
+ charheight = v_textsize;
+ else
+ charheight = DEF_CHARHEIGHT;
+
+ const EZPlotCurve& firstCurve = *m_vecCurves[0];
+ double xmin = firstCurve.x[0]; // extent of curves in world coord
+ double xmax = xmin;
+ double ymin = firstCurve.y[0];
+ double ymax = ymin;
+
+ for (EZPlotCurveConstIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) {
+ const EZPlotCurve& curve = **iterCurve;
+
+ for (ip = 0; ip < curve.m_iPointCount; ip++) {
+ if (curve.x[ip] > xmax)
+ xmax = curve.x[ip];
+ else if (curve.x[ip] < xmin)
+ xmin = curve.x[ip];
+ if (curve.y[ip] > ymax)
+ ymax = curve.y[ip];
+ else if (curve.y[ip] < ymin)
+ ymin = curve.y[ip];
}
+ }
+
+ // extend graph limits for user defined axis cross positions
+ if (s_xcross == TRUE) {
+ if (v_xcross < xmin)
+ xmin = v_xcross;
+ else if (v_xcross > xmax)
+ xmax = v_xcross;
+ }
- if (ez.s_textsize == TRUE)
- charheight = ez.v_textsize;
- else
- charheight = DEF_CHARHEIGHT;
-
- gp_set_aspect (CRTDEV, 1.0);
+ if (s_ycross == TRUE) {
+ if (v_ycross < ymin)
+ ymin = v_ycross;
+ else if (v_ycross > ymax)
+ ymax = v_ycross;
+ }
- xmin = xmax = ez.curve[0].x[0];
- ymin = ymax = ez.curve[0].y[0];
+ /* find nice endpoints for axes */
+ axis_scale (xmin, xmax, o_xmajortick - 1, &xgw_min, &xgw_max, &x_nint);
+ axis_scale (ymin, ymax, o_ymajortick - 1, &ygw_min, &ygw_max, &y_nint);
- for (ic = 0; ic < ez.i_numcurves; ic++) {
- for (ip = 0; ip < ez.curve[ic].numpts; ip++) {
- if (ez.curve[ic].x[ip] > xmax)
- xmax = ez.curve[ic].x[ip];
- else if (ez.curve[ic].x[ip] < xmin)
- xmin = ez.curve[ic].x[ip];
- if (ez.curve[ic].y[ip] > ymax)
- ymax = ez.curve[ic].y[ip];
- else if (ez.curve[ic].y[ip] < ymin)
- ymin = ez.curve[ic].y[ip];
- }
- }
+ /* check if user set x-axis extents */
+ if (s_xmin == TRUE) {
+ xgw_min = v_xmin;
+ x_nint = o_xmajortick - 1;
+ }
+ if (s_xmax == TRUE) {
+ xgw_max = v_xmax;
+ x_nint = o_xmajortick - 1;
+ }
+
+ /* check if user set y-axis extents */
+ if (s_ymin == TRUE) {
+ ygw_min = v_ymin;
+ y_nint = o_ymajortick - 1;
+ }
+ if (s_ymax == TRUE) {
+ ygw_max = v_ymax;
+ y_nint = o_ymajortick - 1;
+ }
- /* extend graph limits for user defined axis cross positions */
+ /* calculate increment between major axis in world coordinates */
+ xw_tickinc = (xgw_max - xgw_min) / x_nint;
+ yw_tickinc = (ygw_max - ygw_min) / y_nint;
- if (ez.s_xcross == TRUE)
- {
- if (ez.v_xcross < xmin)
- xmin = ez.v_xcross;
- else if (ez.v_xcross > xmax)
- xmax = ez.v_xcross;
- }
+ /* we have now calcuated xgw_min, xyw_max, ygw_min, & ygw_max */
+
+ // set the number of decimal point to users' setting or default
+ // Two formats for numbers: Fixed: -nnn.f and Exponent: -n.fffE+eee
+ if (s_lxfrac == TRUE)
+ x_frac = v_lxfrac;
+ else
+ x_frac = -1;
- if (ez.s_ycross == TRUE)
- {
- if (ez.v_ycross < ymin)
- ymin = ez.v_ycross;
- else if (ez.v_ycross > ymax)
- ymax = ez.v_ycross;
- }
+ if (s_lyfrac == TRUE)
+ y_frac = v_lyfrac;
+ else
+ y_frac = -1;
- /* find nice endpoints for axes */
-
- axis_scale (xmin, xmax, ez.o_xmajortick - 1, &xgw_min, &xgw_max, &x_nint);
- axis_scale (ymin, ymax, ez.o_ymajortick - 1, &ygw_min, &ygw_max, &y_nint);
+ make_numfmt (x_numfmt, &x_fldwid, &x_frac, xgw_min, xgw_max, x_nint);
+ make_numfmt (y_numfmt, &y_fldwid, &y_frac, ygw_min, ygw_max, y_nint);
- /* check if user set x-axis extents */
+ xtl_wid = x_fldwid * charwidth; /* calc size of tick labels */
+ ytl_wid = y_fldwid * charwidth;
+ tl_height = charheight;
+
+ /* calculate the extent of the plot frame */
+ xp_min = o_xporigin;
+ yp_min = o_yporigin;
+ xp_max = xp_min + o_xlength;
+ yp_max = yp_min + o_ylength;
+
+ xp_min = clamp (xp_min, 0., 1.);
+ xp_max = clamp (xp_max, 0., 1.);
+ yp_min = clamp (yp_min, 0., 1.);
+ yp_max = clamp (yp_max, 0., 1.);
+
+ xa_min = xp_min; /* extent of axes */
+ xa_max = xp_max;
+ ya_min = yp_min;
+ ya_max = yp_max;
- if (ez.s_xmin == TRUE) {
- xgw_min = ez.v_xmin;
- x_nint = ez.o_xmajortick - 1;
+ /* adjust frame for title */
+ if (c_title.length() > 0)
+ ya_max -= 2.5 * charheight;
+ title_row = ya_max + 0.5 * charheight;
+
+ /* calculate legend box boundaries */
+ int max_leg = 0; /* longest legend in characters */
+ int num_leg = 0; /* number of legend titles */
+ for (EZPlotCurveConstIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) {
+ const EZPlotCurve& curve = **iterCurve;
+ if ((n = curve.m_sLegend.length()) > 0) {
+ ++num_leg;
+ max_leg = max (max_leg, n);
}
- if (ez.s_xmax == TRUE) {
- xgw_max = ez.v_xmax;
- x_nint = ez.o_xmajortick - 1;
- }
-
- /* check if user set y-axis extents */
+ }
+
+ if (num_leg > 0 && o_legendbox != NOLEGEND) {
+ leg_width = (max_leg + 2) * charwidth;
+ leg_height = num_leg * 3 * charheight;
- if (ez.s_ymin == TRUE) {
- ygw_min = ez.v_ymin;
- y_nint = ez.o_ymajortick - 1;
+ if (s_xlegend == TRUE)
+ xl_max = v_xlegend;
+ else {
+ xl_max = xa_max;
+ if (o_legendbox == OUTSIDE)
+ xa_max -= (leg_width + 0.5 * charwidth);
}
- if (ez.s_ymax == TRUE) {
- ygw_max = ez.v_ymax;
- y_nint = ez.o_ymajortick - 1;
- }
-
- /* calculate increment between major axis in world coordinates */
+ xl_min = xl_max - leg_width;
- xw_tickinc = (xgw_max - xgw_min) / x_nint;
- yw_tickinc = (ygw_max - ygw_min) / y_nint;
-
- /* we have now calcuated xgw_min, xyw_max, ygw_min, & ygw_max */
-
- /* set the number of decimal point to users' setting or default */
- /* Two formats for numbers
- Fixed: -nnn.f
- Exponent: -n.fffE+eee
- */
-
- if (ez.s_lxfrac == TRUE)
- x_frac = ez.v_lxfrac;
- else
- x_frac = -1;
-
- if (ez.s_lyfrac == TRUE)
- y_frac = ez.v_lyfrac;
+ if (s_ylegend == TRUE)
+ yl_max = v_ylegend;
else
- y_frac = -1;
-
- make_numfmt (x_numfmt, &x_fldwid, &x_frac, xgw_min, xgw_max, x_nint);
- make_numfmt (y_numfmt, &y_fldwid, &y_frac, ygw_min, ygw_max, y_nint);
-
- xtl_wid = x_fldwid * charwidth; /* calc size of tick labels */
- ytl_wid = y_fldwid * charwidth;
- tl_height = charheight;
-
- /* calculate the extent of the plot frame */
-
- xp_min = ez.o_xporigin;
- yp_min = ez.o_yporigin;
- xp_max = xp_min + ez.o_xlength;
- yp_max = yp_min + ez.o_ylength;
-
- xp_min = clamp (xp_min, 0., 1.);
- xp_max = clamp (xp_max, 0., 1.);
- yp_min = clamp (yp_min, 0., 1.);
- yp_max = clamp (yp_max, 0., 1.);
-
- xa_min = xp_min; /* extent of axes */
- xa_max = xp_max;
- ya_min = yp_min;
- ya_max = yp_max;
+ yl_max = ya_max;
- /* adjust frame for title */
-
- if (strlen(ez.c_title) != 0)
- ya_max -= 2.5 * charheight;
- title_row = ya_max + 0.5 * charheight;
-
- /* calculate legend box boundaries */
-
- max_leg = 0; /* longest legend in characters */
- num_leg = 0; /* number of legend titles */
- for (i = 0; i < ez.i_numcurves; i++)
- if ((n = strlen(ez.curve[i].legend)) > 0) {
- ++num_leg;
- max_leg = max(max_leg, n);
- }
-
- if (num_leg > 0 && ez.o_legendbox != NOLEGEND) {
- leg_width = (max_leg + 2) * charwidth;
- leg_height = num_leg * 3 * charheight;
-
- if (ez.s_xlegend == TRUE)
- xl_max = ez.v_xlegend;
- else {
- xl_max = xa_max;
- if (ez.o_legendbox == OUTSIDE)
- xa_max -= (leg_width + 0.5 * charwidth);
- }
- xl_min = xl_max - leg_width;
-
- if (ez.s_ylegend == TRUE)
- yl_max = ez.v_ylegend;
- else
- yl_max = ya_max;
-
- yl_min = yl_max - leg_height;
-
- sgp2_window (xl_min, yl_min, xl_max, yl_max);
- sgp2_viewport (xl_min, yl_min, xl_max, yl_max);
-
- sgp2_color (ez.clr_legend);
- sgp2_draw_rect (xl_min, yl_min, xl_max, yl_max);
-
- n = 0; /* current legend position */
- for (i = 0; i < ez.i_numcurves; i++) {
- double xmin, xmax, xinc, y;
-
- if (strlen(ez.curve[i].legend) == 0)
- continue;
-
- xmin = xl_min + 1.0 * charwidth;
- xmax = xl_max - 1.0 * charwidth;
- y = yl_max - (2.0 + n * 3) * charheight;
-
- sgp2_move_abs (xmin, y + 0.5 * charheight);
- sgp2_draw_text (ez.curve[i].legend);
- sgp2_color (ez.curve[i].color);
- if (ez.curve[i].linestyle != LS_NOLINE) {
- sgp2_line_style (ez.curve[i].linestyle);
- sgp2_move_abs (xmin, y);
- sgp2_line_abs (xmax, y);
- }
- if (ez.curve[i].symbol > 0) {
- xinc = (xmax - xmin) / (5 - 1);
- sgp2_line_style (LS_SOLID);
- for (j = 0; j < 5; j++) {
- sgp2_move_abs (xmin + j * xinc, y);
- symbol(ez.curve[i].symbol,
- 0.5 * charwidth, 0.5 * charheight);
- }
- }
- ++n; /* move to next legend position */
- }
- } /* end legend printing */
-
- /* calculate the extent of the axes */
-
- /*-------------------------*/
- /* adjust frame for labels */
- /*-------------------------*/
+ yl_min = yl_max - leg_height;
- /* x-label */
+ rSGP.setWindow (xl_min, yl_min, xl_max, yl_max);
+ rSGP.setViewport (xl_min, yl_min, xl_max, yl_max);
+ rSGP.setColor (clr_legend);
+ rSGP.drawRect (xl_min, yl_min, xl_max, yl_max);
- if (strlen(ez.c_xlabel) > 0)
- ya_min += 3.0 * charheight;
- xlbl_row = xp_min; /* put x-label on bottom of plot frame */
-
- /* y-label */
-
- if (strlen(ez.c_ylabel) > 0)
- xa_min += 3.0 * charwidth; /* reverse charsize because writing */
- /* text sideways */
- ylbl_col = xp_min + 2 * charwidth;
-
- /*------------------------------*/
- /* adjust frame for tick labels */
- /*------------------------------*/
-
- /* calc offset of tick labels from axes */
-
- if (ez.o_xaxis == NOAXIS || ez.o_xtlabel == FALSE)
- xtl_ofs = 0.0;
- else if (ez.o_xticks == BELOW)
- xtl_ofs = -2.5 * charheight;
- else if (ez.o_xticks == ABOVE)
- xtl_ofs = 1.5 * charheight;
-
- if (ez.o_yaxis == NOAXIS || ez.o_ytlabel == FALSE)
- ytl_ofs = 0.0;
- else if (ez.o_yticks == LEFT)
- ytl_ofs = -(1 + y_fldwid) * charwidth;
- else if (ez.o_yticks == RIGHT)
- ytl_ofs = 1.5 * charwidth;
-
- /* see if need to shrink axis extents and/or tick extents */
+ n = 0; /* current legend position */
+ for (EZPlotCurveIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) {
+ const EZPlotCurve& curve = **iterCurve;
+
+ if (curve.m_sLegend.length() == 0)
+ continue;
- if (xtl_ofs != 0.0 && ez.s_ycross == FALSE) {
- if (ez.o_xticks == BELOW) {
- ya_min += 2.5 * charheight;
- yt_min = ya_min;
- } else if (ez.o_xticks == ABOVE) {
- ya_min += 0.0;
- yt_min = ya_min + 2.5 * charheight;
+ double xmin = xl_min + 1.0 * charwidth;
+ double xmax = xl_max - 1.0 * charwidth;
+ double y = yl_max - (2.0 + n * 3) * charheight;
+
+ rSGP.moveAbs (xmin, y + 0.5 * charheight);
+ rSGP.drawText (curve.m_sLegend);
+ rSGP.setColor (curve.m_iColor);
+ if (curve.m_iLineStyle != SGP::LS_NOLINE) {
+ rSGP.setLineStyle (curve.m_iLineStyle);
+ rSGP.moveAbs (xmin, y);
+ rSGP.lineAbs (xmax, y);
}
- } else /* noaxis, no t-labels, or user set cross */
- yt_min = ya_min;
-
- if (ytl_ofs != 0.0 && ez.s_xcross == FALSE) {
- if (ez.o_yticks == LEFT) {
- xa_min += (1 + y_fldwid) * charwidth;
- xt_min = xa_min;
- } else if (ez.o_yticks == RIGHT) {
- xa_min += 0.0;
- xt_min = xa_min + ytl_ofs + y_fldwid * charwidth;
+ if (curve.m_iSymbol > 0) {
+ double xinc = (xmax - xmin) / (5 - 1);
+ rSGP.setLineStyle (SGP::LS_SOLID);
+ for (j = 0; j < 5; j++) {
+ rSGP.moveAbs (xmin + j * xinc, y);
+ symbol(curve.m_iSymbol, 0.5 * charwidth, 0.5 * charheight);
}
- } else
- xt_min = xa_min;
-
- xt_max = xa_max;
- yt_max = ya_max;
-
- /* decrease size of graph, if necessary, to accommadate space */
- /* between axis boundary and boundary of ticks */
-
- x_added_ticks = -1;
- y_added_ticks = -1;
-
- if (ez.o_xaxis == NOAXIS || ez.o_xtlabel == FALSE)
- x_added_ticks = 0;
- if (ez.o_yaxis == NOAXIS || ez.o_ytlabel == FALSE)
- y_added_ticks = 0;
-
- if (ez.o_grid == TRUE) {
- if (x_added_ticks < 0)
- x_added_ticks = 2;
- if (y_added_ticks < 0)
- y_added_ticks = 2;
+ }
+ ++n; /* move to next legend position */
}
-
- if (x_added_ticks < 0)
- {
- if (ez.o_yticks == LEFT || ez.s_ycross)
- x_added_ticks = 1;
- else
- x_added_ticks = 2;
- }
-
- if (y_added_ticks < 0)
- {
- if (ez.o_xticks == BELOW || ez.s_xcross)
- y_added_ticks = 1;
- else
- y_added_ticks = 2;
- }
-
- xn_tickinc = (xt_max - xt_min) / (x_nint + x_added_ticks);
- yn_tickinc = (yt_max - yt_min) / (y_nint + y_added_ticks);
-
- xt_min += 0.5 * x_added_ticks * xn_tickinc;
- xt_max -= 0.5 * x_added_ticks * xn_tickinc;
- yt_min += 0.5 * y_added_ticks * yn_tickinc;
- yt_max -= 0.5 * y_added_ticks * yn_tickinc;
-
- xgn_min = xt_min;
- xgn_max = xt_max;
- ygn_min = yt_min;
- ygn_max = yt_max;
-
- /*---------------------------------------------------------------------------*/
-
- /* PLOT CURVES */
-
- sgp2_line_style (LS_SOLID);
- drawaxis();
-
- /* Convert WC in graph boundary to axis boundary */
- {
- double xmin, xmax, ymin, ymax;
-
- sgp2_window (xgw_min, ygw_min, xgw_max, ygw_max); /* Graph boundary */
- sgp2_viewport (xgn_min, ygn_min, xgn_max, ygn_max);
-
- ndc_to_wc (xa_min, ya_min, &xmin, &ymin); /* calc WC of axis */
- ndc_to_wc (xa_max, ya_max, &xmax, &ymax); /* boundaries */
-
- sgp2_window (xmin, ymin, xmax, ymax); /* Set window to axis */
- sgp2_viewport (xa_min, ya_min, xa_max, ya_max); /* boundaries */
+ } /* end legend printing */
+
+ /* calculate the extent of the axes */
+
+ /*-------------------------*/
+ /* adjust frame for labels */
+ /*-------------------------*/
+
+ /* x-label */
+ if (c_xlabel.length() > 0)
+ ya_min += 3.0 * charheight;
+ xlbl_row = xp_min; /* put x-label on bottom of plot frame */
+
+ /* y-label */
+ if (c_ylabel.length() > 0)
+ xa_min += 3.0 * charwidth; /* reverse rSGP.setTextSize because writing text sideways */
+ ylbl_col = xp_min + 2 * charwidth;
+
+ /*------------------------------*/
+ /* adjust frame for tick labels */
+ /*------------------------------*/
+
+ /* calc offset of tick labels from axes */
+ if (o_xaxis == NOAXIS || o_xtlabel == FALSE)
+ xtl_ofs = 0.0;
+ else if (o_xticks == BELOW)
+ xtl_ofs = -2.5 * charheight;
+ else if (o_xticks == ABOVE)
+ xtl_ofs = 1.5 * charheight;
+
+ if (o_yaxis == NOAXIS || o_ytlabel == FALSE)
+ ytl_ofs = 0.0;
+ else if (o_yticks == LEFT)
+ ytl_ofs = -(1 + y_fldwid) * charwidth;
+ else if (o_yticks == RIGHT)
+ ytl_ofs = 1.5 * charwidth;
+
+ /* see if need to shrink axis extents and/or tick extents */
+ if (xtl_ofs != 0.0 && s_ycross == FALSE) {
+ if (o_xticks == BELOW) {
+ ya_min += 2.5 * charheight;
+ yt_min = ya_min;
+ } else if (o_xticks == ABOVE) {
+ ya_min += 0.0;
+ yt_min = ya_min + 2.5 * charheight;
}
-
- symwidth = charwidth * (xgw_max - xgw_min);
- symheight = charheight * (ygw_max - ygw_min);
-
- for (ic = 0; ic < ez.i_numcurves; ic++) {
- sgp2_color (ez.curve[ic].color);
- if (ez.curve[ic].linestyle != LS_NOLINE) {
- sgp2_line_style (ez.curve[ic].linestyle);
- sgp2_polyline_abs (ez.curve[ic].x, ez.curve[ic].y, ez.curve[ic].numpts);
- }
- if (ez.curve[ic].symbol > 0) {
- sgp2_line_style(LS_SOLID);
- sgp2_move_abs (ez.curve[ic].x[0], ez.curve[ic].y[0]);
- symbol (ez.curve[ic].symbol, symwidth, symheight);
- for (i = 1; i < ez.curve[ic].numpts; i++)
- if (i % ez.curve[ic].symfreq == 0 || i == ez.curve[ic].numpts - 1) {
- sgp2_move_abs (ez.curve[ic].x[i], ez.curve[ic].y[i]);
- symbol (ez.curve[ic].symbol, symwidth, symheight);
- }
- }
+ } else /* noaxis, no t-labels, or user set cross */
+ yt_min = ya_min;
+
+ if (ytl_ofs != 0.0 && s_xcross == FALSE) {
+ if (o_yticks == LEFT) {
+ xa_min += (1 + y_fldwid) * charwidth;
+ xt_min = xa_min;
+ } else if (o_yticks == RIGHT) {
+ xa_min += 0.0;
+ xt_min = xa_min + ytl_ofs + y_fldwid * charwidth;
}
+ } else
+ xt_min = xa_min;
+
+ xt_max = xa_max;
+ yt_max = ya_max;
+
+ /* decrease size of graph, if necessary, to accommadate space */
+ /* between axis boundary and boundary of ticks */
+
+ x_added_ticks = -1;
+ y_added_ticks = -1;
+
+ if (o_xaxis == NOAXIS || o_xtlabel == FALSE)
+ x_added_ticks = 0;
+ if (o_yaxis == NOAXIS || o_ytlabel == FALSE)
+ y_added_ticks = 0;
+
+ if (o_grid == TRUE) {
+ if (x_added_ticks < 0)
+ x_added_ticks = 2;
+ if (y_added_ticks < 0)
+ y_added_ticks = 2;
+ }
+
+ if (x_added_ticks < 0) {
+ if (o_yticks == LEFT || s_ycross)
+ x_added_ticks = 1;
+ else
+ x_added_ticks = 2;
+ }
+
+ if (y_added_ticks < 0) {
+ if (o_xticks == BELOW || s_xcross)
+ y_added_ticks = 1;
+ else
+ y_added_ticks = 2;
+ }
+
+ xn_tickinc = (xt_max - xt_min) / (x_nint + x_added_ticks);
+ yn_tickinc = (yt_max - yt_min) / (y_nint + y_added_ticks);
+
+ xt_min += 0.5 * x_added_ticks * xn_tickinc;
+ xt_max -= 0.5 * x_added_ticks * xn_tickinc;
+ yt_min += 0.5 * y_added_ticks * yn_tickinc;
+ yt_max -= 0.5 * y_added_ticks * yn_tickinc;
+
+ xgn_min = xt_min;
+ xgn_max = xt_max;
+ ygn_min = yt_min;
+ ygn_max = yt_max;
+
+ /*---------------------------------------------------------------------------*/
+
+ /* PLOT CURVES */
+
+ rSGP.setLineStyle (SGP::LS_SOLID);
+ drawAxes();
+
+ /* Convert WC in graph boundary to axis boundary */
+ rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max); /* Graph boundary */
+ rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max);
- if (ez.o_ufinish == FALSE)
- termgrf2 ();
-
- return (TRUE);
+ double xminTemp = xa_min, xmaxTemp = xa_max;
+ double yminTemp = ya_min, ymaxTemp = ya_max;
+ rSGP.transformNDCtoMC (&xminTemp, &yminTemp); // calc WC to axis boundaries
+ rSGP.transformNDCtoMC (&yminTemp, &ymaxTemp);
+
+ rSGP.setWindow (xminTemp, yminTemp, xmaxTemp, ymaxTemp); // Set window to axis boundaries
+ rSGP.setViewport (xa_min, ya_min, xa_max, ya_max);
+
+ symwidth = charwidth * (xgw_max - xgw_min);
+ symheight = charheight * (ygw_max - ygw_min);
+
+ for (EZPlotCurveIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) {
+ const EZPlotCurve& curve = **iterCurve;
+
+ rSGP.setColor (curve.m_iColor);
+ if (curve.m_iLineStyle != SGP::LS_NOLINE) {
+ rSGP.setLineStyle (curve.m_iLineStyle);
+ rSGP.polylineAbs (curve.x, curve.y, curve.m_iPointCount);
+ }
+ if (curve.m_iSymbol > 0) {
+ rSGP.setLineStyle (SGP::LS_SOLID);
+ rSGP.moveAbs (curve.x[0], curve.y[0]);
+ symbol (curve.m_iSymbol, symwidth, symheight);
+ for (i = 1; i < curve.m_iPointCount; i++)
+ if (i % curve.m_iSymbolFreq == 0 || i == curve.m_iPointCount - 1) {
+ rSGP.moveAbs (curve.x[i], curve.y[i]);
+ symbol (curve.m_iSymbol, symwidth, symheight);
+ }
+ }
+ }
}
/* NAME
- * drawaxis INTERNAL routine to draw axis & label them
+ * drawAxes INTERNAL routine to draw axis & label them
*
* SYNOPSIS
- * drawaxis()
+ * drawAxes()
*/
-static void drawaxis(void)
+
+void
+EZPlot::drawAxes(void)
{
- double xticklen = 0, yticklen = 0; /* length of ticks in NDC */
- double minorinc; /* increment between minor axes */
- double xaxispos, yaxispos; /* crossing of axes */
- double x, y, x2, y2;
- bool axis_near; /* TRUE if axis too close to print t-label */
- int i, j;
- char str[100];
- char *numstr;
-
- charsize (charwidth, charheight);
- settextclr (1, -1);
-
- if (ez.o_xticks == ABOVE)
- xticklen = charheight;
- else if (ez.o_xticks == BELOW)
- xticklen = -charheight;
-
- if (ez.o_yticks == RIGHT)
- yticklen = charwidth;
- else if (ez.o_yticks == LEFT)
- yticklen = -charwidth;
-
- sgp2_window (xp_min, yp_min, xp_max, yp_max);
- sgp2_viewport (xp_min, yp_min, xp_max, yp_max);
-
- if (strlen (ez.c_title) != 0) {
- sgp2_move_abs (xa_min + (xa_max-xa_min)/2 - strlen(ez.c_title)*charwidth, title_row);
- charsize (charwidth * 2.0, charheight * 2.0);
- settextclr (ez.clr_title, -1);
- sgp2_draw_text (ez.c_title);
- charsize (charwidth, charheight);
+ double xticklen = 0, yticklen = 0; /* length of ticks in NDC */
+ double minorinc; /* increment between minor axes */
+ double xaxispos, yaxispos; /* crossing of axes */
+ double x, y, x2, y2;
+ bool axis_near; /* TRUE if axis too close to print t-label */
+ int i, j;
+ char str[100];
+ char *numstr;
+
+ rSGP.setTextSize (charheight);
+ rSGP.setTextColor (1, -1);
+
+ if (o_xticks == ABOVE)
+ xticklen = charheight;
+ else if (o_xticks == BELOW)
+ xticklen = -charheight;
+
+ if (o_yticks == RIGHT)
+ yticklen = charwidth;
+ else if (o_yticks == LEFT)
+ yticklen = -charwidth;
+
+ rSGP.setWindow (xp_min, yp_min, xp_max, yp_max);
+ rSGP.setViewport (xp_min, yp_min, xp_max, yp_max);
+
+ if (c_title.length() > 0) {
+ rSGP.moveAbs (xa_min + (xa_max-xa_min)/2 - c_title.length()*charwidth, title_row);
+ rSGP.setTextSize (charheight * 2.0);
+ rSGP.setTextColor (clr_title, -1);
+ rSGP.drawText (c_title);
+ rSGP.setTextSize (charheight);
+ }
+
+ if (o_grid == TRUE || o_box == TRUE) {
+ rSGP.setColor (clr_axis);
+ rSGP.moveAbs (xa_min, ya_min);
+ rSGP.lineAbs (xa_max, ya_min);
+ rSGP.lineAbs (xa_max, ya_max);
+ rSGP.lineAbs (xa_min, ya_max);
+ rSGP.lineAbs (xa_min, ya_min);
+ }
+
+ /* calculate position of axes */
+
+ /* x-axis */
+ if (s_ycross == TRUE) { /* convert users' world-coord */
+ xaxispos = v_ycross; /* axis to its position in NDC */
+ rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max);
+ rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max);
+ x = xgw_min;
+ rSGP.transformMCtoNDC (x, xaxispos, &x, &xaxispos);
+ } else
+ xaxispos = ya_min;
+
+ /* y-axis */
+ if (s_xcross == TRUE) { /* convert users' world-coord */
+ yaxispos = v_xcross; /* axis to its NDC position */
+ rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max);
+ rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max);
+ y = ygw_min;
+ rSGP.transformMCtoNDC (yaxispos, y, &yaxispos, &y);
+ } else
+ yaxispos = xa_min;
+
+ /*-------------*/
+ /* draw x-axis */
+ /*-------------*/
+
+ if (o_xaxis == LINEAR) {
+ rSGP.setWindow (xp_min, yp_min, xp_max, yp_max);
+ rSGP.setViewport (xp_min, yp_min, xp_max, yp_max);
+
+ /* draw axis line */
+
+ rSGP.setColor (clr_axis);
+ if (o_tag && !o_grid && !o_box && s_xcross) {
+ rSGP.moveAbs (xa_min, xaxispos - charheight);
+ rSGP.lineAbs (xa_min, xaxispos + charheight);
}
-
- if (ez.o_grid == TRUE || ez.o_box == TRUE) {
- sgp2_color (ez.clr_axis);
- sgp2_move_abs (xa_min, ya_min);
- sgp2_line_abs (xa_max, ya_min);
- sgp2_line_abs (xa_max, ya_max);
- sgp2_line_abs (xa_min, ya_max);
- sgp2_line_abs (xa_min, ya_min);
+ rSGP.moveAbs (xa_min, xaxispos);
+ rSGP.lineAbs (xa_max, xaxispos);
+ if (o_tag && !o_grid && !o_box) {
+ rSGP.moveAbs (xa_max, xaxispos - charheight);
+ rSGP.lineAbs (xa_max, xaxispos + charheight);
}
-
- /* calculate position of axes */
-
- /* x-axis */
- if (ez.s_ycross == TRUE) { /* convert users' world-coord */
- xaxispos = ez.v_ycross; /* axis to its position in NDC */
- sgp2_window (xgw_min, ygw_min, xgw_max, ygw_max);
- sgp2_viewport (xgn_min, ygn_min, xgn_max, ygn_max);
- x = xgw_min;
- wc_to_ndc (x, xaxispos, &x, &xaxispos);
- } else
- xaxispos = ya_min;
-
- /* y-axis */
- if (ez.s_xcross == TRUE) { /* convert users' world-coord */
- yaxispos = ez.v_xcross; /* axis to its NDC position */
- sgp2_window (xgw_min, ygw_min, xgw_max, ygw_max);
- sgp2_viewport (xgn_min, ygn_min, xgn_max, ygn_max);
- y = ygw_min;
- wc_to_ndc (yaxispos, y, &yaxispos, &y);
- } else
- yaxispos = xa_min;
-
- /*-------------*/
- /* draw x-axis */
- /*-------------*/
-
- if (ez.o_xaxis == LINEAR) {
- sgp2_window (xp_min, yp_min, xp_max, yp_max);
- sgp2_viewport (xp_min, yp_min, xp_max, yp_max);
-
- /* draw axis line */
-
- sgp2_color (ez.clr_axis);
- if (ez.o_tag && !ez.o_grid && !ez.o_box && ez.s_xcross) {
- sgp2_move_abs (xa_min, xaxispos - charheight);
- sgp2_line_abs (xa_min, xaxispos + charheight);
+
+ if (o_grid == TRUE) {
+ rSGP.setColor (clr_grid);
+ for (i = 0; i <= x_nint; i++) {
+ rSGP.moveAbs (xt_min + xn_tickinc * i, ya_max);
+ rSGP.lineAbs (xt_min + xn_tickinc * i, ya_min);
+ }
+ }
+ rSGP.moveAbs (xa_min + (xa_max-xa_min)/2 - c_xlabel.length()*charwidth, xlbl_row);
+ rSGP.setTextSize (charheight * 2.0);
+ rSGP.setTextColor (clr_label, -1);
+ rSGP.drawText (c_xlabel);
+ rSGP.setTextSize (charheight);
+ minorinc = xn_tickinc / (o_xminortick + 1);
+
+ for (i = 0; i <= x_nint; i++) {
+ x = xt_min + xn_tickinc * i;
+ rSGP.setColor (clr_axis);
+ rSGP.moveAbs (x, xaxispos);
+ rSGP.lineAbs (x, xaxispos + xticklen);
+ if (i != x_nint)
+ for (j = 1; j <= o_xminortick; j++) {
+ x2 = x + minorinc * j;
+ rSGP.moveAbs (x2, xaxispos);
+ rSGP.lineAbs (x2, xaxispos + TICKRATIO * xticklen);
}
- sgp2_move_abs (xa_min, xaxispos);
- sgp2_line_abs (xa_max, xaxispos);
- if (ez.o_tag && !ez.o_grid && !ez.o_box) {
- sgp2_move_abs (xa_max, xaxispos - charheight);
- sgp2_line_abs (xa_max, xaxispos + charheight);
+ axis_near = FALSE;
+ if (xaxispos + xtl_ofs > ya_min && o_yaxis != NOAXIS) {
+ double xw, x, y, d;
+
+ xw = xgw_min + i * xw_tickinc;
+ rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max);
+ rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max);
+ rSGP.transformMCtoNDC (xw, y, &x, &y);
+ rSGP.setWindow (xp_min, yp_min, xp_max, yp_max);
+ rSGP.setViewport (xp_min, yp_min, xp_max, yp_max);
+ d = x - yaxispos;
+ if (o_yticks == RIGHT && d >= 0 && d < 0.9 * xn_tickinc)
+ axis_near = TRUE;
+ if (o_yticks == LEFT && d <= 0 && d > -0.9 * xn_tickinc)
+ axis_near = TRUE;
+ }
+
+ if (o_xtlabel == TRUE && axis_near == FALSE) {
+ snprintf (str, sizeof(str), x_numfmt, xgw_min + xw_tickinc * i);
+ numstr = str_skip_head (str, " ");
+ rSGP.moveAbs (x-strlen(numstr)*charwidth/2,xaxispos + xtl_ofs);
+ rSGP.setTextColor (clr_number, -1);
+ rSGP.drawText (numstr);
+ }
+ }
+ } /* x - axis */
+
+
+ /*--------*/
+ /* y-axis */
+ /*--------*/
+
+ if (o_yaxis == LINEAR) {
+ rSGP.setWindow (xp_min, yp_min, xp_max, yp_max);
+ rSGP.setViewport (xp_min, yp_min, xp_max, yp_max);
+
+ rSGP.setColor (clr_axis);
+ if (o_tag && !o_grid && !o_box && s_ycross) {
+ rSGP.moveAbs (yaxispos - charwidth, ya_min);
+ rSGP.lineAbs (yaxispos + charwidth, ya_min);
+ }
+ rSGP.moveAbs (yaxispos, ya_min);
+ rSGP.lineAbs (yaxispos, ya_max);
+ if (o_tag && !o_grid && !o_box) {
+ rSGP.moveAbs (yaxispos - charwidth, ya_max);
+ rSGP.lineAbs (yaxispos + charwidth, ya_max);
+ }
+
+ if (o_grid == TRUE) {
+ rSGP.setColor (clr_grid);
+ for (i = 0; i <= y_nint; i++) {
+ y = yt_min + yn_tickinc * i;
+ rSGP.moveAbs (xa_max, y);
+ rSGP.lineAbs (xa_min, y);
+ }
+ }
+ rSGP.moveAbs (ylbl_col,ya_min + (ya_max-ya_min)/2 - c_ylabel.length()*charheight);
+ rSGP.setTextAngle (HALFPI);
+ rSGP.setTextSize (2 * charheight);
+ rSGP.setTextColor (clr_label, -1);
+ rSGP.drawText (c_ylabel);
+ rSGP.setTextAngle (0.0);
+ rSGP.setTextSize (charheight);
+ minorinc = yn_tickinc / (o_yminortick + 1);
+
+ for (i = 0; i <= y_nint; i++) {
+ y = yt_min + yn_tickinc * i;
+ rSGP.setColor (clr_axis);
+ rSGP.moveAbs (yaxispos, y);
+ rSGP.lineAbs (yaxispos + yticklen, y);
+ if (i != y_nint)
+ for (j = 1; j <= o_yminortick; j++) {
+ y2 = y + minorinc * j;
+ rSGP.moveAbs (yaxispos, y2);
+ rSGP.lineAbs (yaxispos + TICKRATIO * yticklen, y2);
}
+ axis_near = FALSE;
+ if (yaxispos + ytl_ofs > xa_min && o_xaxis != NOAXIS) {
+ double yw, x, y, d;
+
+ yw = ygw_min + i * yw_tickinc;
+ rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max);
+ rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max);
+ rSGP.transformMCtoNDC (x, yw, &x, &y);
+ rSGP.setWindow (xp_min, yp_min, xp_max, yp_max);
+ rSGP.setViewport (xp_min, yp_min, xp_max, yp_max);
+ d = y - xaxispos;
+ if (o_xticks == ABOVE && d >= 0 && d < 0.9 * yn_tickinc)
+ axis_near = TRUE;
+ if (o_xticks == BELOW && d <= 0 && d > -0.9 * yn_tickinc)
+ axis_near = TRUE;
+ }
+ if (o_ytlabel == TRUE && axis_near == FALSE) {
+ snprintf (str, sizeof(str), y_numfmt, ygw_min + yw_tickinc * i);
+ rSGP.moveAbs (yaxispos + ytl_ofs, y - 0.5 * charheight);
+ rSGP.setTextColor (clr_number, -1);
+ rSGP.drawText (str);
+ }
+ }
+ } /* y - axis */
+}
- if (ez.o_grid == TRUE) {
- sgp2_color (ez.clr_grid);
- for (i = 0; i <= x_nint; i++) {
- sgp2_move_abs (xt_min + xn_tickinc * i, ya_max);
- sgp2_line_abs (xt_min + xn_tickinc * i, ya_min);
- }
- }
- sgp2_move_abs (xa_min + (xa_max-xa_min)/2 - strlen(ez.c_xlabel)*charwidth, xlbl_row);
- charsize (charwidth * 2.0, charheight * 2.0);
- settextclr (ez.clr_label, -1);
- sgp2_draw_text (ez.c_xlabel);
- charsize (charwidth, charheight);
- minorinc = xn_tickinc / (ez.o_xminortick + 1);
-
- for (i = 0; i <= x_nint; i++) {
- x = xt_min + xn_tickinc * i;
- sgp2_color (ez.clr_axis);
- sgp2_move_abs (x, xaxispos);
- sgp2_line_abs (x, xaxispos + xticklen);
- if (i != x_nint)
- for (j = 1; j <= ez.o_xminortick; j++) {
- x2 = x + minorinc * j;
- sgp2_move_abs (x2, xaxispos);
- sgp2_line_abs (x2, xaxispos + TICKRATIO * xticklen);
- }
- axis_near = FALSE;
- if (xaxispos + xtl_ofs > ya_min && ez.o_yaxis != NOAXIS) {
- double xw, x, y, d;
-
- xw = xgw_min + i * xw_tickinc;
- sgp2_window (xgw_min, ygw_min, xgw_max, ygw_max);
- sgp2_viewport (xgn_min, ygn_min, xgn_max, ygn_max);
- wc_to_ndc (xw, y, &x, &y);
- sgp2_window (xp_min, yp_min, xp_max, yp_max);
- sgp2_viewport (xp_min, yp_min, xp_max, yp_max);
- d = x - yaxispos;
- if (ez.o_yticks == RIGHT && d >= 0 && d < 0.9 * xn_tickinc)
- axis_near = TRUE;
- if (ez.o_yticks == LEFT && d <= 0 && d > -0.9 * xn_tickinc)
- axis_near = TRUE;
- }
-
- if (ez.o_xtlabel == TRUE && axis_near == FALSE) {
- snprintf (str, sizeof(str), x_numfmt, xgw_min + xw_tickinc * i);
- numstr = str_skip_head (str, " ");
- sgp2_move_abs (x-strlen(numstr)*charwidth/2,xaxispos + xtl_ofs);
- settextclr (ez.clr_number, -1);
- sgp2_draw_text (numstr);
- }
- }
- } /* x - axis */
+void
+EZPlot::symbol (int sym, double symwidth, double symheight)
+{
+ if (sym <= 0)
+ return;
+
+ if (sym == SB_CROSS) {
+ rSGP.moveRel (-0.5 * symwidth, -0.5 * symheight);
+ rSGP.lineRel (symwidth, symheight);
+ rSGP.moveRel (-symwidth, 0.0);
+ rSGP.lineRel (symwidth, -symheight);
+ rSGP.moveRel (-0.5 * symwidth, 0.5 * symheight);
+ } else if (sym == SB_PLUS) {
+ rSGP.moveRel (-0.5 * symwidth, 0.0);
+ rSGP.lineRel (symwidth, 0.0);
+ rSGP.moveRel (-0.5 * symwidth, -0.5 * symheight);
+ rSGP.lineRel (0.0, symheight);
+ rSGP.moveRel (0.0, -0.5 * symheight);
+ } else if (sym == SB_BOX) {
+ rSGP.moveRel (-0.5 * symwidth, -0.5 * symheight);
+ rSGP.lineRel (symwidth, 0.0);
+ rSGP.lineRel (0.0, symheight);
+ rSGP.lineRel (-symwidth, 0.0);
+ rSGP.lineRel (0.0, -symheight);
+ rSGP.moveRel (0.5 * symwidth, 0.5 * symheight);
+ } else if (sym == SB_CIRCLE) {
+ rSGP.drawCircle (symwidth);
+ } else if (sym == SB_ERRORBAR) {
+ rSGP.moveRel (-0.5 * symwidth, 0.5 * symheight);
+ rSGP.lineRel (symwidth, 0.0);
+ rSGP.moveRel (-0.5 * symwidth, 0.0);
+ rSGP.lineRel (0.0, -symheight);
+ rSGP.moveRel (-0.5 * symwidth, 0.0);
+ rSGP.lineRel (symwidth, 0.0);
+ rSGP.moveRel (-0.5 * symwidth, 0.5 * symheight);
+ }
+}
- /*--------*/
- /* y-axis */
- /*--------*/
- if (ez.o_yaxis == LINEAR) {
- sgp2_window (xp_min, yp_min, xp_max, yp_max);
- sgp2_viewport (xp_min, yp_min, xp_max, yp_max);
- sgp2_color (ez.clr_axis);
- if (ez.o_tag && !ez.o_grid && !ez.o_box && ez.s_ycross) {
- sgp2_move_abs (yaxispos - charwidth, ya_min);
- sgp2_line_abs (yaxispos + charwidth, ya_min);
- }
- sgp2_move_abs (yaxispos, ya_min);
- sgp2_line_abs (yaxispos, ya_max);
- if (ez.o_tag && !ez.o_grid && !ez.o_box) {
- sgp2_move_abs (yaxispos - charwidth, ya_max);
- sgp2_line_abs (yaxispos + charwidth, ya_max);
- }
+/* NAME
+ * axis_scale calculates graph axis scaling
+ *
+ * SYNOPSIS:
+ * retval = axis_scale (min, max, nint, minp, maxp, nintp,
+ * rec_total, rec_frac)
+ *
+ * INPUT:
+ * double min Smallest value to plot
+ * double max Largest value to plot
+ * int nint Number of intervals desired
+ *
+ * OUTPUT:
+ * int retval FALSE if illegal parameters, else TRUE
+ * double *minp Minimum graph value
+ * double *maxp Maximum graph value
+ * int *nintp Number of intervals for graph
+ * int *rec_total Recommended field width for printing out the number
+ * int *rec_frac Recommended number of digits for print fraction
+ */
- if (ez.o_grid == TRUE) {
- sgp2_color (ez.clr_grid);
- for (i = 0; i <= y_nint; i++) {
- y = yt_min + yn_tickinc * i;
- sgp2_move_abs (xa_max, y);
- sgp2_line_abs (xa_min, y);
- }
- }
- sgp2_move_abs (ylbl_col,ya_min + (ya_max-ya_min)/2 - strlen(ez.c_ylabel)*charheight);
- textangle (HALFPI);
- charsize (2 * charheight, 2 * charwidth); /* axis reversed */
- settextclr (ez.clr_label, -1);
- sgp2_draw_text (ez.c_ylabel);
- textangle (0.0);
- charsize (charwidth, charheight);
- minorinc = yn_tickinc / (ez.o_yminortick + 1);
-
- for (i = 0; i <= y_nint; i++) {
- y = yt_min + yn_tickinc * i;
- sgp2_color (ez.clr_axis);
- sgp2_move_abs (yaxispos, y);
- sgp2_line_abs (yaxispos + yticklen, y);
- if (i != y_nint)
- for (j = 1; j <= ez.o_yminortick; j++) {
- y2 = y + minorinc * j;
- sgp2_move_abs (yaxispos, y2);
- sgp2_line_abs (yaxispos + TICKRATIO * yticklen, y2);
- }
- axis_near = FALSE;
- if (yaxispos + ytl_ofs > xa_min && ez.o_xaxis != NOAXIS) {
- double yw, x, y, d;
-
- yw = ygw_min + i * yw_tickinc;
- sgp2_window (xgw_min, ygw_min, xgw_max, ygw_max);
- sgp2_viewport (xgn_min, ygn_min, xgn_max, ygn_max);
- wc_to_ndc (x, yw, &x, &y);
- sgp2_window (xp_min, yp_min, xp_max, yp_max);
- sgp2_viewport (xp_min, yp_min, xp_max, yp_max);
- d = y - xaxispos;
- if (ez.o_xticks == ABOVE && d >= 0 && d < 0.9 * yn_tickinc)
- axis_near = TRUE;
- if (ez.o_xticks == BELOW && d <= 0 && d > -0.9 * yn_tickinc)
- axis_near = TRUE;
- }
- if (ez.o_ytlabel == TRUE && axis_near == FALSE) {
- snprintf (str, sizeof(str), y_numfmt, ygw_min + yw_tickinc * i);
- sgp2_move_abs (yaxispos + ytl_ofs, y - 0.5 * charheight);
- settextclr (ez.clr_number, -1);
- sgp2_draw_text (str);
- }
- }
- } /* y - axis */
+int
+EZPlot::axis_scale (double min, double max, int nint, double *minp, double *maxp, int *nintp)
+{
+ if (min >= max || nint < 1) {
+ sys_error (ERR_WARNING, "Invalid params: min=%lf, min=%lf, num intervals=%d [axis_scale]", min, max, nint);
+ return (FALSE);
+ }
+
+ double eps = 0.025;
+ double a = fabs(min);
+ if (fabs(min) < fabs(max))
+ a = fabs(max);
+ double scale = pow (10.0, floor(log10(a)));
+ loop:
+ double mina = min / scale;
+ double maxa = max / scale;
+ double d = (maxa - mina) / nint;
+ double j = d * eps;
+ double e = floor (log10(d));
+ double f = d / pow (10.0, e);
+ double v = 10.0;
+ if (f < sqrt(2.0))
+ v = 1.0;
+ else if (f < sqrt (10.0))
+ v = 2.0;
+ else if (f < sqrt (50.0))
+ v = 5.0;
+ double wdt = v * pow (10.0, e);
+ double g = floor (mina / wdt);
+ if (fabs(g + 1 - mina / wdt) < j)
+ g = g + 1;
+ *minp = wdt * g;
+ double h = floor (maxa / wdt) + 1.0;
+ if (fabs(maxa / wdt + 1 - h) < j)
+ h = h - 1;
+ *maxp = wdt * h;
+ *nintp = static_cast<int>(h - g);
+ if (fabs(*maxp) >= 10.0 || fabs(*minp) >= 10.0) {
+ scale = scale * 10.0;
+ goto loop;
+ }
+
+ *minp *= scale;
+ *maxp *= scale;
+
+ return (TRUE);
}
-static void
-symbol (int sym, double symwidth, double symheight)
+/* NAME
+ * make_numfmt Make a numeric format string
+ *
+ * SYNOPSIS
+ * make_numfmt (fmtstr, fldwid, nfrac, min, max, nint)
+ * char *fmtstr Returned format string for printf()
+ * int *fldwid Returned field width
+ * int *nfrac If < 0, then calculate best number of
+ * fraction places & return that value
+ * If >= 0, then use that number of places
+ * double min Minimum value
+ * double max Maximum value
+ * int nint Number of intervals between min & max
+ *
+ * DESCRIPTION
+ * This routine is written as an INTERNAL routine for EZPLOT
+ */
+
+static inline double
+trunc (double x)
{
- if (sym <= 0)
- return;
-
- if (sym == SB_CROSS) {
- sgp2_move_rel (-0.5 * symwidth, -0.5 * symheight);
- sgp2_line_rel (symwidth, symheight);
- sgp2_move_rel (-symwidth, 0.0);
- sgp2_line_rel (symwidth, -symheight);
- sgp2_move_rel (-0.5 * symwidth, 0.5 * symheight);
- } else if (sym == SB_PLUS) {
- sgp2_move_rel (-0.5 * symwidth, 0.0);
- sgp2_line_rel (symwidth, 0.0);
- sgp2_move_rel (-0.5 * symwidth, -0.5 * symheight);
- sgp2_line_rel (0.0, symheight);
- sgp2_move_rel (0.0, -0.5 * symheight);
- } else if (sym == SB_BOX) {
- sgp2_move_rel (-0.5 * symwidth, -0.5 * symheight);
- sgp2_line_rel (symwidth, 0.0);
- sgp2_line_rel (0.0, symheight);
- sgp2_line_rel (-symwidth, 0.0);
- sgp2_line_rel (0.0, -symheight);
- sgp2_move_rel (0.5 * symwidth, 0.5 * symheight);
- } else if (sym == SB_CIRCLE) {
- sgp2_draw_circle (symwidth);
- } else if (sym == SB_ERRORBAR) {
- sgp2_move_rel (-0.5 * symwidth, 0.5 * symheight);
- sgp2_line_rel (symwidth, 0.0);
- sgp2_move_rel (-0.5 * symwidth, 0.0);
- sgp2_line_rel (0.0, -symheight);
- sgp2_move_rel (-0.5 * symwidth, 0.0);
- sgp2_line_rel (symwidth, 0.0);
- sgp2_move_rel (-0.5 * symwidth, 0.5 * symheight);
- }
+ double integer;
+
+ modf (x, &integer);
+
+ return (integer);
}
-
-void ezinit(void)
+void
+EZPlot::make_numfmt (char *fmtstr, int *fldwid, int *nfrac, double minval, double maxval, int nint)
{
- /* EZPLOT Variables */
+ int wid, frac, expon;
- charwidth = DEF_CHARWIDTH; /* KR_FIX: Make these ez.o_ variables */
- charheight = DEF_CHARHEIGHT;
+ double delta = (maxval - minval) / nint;
+ double absmin = fabs(minval);
+ double absmax = fabs(maxval);
+ double logt = log10( max(absmin, absmax) );
- /* EZPLOT & EZSET Variables */
-
- strcpy (ez.c_xlabel, "X axis");
- strcpy (ez.c_ylabel, "Y axis");
- strcpy (ez.c_title, "");
- strcpy (ez.c_legend, "");
-
- ezplot_firstcall = FALSE;
-
- ez.i_numcurves = 0;
- ez.i_plotimmediate = FALSE;
-
- ez.o_reqcurves = 1;
- ez.o_unknowncurves = FALSE;
-
- ez.o_ustart = FALSE;
- ez.o_ufinish = FALSE;
-
- ez.o_xporigin = 0.0;
- ez.o_yporigin = 0.0;
- ez.o_xlength = 1.0;
- ez.o_ylength = 1.0;
-
- ez.o_xaxis = LINEAR;
- ez.o_yaxis = LINEAR;
-
- ez.o_grid = FALSE;
- ez.o_box = FALSE;
-
- ez.o_xmajortick = 10;
- ez.o_ymajortick = 8;
- ez.o_xminortick = 4;
- ez.o_yminortick = 4;
-
- ez.o_color = DEF_CURVE_CLR;
- ez.o_symfreq = 1;
- ez.o_symbol = -1;
- ez.o_linestyle = LS_SOLID;
-
- ez.o_xtlabel = TRUE;
- ez.o_ytlabel = TRUE;
- ez.o_xticks = BELOW;
- ez.o_yticks = LEFT;
-
- ez.o_legendbox = INSIDE;
- ez.o_tag = FALSE;
-
- ez.s_xtitle = FALSE;
- ez.s_ytitle = FALSE;
- ez.s_xcross = FALSE;
- ez.s_ycross = FALSE;
- ez.s_lxfrac = FALSE;
- ez.s_lyfrac = FALSE;
- ez.s_xlegend = FALSE;
- ez.s_ylegend = FALSE;
- ez.s_textsize = FALSE;
-
- ez.d_usecrt = TRUE;
- ez.d_useprt = FALSE;
- ez.d_crtmode = DEF_CRTMODE;
- ez.d_prtmode = PRTMODE_DEF;
- ez.d_xprtbuf = XBUF_DEF;
- ez.d_yprtbuf = YBUF_DEF;
-
- ez.clr_axis = C_WHITE; /* set fixed colors */
- ez.clr_title = (C_CYAN+8);
- ez.clr_label = (C_CYAN+8);
- ez.clr_legend = (C_RED+8);
- ez.clr_number = (C_GREEN+8);
- ez.clr_grid = (C_BLACK+8);
-}
+ if (fabs(logt) >= 6) { /* use exponential format */
+ if (fabs(logt) > 99)
+ expon = 5; /* E+102 */
+ else
+ expon = 4; /* E+00 */
+
+ if (*nfrac < 0) { /* calculate frac */
+ delta /= pow (10., floor(logt)); /* scale delta */
+ frac = static_cast<int>(fabs(trunc(log10(delta)))) + 1;
+ if (frac < 1)
+ frac = 1; /* to be safe, add decimal pt */
+ } else /* use users' frac */
+ frac = *nfrac;
+
+ wid = 2 + frac + expon;
+ if (minval < 0. || maxval < 0.)
+ ++wid;
+ sprintf (fmtstr, "%s%d%s%d%s", "%", wid, ".", frac, "g");
+ } else { /* use fixed format */
+ wid = static_cast<int>(trunc(logt)) + 1;
+ if (wid < 1)
+ wid = 1;
+ if (minval < 0. || maxval < 0.)
+ ++wid;
+
+ if (*nfrac < 0) { /* calculate frac */
+ if (delta >= 0.999999)
+ frac = 1; /* add a decimal pt to be safe */
+ else
+ frac = static_cast<int>(fabs(trunc(log10(delta)))) + 1;
+ } else /* use users' frac */
+ frac = *nfrac;
+
+ wid += 1 + frac;
+ sprintf (fmtstr, "%s%d%s%d%s", "%", wid, ".", frac, "f");
+ }
-void ezfree(void)
-{
- for (int i = 0; i < ez.i_numcurves; i++) {
- delete ez.curve[i].x;
- delete ez.curve[i].y;
- }
- ez.i_numcurves = 0;
+ *fldwid = wid;
+ *nfrac = frac;
}
-void ezclear(void)
-{
- ezfree();
- ezinit();
-}
/*****************************************************************************
-** FILE IDENTIFICATION
-**
-** EZSET - Parameter control for EZPLOT
-**
-** This is part of the CTSim program
-** Copyright (C) 1983-2000 Kevin Rosenberg
-**
-** $Id: ezset.cpp,v 1.4 2000/07/13 07:03:21 kevin Exp $
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License (version 2) as
-** published by the Free Software Foundation.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-******************************************************************************/
-/*----------------------------------------------------------------------*/
-/* */
-/*----------------------------------------------------------------------*/
+ ** FILE IDENTIFICATION
+ **
+ ** EZSET - Parameter control for EZPLOT
+ **
+ ** This is part of the CTSim program
+ ** Copyright (C) 1983-2000 Kevin Rosenberg
+ **
+ ** $Id: ezset.cpp,v 1.5 2000/07/28 08:28:08 kevin Exp $
+ **
+ ** This program is free software; you can redistribute it and/or modify
+ ** it under the terms of the GNU General Public License (version 2) as
+ ** published by the Free Software Foundation.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU General Public License for more details.
+ **
+ ** You should have received a copy of the GNU General Public License
+ ** along with this program; if not, write to the Free Software
+ ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ******************************************************************************/
#include "ctsupport.h"
#include "ezplot.h"
#include "pol.h"
-static int ezcmd (char *comm);
-static int do_cmd(int lx);
-static void do_data(void);
-static void do_help(void);
-static void bad_option(char *opt);
-static void initkw(void);
-
-static int modeinteract = FALSE;
-static int curveinteract = -1;
-static int ezset_firstcall = TRUE;
+bool EZPlot::ezset_initialized = false;
int
-ezset (char *command)
+EZPlot::ezset (char *command)
{
- if (ezplot_firstcall == TRUE) {
- ezinit ();
- }
- if (ezset_firstcall == TRUE) {
- pol_init();
- initkw();
- pol_skpword ("please");
- pol_skpword ("use");
- pol_skpword ("are");
- pol_skpword ("and");
- pol_skpword ("is");
- pol_skpword ("the");
- pol_skpword ("equals");
- pol_skpchar ("=");
- ezset_firstcall = FALSE;
-
- pol_usefile (P_USE_STR,"");
- set_inputline ("!eoc ,");
- pol_reader ();
- pol_closefile ();
- }
- return (ezcmd (command));
+ if (! ezset_initialized) {
+ pol_init();
+ initkw();
+ pol_skpword ("please");
+ pol_skpword ("use");
+ pol_skpword ("are");
+ pol_skpword ("and");
+ pol_skpword ("is");
+ pol_skpword ("the");
+ pol_skpword ("equals");
+ pol_skpchar ("=");
+
+ pol_usefile (P_USE_STR,"");
+ set_inputline ("!eoc ,");
+ pol_reader ();
+ pol_closefile ();
+ ezset_initialized = true;
+ }
+ return (ezcmd (command));
}
-static int
-ezcmd (char *comm)
+bool
+EZPlot::ezcmd (char *comm)
{
- char str[MAXTOK+1];
- int code, retval;
-
- retval = TRUE;
- pol_usefile (P_USE_STR, "");
- set_inputline (comm);
-
- if (pol_usertok (str, &code) == FALSE) {
- fputs("Illegal EZSET command\n", stderr);
- pol_reader();
- retval = FALSE;
- goto ezexit;
- }
-
- if (code != S_INTERACTIVE) {
- retval = do_cmd (code);
- } else {
- modeinteract = TRUE;
- pol_reader();
- do {
- fputs ("Enter EZSET command, DATA, EXIT, or HELP\n>", stderr);
- if (get_inputline (stdin) != TRUE)
- goto ezexit;
- while (pol_lookchar() != EOF) {
- if (pol_usertok (str, &code) == FALSE) {
- if (pol_lookchar() != EOF) {
- fputs ("illegal EZSET command\n", stderr);
- pol_reader();
- }
- } else if (code == S_DATA) {
- pol_reader ();
- do_data ();
- } else if (code == S_HELP) {
- pol_reader();
- do_help ();
- } else if (code == S_EXIT) {
- pol_reader();
- goto ezexit;
- } else
- do_cmd (code);
- }
- putc (NEWLINE, stderr);
- } while (TRUE);
- modeinteract = FALSE;
- curveinteract = -1;
- }
-ezexit:
- pol_closefile(); /* close input string file */
- return (retval);
+ pol_usefile (P_USE_STR, "");
+ set_inputline (comm);
+
+ char str[MAXTOK+1];
+ int code;
+ bool retval = true;
+ if (! pol_usertok (str, &code)) {
+ cerr << "Illegal EZSET command: " << str << endl;
+ pol_reader();
+ retval = false;
+ }
+ else
+ retval = do_cmd (code);
+
+ pol_closefile(); /* close input string file */
+ return (retval);
}
-static int
-do_cmd (int lx)
+int
+EZPlot::do_cmd (int lx)
{
- char str [MAXTOK+1];
- int n;
- double f;
-
- switch (lx) {
- case S_CRT:
- if (pol_word("no", 2) == TRUE)
- ez.d_usecrt = FALSE;
- else {
- ez.d_usecrt = TRUE;
- }
- break;
- case S_EPSON:
- if (pol_word("no", 2) == TRUE)
- ez.d_useprt = FALSE;
- else
- ez.d_useprt = TRUE;
- break;
- case S_TEXTSIZE:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- {
- if (f >= 0.0 && f <= 1.0) {
- ez.v_textsize = f;
- ez.s_textsize = TRUE;
- } else
- ez.s_textsize = FALSE;
- }
- break;
- case S_PRTMODE:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- {
- if (n >= 0 && n <= 6)
- ez.d_prtmode = n;
- else
- ez.d_prtmode = PRTMODE_DEF;
- }
- break;
- case S_XBUF:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- {
- if (n > 2 && n <= 960)
- ez.d_xprtbuf = n;
- else
- ez.d_xprtbuf = XBUF_DEF;
- }
- break;
- case S_YBUF:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- {
- if (n > 2 && n <= 960)
- ez.d_yprtbuf = n;
- else
- ez.d_yprtbuf = YBUF_DEF;
- }
- break;
- case S_REPLOT:
- ez.i_plotimmediate = TRUE;
- ezplot (static_cast<double*>(NULL), static_cast<double*>(NULL), 0);
-#if 0
- if (modeinteract == TRUE)
- WAITKEY();
-#endif
- ez.i_plotimmediate = FALSE;
- break;
- case S_CLEAR:
- ezclear ();
- break;
- case S_TITLE:
- gettext (ez.c_title, MAXTITLE);
- break;
- case S_LEGEND:
- gettext (ez.c_legend, MAXLEGEND);
- if (modeinteract == TRUE && curveinteract >= 0)
- strncpy (ez.curve[curveinteract].legend, ez.c_legend, MAXLEGEND);
- break;
- case S_XLABEL:
- gettext (ez.c_xlabel, MAXLABEL);
- break;
- case S_YLABEL:
- gettext (ez.c_ylabel, MAXLABEL);
- break;
- case S_XCROSS:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
- ez.v_xcross = f;
- ez.s_xcross = TRUE;
- } else
- ez.s_xcross = FALSE;
- break;
- case S_YCROSS:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
- ez.v_ycross = f;
- ez.s_ycross = TRUE;
- } else
- ez.s_ycross = FALSE;
- break;
- case S_NOXAXIS:
- ez.o_xaxis = NOAXIS;
- break;
- case S_NOYAXIS:
- ez.o_yaxis = NOAXIS;
- break;
- case S_XLIN:
- ez.o_xaxis = LINEAR;
- break;
- case S_YLIN:
- ez.o_yaxis = LINEAR;
- break;
- case S_XLOG:
- ez.o_xaxis = LOG;
- break;
- case S_YLOG:
- ez.o_yaxis = LOG;
- break;
- case S_XAUTOSCALE:
- ez.s_xmin = FALSE;
- ez.s_xmax = FALSE;
- break;
- case S_YAUTOSCALE:
- ez.s_ymin = FALSE;
- ez.s_ymax = FALSE;
- break;
- case S_XMIN:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
- ez.v_xmin = f;
- ez.s_xmin = TRUE;
- }
- break;
- case S_XMAX:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
- ez.v_xmax = f;
- ez.s_xmax = TRUE;
- }
- break;
- case S_YMIN:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
- ez.v_ymin = f;
- ez.s_ymin = TRUE;
- }
- break;
- case S_YMAX:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
- ez.v_ymax = f;
- ez.s_ymax = TRUE;
- }
- break;
- case S_SOLID:
- ez.o_linestyle = LS_SOLID;
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].linestyle = LS_SOLID;
- break;
- case S_DASH:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
- if (n == 1)
- ez.o_linestyle = LS_DASH1;
- else if (n == 2)
- ez.o_linestyle = LS_DASH2;
- else if (n == 3)
- ez.o_linestyle = LS_DASH3;
- else if (n == 4)
- ez.o_linestyle = LS_DASH4;
- else
- ez.o_linestyle = LS_DASH1;
- } else
- ez.o_linestyle = LS_DASH1;
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].linestyle = ez.o_linestyle;
- break;
- case S_NOLINE:
- ez.o_linestyle = LS_NOLINE;
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].linestyle = LS_NOLINE;
- break;
- case S_PEN:
- case S_COLOR:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- {
- if (n >= 0 && n <= MAXCOLOR)
- ez.o_color = n;
- else
- bad_option("The color you picked");
- }
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].color = ez.o_color;
- break;
- case S_BOX:
- ez.o_box = TRUE;
- break;
- case S_NOBOX:
- ez.o_box = FALSE;
- break;
- case S_GRID:
- ez.o_grid = TRUE;
- break;
- case S_NOGRID:
- ez.o_grid = FALSE;
- break;
- case S_XLENGTH:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- if (f > 0.0 && f <= 1.0)
- ez.o_xlength = f;
- break;
- case S_YLENGTH:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- if (f > 0.0 && f <= 1.0)
- ez.o_ylength = f;
- break;
- case S_XPORIGIN:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- if (f >= 0.0 && f < 1.0)
- ez.o_xporigin = f;
- break;
- case S_YPORIGIN:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- if (f >= 0.0 && f < 1.0)
- ez.o_yporigin = f;
- break;
- case S_TAG:
- if (pol_word("no", 2) == TRUE)
- ez.o_tag = FALSE;
- else if (pol_word("off", 2) == TRUE)
- ez.o_tag = FALSE;
- else
- ez.o_tag = TRUE;
- break;
- case S_LEGENDBOX:
- if (pol_word("inside", 2) == TRUE)
- ez.o_legendbox = INSIDE;
- else if (pol_word("outside", 3) == TRUE)
- ez.o_legendbox = OUTSIDE;
- else if (pol_word("none",2) == TRUE)
- ez.o_legendbox = NOLEGEND;
- else {
- gettext (str, MAXTOK);
- bad_option(str);
- }
- break;
- case S_XLEGEND:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- {
- if (f >= 0.0 && f < 1.0) {
- ez.v_xlegend = f;
- ez.s_xlegend = TRUE;
- }
- else
- ez.s_xlegend = FALSE;
- }
- break;
- case S_YLEGEND:
- if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
- {
- if (f >= 0.0 && f < 1.0) {
- ez.v_ylegend = f;
- ez.s_ylegend = TRUE;
- }
- else
- ez.s_ylegend = FALSE;
- }
- break;
- case S_CURVES:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
- if (n < 1)
- n = 1;
- else if (n > MAXCURVES)
- n = MAXCURVES;
- if (modeinteract == TRUE) {
- curveinteract = n - 1;
- if (ez.o_unknowncurves == FALSE && ez.o_reqcurves < n)
- ez.o_reqcurves = n;
- } else {
- ezfree ();
- ez.o_reqcurves = n;
- }
- } else {
- if (pol_word ("unknown", 7) == TRUE)
- ez.o_unknowncurves = TRUE;
- else if (pol_word ("end", 3) == TRUE) {
- ez.o_unknowncurves = FALSE;
- ez.o_reqcurves = ez.i_numcurves;
- ez.i_plotimmediate = TRUE;
- ezplot (static_cast<double*>(NULL), static_cast<double*>(NULL), 0);
- ez.i_plotimmediate = FALSE;
- }
- }
- break;
- case S_SYMBOL:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
- if (n > 0 && n <= MAXSYMBOL)
- ez.o_symbol = n;
- else
- ez.o_symbol = 1;
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].symbol = ez.o_symbol;
- } else {
- if (pol_word("every",5) == TRUE) {
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
- if (n > 0)
- ez.o_symfreq = n;
- else
- ez.o_symfreq = 1;
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].symfreq = ez.o_symfreq;
- }
- } else if (pol_word ("none",4) == TRUE) {
- ez.o_symbol = -1;
- if (modeinteract == TRUE && curveinteract >= 0)
- ez.curve[curveinteract].symbol = ez.o_symbol;
- }
- }
- break;
- case S_XTICKS:
- if (pol_usertok(str,&lx) == FALSE)
- break;
- if (lx == S_ABOVE)
- ez.o_xticks = ABOVE;
- else if (lx == S_BELOW)
- ez.o_xticks = BELOW;
- else if (lx == S_NOLABEL)
- ez.o_xtlabel = FALSE;
- else if (lx == S_LABEL)
- ez.o_xtlabel = TRUE;
- else if (lx == S_MAJOR) {
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- if (n > 1 && n < 100)
- ez.o_xmajortick = n;
- } else if (lx == S_MINOR)
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- if (n >= 0 && n < 100)
- ez.o_xminortick = n;
- break;
- case S_YTICKS:
- if (pol_usertok(str,&lx) == FALSE)
- break;
- if (lx == S_RIGHT)
- ez.o_yticks = RIGHT;
- else if (lx == S_LEFT)
- ez.o_yticks = LEFT;
- else if (lx == S_NOLABEL)
- ez.o_ytlabel = FALSE;
- else if (lx == S_LABEL)
- ez.o_ytlabel = TRUE;
- else if (lx == S_MAJOR) {
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- if (n > 1 && n < 100)
- ez.o_ymajortick = n;
- } else if (lx == S_MINOR)
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
- if (n >= 0 && n < 100)
- ez.o_yminortick = n;
- break;
- case S_LXFRAC:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
- if (n >= 0) {
- ez.v_lxfrac = n;
- ez.s_lxfrac = TRUE;
- }
- } else
- ez.s_lxfrac = FALSE;
- break;
- case S_LYFRAC:
- if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
- if (n >= 0) {
- ez.v_lyfrac = n;
- ez.s_lyfrac = TRUE;
- }
- } else
- ez.s_lyfrac = FALSE;
- break;
- case S_USTART:
- if (pol_word("no", 2) == TRUE)
- ez.o_ustart = FALSE;
- else
- ez.o_ustart = TRUE;
- break;
- case S_UFINISH:
- if (pol_word("no", 2) == TRUE)
- ez.o_ufinish = FALSE;
- else
- ez.o_ufinish = TRUE;
- break;
- default:
- fprintf (stderr, "Unimplemented EZPLOT command\n");
- break;
+ char str [1024];
+ char strIn [1024];
+ int n;
+ double f;
+
+ switch (lx) {
+ case S_TEXTSIZE:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ {
+ if (f >= 0.0 && f <= 1.0) {
+ v_textsize = f;
+ s_textsize = TRUE;
+ } else
+ s_textsize = FALSE;
+ }
+ break;
+ case S_REPLOT:
+ plot ();
+ break;
+ case S_CLEAR:
+ clearCurves ();
+ break;
+ case S_TITLE:
+ gettext (strIn, sizeof(strIn));
+ c_title = strIn;
+ break;
+ case S_LEGEND:
+ gettext (strIn, sizeof(strIn));
+ c_legend = strIn;
+ break;
+ case S_XLABEL:
+ gettext (strIn, sizeof(strIn));
+ c_xlabel = strIn;
+ break;
+ case S_YLABEL:
+ gettext (strIn, sizeof(strIn));
+ c_ylabel = strIn;
+ break;
+ case S_XCROSS:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
+ v_xcross = f;
+ s_xcross = TRUE;
+ } else
+ s_xcross = FALSE;
+ break;
+ case S_YCROSS:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
+ v_ycross = f;
+ s_ycross = TRUE;
+ } else
+ s_ycross = FALSE;
+ break;
+ case S_NOXAXIS:
+ o_xaxis = NOAXIS;
+ break;
+ case S_NOYAXIS:
+ o_yaxis = NOAXIS;
+ break;
+ case S_XLIN:
+ o_xaxis = LINEAR;
+ break;
+ case S_YLIN:
+ o_yaxis = LINEAR;
+ break;
+ case S_XLOG:
+ o_xaxis = LOG;
+ break;
+ case S_YLOG:
+ o_yaxis = LOG;
+ break;
+ case S_XAUTOSCALE:
+ s_xmin = FALSE;
+ s_xmax = FALSE;
+ break;
+ case S_YAUTOSCALE:
+ s_ymin = FALSE;
+ s_ymax = FALSE;
+ break;
+ case S_XMIN:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
+ v_xmin = f;
+ s_xmin = TRUE;
+ }
+ break;
+ case S_XMAX:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
+ v_xmax = f;
+ s_xmax = TRUE;
+ }
+ break;
+ case S_YMIN:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
+ v_ymin = f;
+ s_ymin = TRUE;
+ }
+ break;
+ case S_YMAX:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE) {
+ v_ymax = f;
+ s_ymax = TRUE;
+ }
+ break;
+ case S_SOLID:
+ o_linestyle = SGP::LS_SOLID;
+ break;
+ case S_DASH:
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
+ if (n == 1)
+ o_linestyle = SGP::LS_DASH1;
+ else if (n == 2)
+ o_linestyle = SGP::LS_DASH2;
+ else if (n == 3)
+ o_linestyle = SGP::LS_DASH3;
+ else if (n == 4)
+ o_linestyle = SGP::LS_DASH4;
+ else
+ o_linestyle = SGP::LS_DASH1;
+ } else
+ o_linestyle = SGP::LS_DASH1;
+ break;
+ case S_NOLINE:
+ o_linestyle = SGP::LS_NOLINE;
+ break;
+ case S_PEN:
+ case S_COLOR:
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
+ {
+ if (n >= 0)
+ o_color = n;
+ else
+ bad_option("The color you picked");
+ }
+ break;
+ case S_BOX:
+ o_box = TRUE;
+ break;
+ case S_NOBOX:
+ o_box = FALSE;
+ break;
+ case S_GRID:
+ o_grid = TRUE;
+ break;
+ case S_NOGRID:
+ o_grid = FALSE;
+ break;
+ case S_XLENGTH:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ if (f > 0.0 && f <= 1.0)
+ o_xlength = f;
+ break;
+ case S_YLENGTH:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ if (f > 0.0 && f <= 1.0)
+ o_ylength = f;
+ break;
+ case S_XPORIGIN:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ if (f >= 0.0 && f < 1.0)
+ o_xporigin = f;
+ break;
+ case S_YPORIGIN:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ if (f >= 0.0 && f < 1.0)
+ o_yporigin = f;
+ break;
+ case S_TAG:
+ if (pol_word("no", 2) == TRUE)
+ o_tag = FALSE;
+ else if (pol_word("off", 2) == TRUE)
+ o_tag = FALSE;
+ else
+ o_tag = TRUE;
+ break;
+ case S_LEGENDBOX:
+ if (pol_word("inside", 2) == TRUE)
+ o_legendbox = INSIDE;
+ else if (pol_word("outside", 3) == TRUE)
+ o_legendbox = OUTSIDE;
+ else if (pol_word("none",2) == TRUE)
+ o_legendbox = NOLEGEND;
+ else {
+ gettext (str, MAXTOK);
+ bad_option(str);
+ }
+ break;
+ case S_XLEGEND:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ {
+ if (f >= 0.0 && f < 1.0) {
+ v_xlegend = f;
+ s_xlegend = TRUE;
}
-
- pol_reader ();
- return (TRUE);
-}
-
-static void do_data (void)
-{
- double x[MAXPTS], y[MAXPTS], d;
- int c, i;
-
- printf ("Enter your data in free format\n");
- printf ("Alternate X and Y coordinates\n");
- printf ("Type ^Z (control Z) to terminate data entry\n");
-
- pol_usefile (P_USE_FILE, "");
- for (i = 0; i < MAXPTS; i++) {
- if (pol_float (&d, TT_REAL, FALSE, 0, 0) == TRUE)
- x[i] = d;
- else
- break;
- if (pol_float (&d, TT_REAL, FALSE, 0, 0) == TRUE)
- y[i] = d;
- else
- break;
+ else
+ s_xlegend = FALSE;
+ }
+ break;
+ case S_YLEGEND:
+ if (pol_float (&f, TT_REAL, FALSE, 0.0, 0.0) == TRUE)
+ {
+ if (f >= 0.0 && f < 1.0) {
+ v_ylegend = f;
+ s_ylegend = TRUE;
}
-
- if ((c = pol_inchar()) != EOF) {
- ungetc (c, stdin);
- printf("Error reading in points, read char %d, plotting %d points\n", c, i);
+ else
+ s_ylegend = FALSE;
+ }
+ break;
+ case S_CURVES:
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
+ if (n < 1)
+ n = 1;
+ // if (modeinteract == TRUE) {
+ // curveinteract = n - 1;
+ // if (o_unknowncurves == FALSE && o_reqcurves < n)
+ // o_reqcurves = n;
+ // } else {
+ // clearCurve ();
+ // o_reqcurves = n;
+ // }
+ } else {
+ if (pol_word ("unknown", 7) == TRUE)
+ o_unknowncurves = TRUE;
+ else if (pol_word ("end", 3) == TRUE) {
+ // o_unknowncurves = FALSE;
+ // o_reqcurves = i_numcurves;
+ // i_plotimmediate = TRUE;
+ // ezplot (static_cast<double*>(NULL), static_cast<double*>(NULL), 0);
+ // i_plotimmediate = FALSE;
+ }
+ }
+ break;
+ case S_SYMBOL:
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
+ if (n > 0 && n <= MAXSYMBOL)
+ o_symbol = n;
+ else
+ o_symbol = 1;
+ // if (modeinteract == TRUE && curveinteract >= 0)
+ // curve[curveinteract].symbol = o_symbol;
+ } else {
+ if (pol_word("every",5) == TRUE) {
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
+ if (n > 0)
+ o_symfreq = n;
+ else
+ o_symfreq = 1;
+ // if (modeinteract == TRUE && curveinteract >= 0)
+ // curve[curveinteract].symfreq = o_symfreq;
}
- if (i > 0)
- ezplot (x, y, i);
- pol_closefile ();
+ } else if (pol_word ("none",4) == TRUE) {
+ o_symbol = -1;
+ // if (modeinteract == TRUE && curveinteract >= 0)
+ // curve[curveinteract].symbol = o_symbol;
+ }
+ }
+ break;
+ case S_XTICKS:
+ if (pol_usertok(str,&lx) == FALSE)
+ break;
+ if (lx == S_ABOVE)
+ o_xticks = ABOVE;
+ else if (lx == S_BELOW)
+ o_xticks = BELOW;
+ else if (lx == S_NOLABEL)
+ o_xtlabel = FALSE;
+ else if (lx == S_LABEL)
+ o_xtlabel = TRUE;
+ else if (lx == S_MAJOR) {
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
+ if (n > 1 && n < 100)
+ o_xmajortick = n;
+ } else if (lx == S_MINOR)
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
+ if (n >= 0 && n < 100)
+ o_xminortick = n;
+ break;
+ case S_YTICKS:
+ if (pol_usertok(str,&lx) == FALSE)
+ break;
+ if (lx == S_RIGHT)
+ o_yticks = RIGHT;
+ else if (lx == S_LEFT)
+ o_yticks = LEFT;
+ else if (lx == S_NOLABEL)
+ o_ytlabel = FALSE;
+ else if (lx == S_LABEL)
+ o_ytlabel = TRUE;
+ else if (lx == S_MAJOR) {
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
+ if (n > 1 && n < 100)
+ o_ymajortick = n;
+ } else if (lx == S_MINOR)
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE)
+ if (n >= 0 && n < 100)
+ o_yminortick = n;
+ break;
+ case S_LXFRAC:
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
+ if (n >= 0) {
+ v_lxfrac = n;
+ s_lxfrac = TRUE;
+ }
+ } else
+ s_lxfrac = FALSE;
+ break;
+ case S_LYFRAC:
+ if (pol_integer (&n, TT_REAL, FALSE, 0, 0) == TRUE) {
+ if (n >= 0) {
+ v_lyfrac = n;
+ s_lyfrac = TRUE;
+ }
+ } else
+ s_lyfrac = FALSE;
+ break;
+ break;
+ default:
+ fprintf (stderr, "Unimplemented EZPLOT command\n");
+ break;
+ }
+
+ pol_reader ();
+ return (TRUE);
}
-static void do_help (void )
-{
- fputs ("EZSET Help: not available\n", stderr);
-}
-
-static void
-bad_option (char *opt)
+void
+EZPlot::bad_option (char *opt)
{
- fprintf(stderr,"%s is an INVALID option (sorry!)\n", opt);
+ cerr << opt << " is an INVALID option\n";
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
static struct key {
- char *keyword;
- int code;
+ char *keyword;
+ int code;
} keytab[] = {
- {"solid", S_SOLID},
- {"dash", S_DASH},
- {"noline", S_NOLINE},
+ {"solid", S_SOLID},
+ {"dash", S_DASH},
+ {"noline", S_NOLINE},
{"black", S_BLACK},
- {"red", S_RED},
- {"blue", S_BLUE},
- {"green", S_GREEN},
- {"pen", S_PEN},
- {"symbol", S_SYMBOL},
-/* "every", S_EVERY, */
-/* "none", S_NONE, */
-
- {"curves", S_CURVES},
- {"curve", S_CURVES},
-/* "unknown", S_UNKNOWN, */
-/* "end", S_END, */
-
- {"legend", S_LEGEND},
- {"xlegend", S_XLEGEND},
- {"ylegend", S_YLEGEND},
-
- {"xlin", S_XLIN},
- {"ylin", S_YLIN},
- {"xlog", S_XLOG},
- {"ylog", S_YLOG},
- {"xlabel", S_XLABEL},
- {"ylabel", S_YLABEL},
- {"xlength", S_XLENGTH},
- {"ylength", S_YLENGTH},
-
- {"xticks", S_XTICKS},
- {"yticks", S_YTICKS},
- {"above", S_ABOVE},
- {"label", S_LABEL},
- {"below", S_BELOW},
- {"nolabel", S_NOLABEL},
- {"right", S_RIGHT},
- {"left", S_LEFT},
-
- {"xautoscale", S_XAUTOSCALE},
- {"yautoscale", S_YAUTOSCALE},
- {"xmin", S_XMIN},
- {"ymin", S_YMIN},
- {"xmax", S_XMAX},
- {"ymax", S_YMAX},
- {"lxfrac", S_LXFRAC},
- {"lyfrac", S_LYFRAC},
- {"xcross", S_XCROSS},
- {"ycross", S_YCROSS},
- {"noxaxis", S_NOXAXIS},
- {"noyaxis", S_NOYAXIS},
- {"xporigin", S_XPORIGIN},
- {"yporigin", S_YPORIGIN},
- {"title", S_TITLE},
- {"xtitle", S_XTITLE},
- {"ytitle", S_YTITLE},
-
- {"replot", S_REPLOT},
- {"clear", S_CLEAR},
- {"store", S_STORE},
- {"restore", S_RESTORE},
- {"ustart", S_USTART},
- {"ufinish", S_UFINISH},
- {"amark", S_AMARK},
- {"interactive", S_INTERACTIVE},
- {"units", S_UNITS},
- {"inches", S_INCHES},
- {"user", S_USER},
-
- {"data", S_DATA},
- {"help", S_HELP},
- {"exit", S_EXIT},
-
- {"box", S_BOX},
- {"nobox", S_NOBOX},
- {"grid", S_GRID},
- {"nogrid", S_NOGRID},
- {"major", S_MAJOR},
- {"minor", S_MINOR},
- {"color", S_COLOR},
- {"legendbox", S_LEGENDBOX},
-
- {"epson", S_EPSON},
- {"crt", S_CRT},
- {"no", S_NO},
-
- {"textsize", S_TEXTSIZE},
- {"xbuf", S_XBUF},
- {"ybuf", S_YBUF},
- // {"prtmode", S_PRTMOD},
-};
+ {"red", S_RED},
+ {"blue", S_BLUE},
+ {"green", S_GREEN},
+ {"pen", S_PEN},
+ {"symbol", S_SYMBOL},
+ /* "every", S_EVERY, */
+ /* "none", S_NONE, */
+
+ {"curves", S_CURVES},
+ {"curve", S_CURVES},
+ /* "unknown", S_UNKNOWN, */
+ /* "end", S_END, */
+
+ {"legend", S_LEGEND},
+ {"xlegend", S_XLEGEND},
+ {"ylegend", S_YLEGEND},
+
+ {"xlin", S_XLIN},
+ {"ylin", S_YLIN},
+ {"xlog", S_XLOG},
+ {"ylog", S_YLOG},
+ {"xlabel", S_XLABEL},
+ {"ylabel", S_YLABEL},
+ {"xlength", S_XLENGTH},
+ {"ylength", S_YLENGTH},
+
+ {"xticks", S_XTICKS},
+ {"yticks", S_YTICKS},
+ {"above", S_ABOVE},
+ {"label", S_LABEL},
+ {"below", S_BELOW},
+ {"nolabel", S_NOLABEL},
+ {"right", S_RIGHT},
+ {"left", S_LEFT},
+
+ {"xautoscale", S_XAUTOSCALE},
+ {"yautoscale", S_YAUTOSCALE},
+ {"xmin", S_XMIN},
+ {"ymin", S_YMIN},
+ {"xmax", S_XMAX},
+ {"ymax", S_YMAX},
+ {"lxfrac", S_LXFRAC},
+ {"lyfrac", S_LYFRAC},
+ {"xcross", S_XCROSS},
+ {"ycross", S_YCROSS},
+ {"noxaxis", S_NOXAXIS},
+ {"noyaxis", S_NOYAXIS},
+ {"xporigin", S_XPORIGIN},
+ {"yporigin", S_YPORIGIN},
+ {"title", S_TITLE},
+ {"xtitle", S_XTITLE},
+ {"ytitle", S_YTITLE},
+
+ {"replot", S_REPLOT},
+ {"clear", S_CLEAR},
+ {"store", S_STORE},
+ {"restore", S_RESTORE},
+ {"amark", S_AMARK},
+ {"interactive", S_INTERACTIVE},
+ {"units", S_UNITS},
+ {"inches", S_INCHES},
+ {"user", S_USER},
+
+ {"data", S_DATA},
+ {"help", S_HELP},
+ {"exit", S_EXIT},
+
+ {"box", S_BOX},
+ {"nobox", S_NOBOX},
+ {"grid", S_GRID},
+ {"nogrid", S_NOGRID},
+ {"major", S_MAJOR},
+ {"minor", S_MINOR},
+ {"color", S_COLOR},
+ {"legendbox", S_LEGENDBOX},
+
+ {"no", S_NO},
+
+ {"textsize", S_TEXTSIZE},
+ };
static const unsigned int NKEYS=(sizeof(keytab) / sizeof(struct key));
-static void initkw(void)
+void
+EZPlot::initkw(void)
{
for (unsigned int i = 0; i < NKEYS; i++)
if (pol_install(keytab[i].keyword, keytab[i].code) == FALSE)
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ezsupport.cpp,v 1.4 2000/07/13 07:03:21 kevin Exp $
+** $Id: ezsupport.cpp,v 1.5 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#include "ezplot.h"
-/* NAME
- * axis_scale calculates graph axis scaling
- *
- * SYNOPSIS:
- * retval = axis_scale (min, max, nint, minp, maxp, nintp,
- * rec_total, rec_frac)
- *
- * INPUT:
- * double min Smallest value to plot
- * double max Largest value to plot
- * int nint Number of intervals desired
- *
- * OUTPUT:
- * int retval FALSE if illegal parameters, else TRUE
- * double *minp Minimum graph value
- * double *maxp Maximum graph value
- * int *nintp Number of intervals for graph
- * int *rec_total Recommended field width for printing out the number
- * int *rec_frac Recommended number of digits for print fraction
- */
-
-int
-axis_scale (double min, double max, int nint, double *minp, double *maxp, int *nintp)
-{
- double eps, a, scale, mina, maxa, d, j, e, f, v, wdt, g, h;
-
- if (min >= max || nint < 1) {
- sys_error (ERR_WARNING, "Invalid params: min=%lf, min=%lf, num intervals=%d [axis_scale]", min, max, nint);
- return (FALSE);
- }
-
- eps = 0.025;
- a = fabs(min);
- if (fabs(min) < fabs(max))
- a = fabs(max);
- scale = pow (10.0, floor(log10(a)));
- loop:
- mina = min / scale;
- maxa = max / scale;
- d = (maxa - mina) / nint;
- j = d * eps;
- e = floor (log10(d));
- f = d / pow (10.0, e);
- v = 10.0;
- if (f < sqrt(2.0))
- v = 1.0;
- else if (f < sqrt (10.0))
- v = 2.0;
- else if (f < sqrt (50.0))
- v = 5.0;
- wdt = v * pow (10.0, e);
- g = floor (mina / wdt);
- if (fabs(g + 1 - mina / wdt) < j)
- g = g + 1;
- *minp = wdt * g;
- h = floor (maxa / wdt) + 1.0;
- if (fabs(maxa / wdt + 1 - h) < j)
- h = h - 1;
- *maxp = wdt * h;
- *nintp = static_cast<int>(h - g);
- if (fabs(*maxp) >= 10.0 || fabs(*minp) >= 10.0) {
- scale = scale * 10.0;
- goto loop;
- }
-
- *minp *= scale;
- *maxp *= scale;
-
- return (TRUE);
-}
-
-
-/* NAME
- * make_numfmt Make a numeric format string
- *
- * SYNOPSIS
- * make_numfmt (fmtstr, fldwid, nfrac, min, max, nint)
- * char *fmtstr Returned format string for printf()
- * int *fldwid Returned field width
- * int *nfrac If < 0, then calculate best number of
- * fraction places & return that value
- * If >= 0, then use that number of places
- * double min Minimum value
- * double max Maximum value
- * int nint Number of intervals between min & max
- *
- * DESCRIPTION
- * This routine is written as an INTERNAL routine for EZPLOT
- */
-
-static inline double
-trunc (double x)
-{
- double integer;
-
- modf (x, &integer);
-
- return (integer);
-}
-
-void
-make_numfmt (char *fmtstr, int *fldwid, int *nfrac, double minval, double maxval, int nint)
-{
- int wid, frac, expon;
-
- double delta = (maxval - minval) / nint;
- double absmin = fabs(minval);
- double absmax = fabs(maxval);
- double logt = log10( max(absmin, absmax) );
-
- if (fabs(logt) >= 6) { /* use exponential format */
- if (fabs(logt) > 99)
- expon = 5; /* E+102 */
- else
- expon = 4; /* E+00 */
-
- if (*nfrac < 0) { /* calculate frac */
- delta /= pow (10., floor(logt)); /* scale delta */
- frac = static_cast<int>(fabs(trunc(log10(delta)))) + 1;
- if (frac < 1)
- frac = 1; /* to be safe, add decimal pt */
- } else /* use users' frac */
- frac = *nfrac;
-
- wid = 2 + frac + expon;
- if (minval < 0. || maxval < 0.)
- ++wid;
- sprintf (fmtstr, "%s%d%s%d%s", "%", wid, ".", frac, "g");
- } else { /* use fixed format */
- wid = static_cast<int>(trunc(logt)) + 1;
- if (wid < 1)
- wid = 1;
- if (minval < 0. || maxval < 0.)
- ++wid;
-
- if (*nfrac < 0) { /* calculate frac */
- if (delta >= 0.999999)
- frac = 1; /* add a decimal pt to be safe */
- else
- frac = static_cast<int>(fabs(trunc(log10(delta)))) + 1;
- } else /* use users' frac */
- frac = *nfrac;
-
- wid += 1 + frac;
- sprintf (fmtstr, "%s%d%s%d%s", "%", wid, ".", frac, "f");
- }
-
- *fldwid = wid;
- *nfrac = frac;
-}
-
-#ifdef TEST
-int
-main (void)
-{
- double min, max;
- double x, xinc;
- int i, nint, wid, frac;
- char fmtstr[10];
-
- printf ("Enter min, max, & number of intervals -- ");
- scanf ("%lf %lf %d", &min, &max, &nint);
-
- frac = -1; /* let makefmt determine fraction */
-
- makefmt (fmtstr, &wid, &frac, min, max, nint);
-
- printf ("Format string = %s\n", fmtstr);
-
- xinc = (max - min) / nint;
-
- x = min;
- for (i = 0; i <= nint; i++) {
- printf (fmtstr, x);
- x += xinc;
- printf ("\n");
- }
-}
-#endif
-
-void
-ezplot_1d (double *y, int n)
-{
- double x [n];
-
- for (int i = 0; i < n; i++)
- x[i] = i;
-
- ezplot (x, y, n);
-}
/*****************************************************************************
** FILE IDENTIFICATION
**
-** Name: sgp.c Simple Graphics Package
+** Name: sgp.cpp Simple Graphics Package
** Programmer: Kevin Rosenberg
**
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: sgp.cpp,v 1.4 2000/07/11 10:32:44 kevin Exp $
+** $Id: sgp.cpp,v 1.5 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#include "sgp.h"
-static SGP_ID _sgp2_cwin = NULL;
-extern CHARSPEC cspec;
+#ifdef HAVE_WXWINDOWS
+SGPDriver::SGPDriver (wxDC* pDC, const char* szWinTitle = "", int xsize = 640, int ysize = 480)
+ : m_iPhysicalXSize(xsize), m_iPhysicalYSize(ysize), m_sWindowTitle(szWinTitle), m_idDriver(0)
+{
+ m_pDC = pDC;
+ m_idDriver |= SGPDRIVER_WXWINDOWS;
+}
+#endif
+SGPDriver::SGPDriver (const char* szWinTitle = "", int xsize = 640, int ysize = 480)
+ : m_iPhysicalXSize(xsize), m_iPhysicalYSize(ysize), m_sWindowTitle(szWinTitle), m_idDriver(0)
+{
+#ifdef HAVE_G2_H
+ m_idG2 = g2_open_X11X (m_iPhysicalXSize, m_iPhysicalYSize, 10, 10, const_cast<char*>(szWinTitle), const_cast<char*>(szWinTitle), NULL, -1, -1);
+ m_idDriver |= SGPDRIVER_G2;
+#endif
+}
-/* NAME
- * sgp2_init Initialize 2 graphics system
- *
- * SYNOPSIS
- * sgp2_init()
- */
+SGPDriver::~SGPDriver ()
+{
+ if (isG2())
+ g2_close (m_idG2);
+}
-SGP_ID
-sgp2_init (int xsize, int ysize, const char *win_title )
+
+// NAME
+// SGP::SGP Constructor for Simple Graphics Package
+
+SGP::SGP (const SGPDriver& driver)
+ : m_driver (driver)
{
- SGP_ID gid;
+ m_iPhysicalXSize = m_driver.getPhysicalXSize();
+ m_iPhysicalYSize = m_driver.getPhysicalYSize();
- gid = new SGP_WINDOW;
- _sgp2_cwin = gid;
-
- if (xsize <= 0)
- xsize = 640;
- if (ysize <= 0)
- ysize = 480;
-
- gid->pw_xsize = xsize;
- gid->pw_ysize = ysize;
- strncpy(gid->title, win_title, sizeof(gid->title));
-
- gid->recalc_mc_to_ndc = TRUE;
- gid->recalc_ndc_to_mc = TRUE;
- ident_gmtx_2 (gid->wc_to_ndc_x);
- ident_gmtx_2 (gid->mc_to_ndc_x);
- ident_gmtx_2 (gid->ndc_to_mc_x);
- ident_gmtx_2 (gid->ctm_2_x);
-
- sgp2_window (0., 0., 1., 1.);
- sgp2_viewport (0., 0., 1., 1.);
- ctm_clr_2 ();
- sgp2_move_abs (0., 0.);
-
-#if HAVE_G2_H
- gid->g2_id = g2_open_X11X (gid->pw_xsize, gid->pw_ysize, 10, 10, gid->title, gid->title, NULL, -1, -1);
-#endif
+ wc_to_ndc.setIdentity ();
+ mc_to_ndc.setIdentity();
+ ndc_to_mc.setIdentity();
+ m_ctm.setIdentity();
- _sgp2_init_dev (_sgp2_cwin);
-
- return (gid);
+ setWindow (0., 0., 1., 1.);
+ setViewport (0., 0., 1., 1.);
+ moveAbs (0., 0.);
+ m_iCurrentPhysicalX = 0;
+ m_iCurrentPhysicalY = 0;
+
+ setTextAngle (0.);
+ setTextSize (1. / 25.);
}
void
-sgp2_close (SGP_ID gid)
+SGP::stylusNDC (double x, double y, bool beam)
{
-#if HAVE_G2_H
- if (gid)
- g2_close (gid->g2_id);
-#endif
- if (gid == _sgp2_cwin)
- _sgp2_cwin = NULL;
-
- delete gid;
+ int xp = static_cast<int>(x * m_iPhysicalXSize + 0.5);
+ int yp = static_cast<int>(y * m_iPhysicalYSize + 0.5);
+ if (beam) {
+ if (m_driver.isWX())
+ m_driver.idWX()->DrawLine (m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp);
+ if (m_driver.isG2())
+ g2_line (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp);
+ }
+ m_iCurrentPhysicalX = xp;
+ m_iCurrentPhysicalY = yp;
}
void
-sgp2_set_active_win (SGP_ID gid)
+SGP::markerNDC (double x, double y)
{
- _sgp2_cwin = gid;
}
-SGP_ID
-sgp2_get_active_win (void)
+void
+SGP::pointNDC (double x, double y)
{
- return (_sgp2_cwin);
}
-/* NAME
- * sgp2_clear Clear window
- */
+// NAME
+// clear Clear Window
void
-sgp2_clear ()
+SGP::eraseWindow ()
{
-#if HAVE_G2
- if (_sgp_cwin != NULL)
- g2_clear (gid->g2_id);
-#endif
+ if (m_driver.isG2())
+ g2_clear (m_driver.idG2());
+ if (m_driver.isWX())
+ m_driver.idWX()->Clear();
}
-/* NAME
- * sgp2_window Set window in world coordinates
- */
+// NAME
+// sgp2_window Set window in world coordinates
+
void
-sgp2_window (double xmin, double ymin, double xmax, double ymax)
+SGP::setWindow (double xmin, double ymin, double xmax, double ymax)
{
- if (_sgp2_cwin == NULL)
- return;
-
- if (xmin >= xmax || ymin >= ymax) {
- sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_window]");
- return;
- }
-
- _sgp2_cwin->xw_min = xmin;
- _sgp2_cwin->yw_min = ymin;
- _sgp2_cwin->xw_max = xmax;
- _sgp2_cwin->yw_max = ymax;
- calc_wc_to_ndc();
+ if (xmin >= xmax || ymin >= ymax) {
+ sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_window]");
+ return;
+ }
+
+ xw_min = xmin;
+ yw_min = ymin;
+ xw_max = xmax;
+ yw_max = ymax;
+ m_bRecalcTransform = true;
}
-/* NAME
- * sgp2_viewport Set viewport in NDC
- */
+// NAME
+// sgp2_viewport Set viewport in NDC
void
-sgp2_viewport (double xmin, double ymin, double xmax, double ymax)
+SGP::setViewport (double xmin, double ymin, double xmax, double ymax)
{
- if (_sgp2_cwin == NULL)
- return;
-
- if (xmin >= xmax || ymin >= ymax) {
- sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_viewport]");
- return;
- }
+ if (xmin >= xmax || ymin >= ymax) {
+ sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_viewport]");
+ return;
+ }
- _sgp2_cwin->xv_min = xmin;
- _sgp2_cwin->yv_min = ymin;
- _sgp2_cwin->xv_max = xmax;
- _sgp2_cwin->yv_max = ymax;
- calc_wc_to_ndc();
-
- _sgp2_cwin->view[0] = xmin; /* Array for clip_rect() */
- _sgp2_cwin->view[1] = ymin;
- _sgp2_cwin->view[2] = xmax;
- _sgp2_cwin->view[3] = ymax;
+ xv_min = xmin;
+ yv_min = ymin;
+ xv_max = xmax;
+ yv_max = ymax;
+ m_bRecalcTransform = true;
+
+ viewNDC[0] = xmin; // Array for clip_rect()
+ viewNDC[1] = ymin;
+ viewNDC[2] = xmax;
+ viewNDC[3] = ymax;
}
-/* NAME
- * sgp2_frame_vpt draw box around viewport
- */
+// NAME
+// frameViewport draw box around viewport
void
-sgp2_frame_vpt (void)
+SGP::frameViewport (void)
{
- if (_sgp2_cwin == NULL)
- return;
-
- _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_min, _sgp2_cwin->yv_min, 0);
- _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_max, _sgp2_cwin->yv_min, 1);
- _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_max, _sgp2_cwin->yv_max, 1);
- _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_min, _sgp2_cwin->yv_max, 1);
- _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_min, _sgp2_cwin->yv_min, 1);
+ stylusNDC (xv_min, yv_min, 0);
+ stylusNDC (xv_max, yv_min, 1);
+ stylusNDC (xv_max, yv_max, 1);
+ stylusNDC (xv_min, yv_max, 1);
+ stylusNDC (xv_min, yv_min, 1);
}
-
-/* NAME
- * calc_wc_to_ndc Calculate transform matrix
- */
-
void
-calc_wc_to_ndc (void)
+SGP::setTextColor (int iFGcolor, int iBGcolor)
{
- double sx, sy;
-
- if (_sgp2_cwin == NULL)
- return;
-
- sx = (_sgp2_cwin->xv_max - _sgp2_cwin->xv_min) / (_sgp2_cwin->xw_max - _sgp2_cwin->xw_min);
- sy = (_sgp2_cwin->yv_max - _sgp2_cwin->yv_min) / (_sgp2_cwin->yw_max - _sgp2_cwin->yw_min);
-
- ident_gmtx_2 (_sgp2_cwin->wc_to_ndc_x);
- _sgp2_cwin->wc_to_ndc_x[0][0] = sx;
- _sgp2_cwin->wc_to_ndc_x[2][0] = _sgp2_cwin->xv_min - sx * _sgp2_cwin->xw_min;
- _sgp2_cwin->wc_to_ndc_x[1][1] = sy;
- _sgp2_cwin->wc_to_ndc_x[2][1] = _sgp2_cwin->yv_min - sy * _sgp2_cwin->yw_min;
-
- _sgp2_cwin->recalc_mc_to_ndc = TRUE;
- _sgp2_cwin->recalc_ndc_to_mc = TRUE;
}
-
void
-calc_ndc_to_mc (void)
+SGP::setColor (int icol)
{
- if (_sgp2_cwin == NULL)
- return;
-
- if (_sgp2_cwin->recalc_mc_to_ndc) {
- mult_gmtx_2 (_sgp2_cwin->ctm_2_x, _sgp2_cwin->wc_to_ndc_x, _sgp2_cwin->mc_to_ndc_x);
- _sgp2_cwin->recalc_mc_to_ndc = FALSE;
- }
-
- invert_gmtx_2 (_sgp2_cwin->mc_to_ndc_x, _sgp2_cwin->ndc_to_mc_x);
- _sgp2_cwin->recalc_ndc_to_mc = FALSE;
}
+void
+SGP::setMarker (int idMarke, int iColor)
+{
+}
-/* NAME
- * wc_to_ndc Map from world coordinates to NDC
- */
-
+//==============================================================
+// set line style. Pass 16 bit repeating pattern
+//==============================================================
void
-wc_to_ndc (double xw, double yw, double *xn, double *yn)
+SGP::setLineStyle (int style)
{
- if (_sgp2_cwin == NULL)
- return;
-
- if (_sgp2_cwin->recalc_mc_to_ndc) {
- mult_gmtx_2 (_sgp2_cwin->ctm_2_x, _sgp2_cwin->wc_to_ndc_x, _sgp2_cwin->mc_to_ndc_x);
- _sgp2_cwin->recalc_mc_to_ndc = FALSE;
- }
-
- *xn = xw * _sgp2_cwin->mc_to_ndc_x[0][0] + yw * _sgp2_cwin->mc_to_ndc_x[1][0] + _sgp2_cwin->mc_to_ndc_x[2][0];
- *yn = xw * _sgp2_cwin->mc_to_ndc_x[0][1] + yw * _sgp2_cwin->mc_to_ndc_x[1][1] + _sgp2_cwin->mc_to_ndc_x[2][1];
}
+//==============================================================
+// absolute draw to
+//*==============================================================
-/*==============================================================*/
-/* map from normalized device coords. to world coordinates */
-/*==============================================================*/
-void
-ndc_to_wc (double xn, double yn, double *xw, double *yw)
+void
+SGP::lineAbs (double x, double y)
{
- if (_sgp2_cwin == NULL)
- return;
+ if (m_bRecalcTransform)
+ calc_transform();
- if (_sgp2_cwin->recalc_ndc_to_mc) {
- calc_ndc_to_mc();
- _sgp2_cwin->recalc_ndc_to_mc = FALSE;
- }
+ double x1 = m_dCurrentWorldX;
+ double y1 = m_dCurrentWorldY;
+ mc_to_ndc.transformPoint (&x1, &y1);
- *xw = xn * _sgp2_cwin->ndc_to_mc_x[0][0] + yn * _sgp2_cwin->ndc_to_mc_x[1][0] + _sgp2_cwin->ndc_to_mc_x[2][0];
- *yw = xn * _sgp2_cwin->ndc_to_mc_x[0][1] + yn * _sgp2_cwin->ndc_to_mc_x[1][1] + _sgp2_cwin->ndc_to_mc_x[2][1];
-}
+ double x2 = x;
+ double y2 = y;
+ mc_to_ndc.transformPoint (&x1, &y2);
+
+ if (clip_rect (x1, y1, x2, y2, viewNDC) == true) { // clip to viewport
+ stylusNDC (x1, y1, 0); // move to first point
+ stylusNDC (x2, y2, 1); // draw to second point
+ }
+ m_dCurrentWorldX = x;
+ m_dCurrentWorldY = y;
+}
-/*==============================================================*/
-/* set the color */
-/*==============================================================*/
void
-sgp2_color (int icol)
+SGP::moveAbs (double x, double y)
{
- setcolor(icol);
+ m_dCurrentWorldX = x;
+ m_dCurrentWorldY = y; /* moves are not clipped */
}
-/*==============================================================*/
-/* set line style. Pass 16 bit repeating pattern */
-/*==============================================================*/
void
-sgp2_line_style (int style)
+SGP::lineRel (double x, double y)
{
- setlinestyle(style);
+ lineAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY);
}
-/*==============================================================*/
-/* absolute draw to */
-/*==============================================================*/
void
-sgp2_line_abs (double x, double y)
+SGP::moveRel (double x, double y)
{
- double x1, y1, x2, y2;
+ moveAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY);
+}
- if (_sgp2_cwin == NULL)
- return;
+void
+SGP::setTextSize (double height)
+{
+ if (m_driver.isG2())
+ g2_set_font_size(m_driver.idG2(), (height * m_iPhysicalYSize));
+}
- wc_to_ndc (_sgp2_cwin->curx, _sgp2_cwin->cury, &x1, &y1);
- wc_to_ndc (x, y, &x2, &y2);
+void
+SGP::setTextAngle (double angle)
+{
+ m_dTextAngle = angle;
+}
- if (clip_rect (x1, y1, x2, y2, _sgp2_cwin->view) == TRUE) { /* clip to viewport */
- _sgp2_stylus (_sgp2_cwin, x1, y1, 0); /* move to first point */
- _sgp2_stylus (_sgp2_cwin, x2, y2, 1); /* draw to second point */
+void
+SGP::polylineAbs (double x[], double y[], int n)
+{
+ if (m_bRecalcTransform)
+ calc_transform();
+
+ double x1 = x[0], y1 = y[0];
+ mc_to_ndc.transformPoint (&x1, &y1);
+ double x2 = x[1], y2 = y[1];
+ mc_to_ndc.transformPoint (&x2, &y2);
+
+ double xt = x2; // don't pass (x2,y2) to clip, we need them
+ double yt = y2; // as the beginning point of the next line
+
+ if (clip_rect (x1, y1, xt, yt, viewNDC)) {
+ stylusNDC (x1, y1, 0);
+ stylusNDC (xt, yt, 1);
+ }
+
+ for (int i = 2; i < n; i++) {
+ x1 = x2; y1 = y2; // NDC endpoint of last line
+ x2 = x[i]; y2 = y[i];
+ mc_to_ndc.transformPoint (&x2, &y2);
+ xt = x2;
+ yt = y2;
+ if (clip_rect (x1, y1, xt, yt, viewNDC)) {
+ stylusNDC (x1, y1, 0);
+ stylusNDC (xt, yt, 1);
}
-
- _sgp2_cwin->curx = x;
- _sgp2_cwin->cury = y;
+ }
}
-/*==============================================================*/
-/* absolute move to */
-/*==============================================================*/
+
void
-sgp2_move_abs (double x, double y)
+SGP::markerAbs (double x, double y)
{
- if (_sgp2_cwin == NULL)
- return;
+ if (m_bRecalcTransform)
+ calc_transform();
- _sgp2_cwin->curx = x;
- _sgp2_cwin->cury = y; /* moves are not clipped */
+ double xndc = x;
+ double yndc = y;
+ mc_to_ndc.transformPoint (&xndc, &yndc);
+ markerNDC (xndc, yndc);
+ stylusNDC (xndc, yndc, false); // move to location
+ m_dCurrentWorldX = x;
+ m_dCurrentWorldY = y;
}
-/*==============================================================*/
-/* vector draw */
-/*==============================================================*/
+
void
-sgp2_line_rel (double x, double y)
+SGP::markerRel (double x, double y)
{
- if (_sgp2_cwin != NULL)
- sgp2_line_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
+ markerAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY);
}
-/*==============================================================*/
-/* vector move */
-/*==============================================================*/
+
void
-sgp2_move_rel (double x, double y)
+SGP::pointAbs (double x, double y)
{
- if (_sgp2_cwin != NULL)
- sgp2_move_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
+ if (m_bRecalcTransform)
+ calc_transform();
+ double xndc = x, yndc = y;
+ mc_to_ndc.transformPoint (&xndc, &yndc);
+ pointNDC (xndc, yndc);
+ stylusNDC (xndc, yndc, false); // move to location
+ m_dCurrentWorldX = x;
+ m_dCurrentWorldY = y;
}
-/*==============================================================*/
-/* draw text */
-/*==============================================================*/
+
void
-sgp2_draw_text (char *message)
+SGP::pointRel (double x, double y)
{
- double sx,sy;
- if (_sgp2_cwin == NULL)
- return;
-
- wc_to_ndc (_sgp2_cwin->curx, _sgp2_cwin->cury, &sx, &sy);
- _sgp2_stylus (_sgp2_cwin, sx, sy, 0); /* move to location */
- _sgp2_dev_text (_sgp2_cwin, message);
+ pointAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY);
}
-void
-charsize (double wid, double height)
-{
- _sgp2_set_text (_sgp2_cwin, wid, height, cspec.textangle, cspec.font);
-}
void
-textangle (double angle)
+SGP::drawText (const string& rsMessage)
{
- _sgp2_set_text (_sgp2_cwin, cspec.width, cspec.height, angle, cspec.font);
+ drawText (rsMessage.c_str());
}
void
-sgp2_polyline_abs (double x[], double y[], int n)
+SGP::drawText (const char *pszMessage)
{
- double x1, y1, x2, y2;
- int i;
- double xt, yt;
+ if (m_bRecalcTransform)
+ calc_transform();
- if (_sgp2_cwin == NULL || n < 2)
- return;
+ double xndc = m_dCurrentWorldX;
+ double yndc = m_dCurrentWorldY;
+ mc_to_ndc.transformPoint (&xndc, &yndc);
- wc_to_ndc (x[0], y[0], &x1, &y1);
- wc_to_ndc (x[1], y[1], &x2, &y2);
+ stylusNDC (xndc, yndc, false); // move to location
- xt = x2; /* don't pass (x2,y2) to clip, we need them */
- yt = y2; /* as the beginning point of the next line */
-
- if (clip_rect (x1, y1, xt, yt, _sgp2_cwin->view) == TRUE) {
- _sgp2_stylus (_sgp2_cwin, x1, y1, 0);
- _sgp2_stylus (_sgp2_cwin, xt, yt, 1);
- }
-
- for (i = 2; i < n; i++) {
- x1 = x2; /* NDC endpoint of last line */
- y1 = y2;
- wc_to_ndc (x[i], y[i], &x2, &y2);
- xt = x2;
- yt = y2;
- if (clip_rect (x1, y1, xt, yt, _sgp2_cwin->view) == TRUE) {
- _sgp2_stylus (_sgp2_cwin, x1, y1, 0);
- _sgp2_stylus (_sgp2_cwin, xt, yt, 1);
- }
- }
+ if (m_driver.isG2()) {
+ if (m_dTextAngle == 0.)
+ g2_string (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, const_cast<char*>(pszMessage));
+ }
+ if (m_driver.isWX()) {
+ }
}
-void
-sgp2_mark_abs (double x, double y)
-{
- double xndc, yndc;
-
- if (_sgp2_cwin == NULL)
- return;
+// NAME
+// drawRect Draw box in graphics mode
+//
+// SYNOPSIS
+// drawbox (xmin, ymin, xmax, ymax)
+// double xmin, ymin Lower left corner of box
+// double xmax, ymax Upper left corner of box
+//
+// NOTES
+// This routine leaves the current position of graphic cursor at lower
+// left corner of box.
- wc_to_ndc (x, y, &xndc, &yndc);
- markndc (_sgp2_cwin, xndc, yndc);
- _sgp2_cwin->curx = x;
- _sgp2_cwin->cury = y;
+void
+SGP::drawRect (double xmin, double ymin, double xmax, double ymax)
+{
+ moveAbs (xmin, ymin);
+ lineAbs (xmax, ymin);
+ lineAbs (xmax, ymax);
+ lineAbs (xmin, ymax);
+ lineAbs (xmin, ymin);
}
-
+// FUNCTION
+// sgp2_circle - draw circle of radius r at current center
+
void
-sgp2_mark_rel (double x, double y)
+SGP::drawCircle (const double r)
{
- sgp2_mark_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
+ drawArc (0.0, 7.0, r);
}
+// =============================================================
+// draw arc around current center. pass angles and radius
+//==============================================================
void
-sgp2_point_abs (double x, double y)
+SGP::drawArc (double start, double stop, const double r)
{
- double xndc, yndc;
+ if ((stop-start) > 2 * PI)
+ stop = start + 2 * PI;
+ if ((start-stop) > 2 * PI)
+ stop = start + 2 * PI;
+ while (start >= stop)
+ stop += 2*PI;
+
+ double x = r * cos ((double) start);
+ double y = r * sin ((double) start);
+ moveRel (x, y); // move from center to start of arc
+
+ double theta = 5 * PI / 180;
+ double c = cos(theta);
+ double s = sin(theta);
+
+ double angle, xp, yp;
+ for (angle = start; angle < stop - theta; angle += theta) {
+ xp = c * x - s * y;
+ yp = s * x + c * y;
+ lineRel (xp - x, yp - y);
+ x = xp; y = yp;
+ }
- if (_sgp2_cwin == NULL)
- return;;
+ c = cos (stop - angle);
+ s = sin (stop - angle);
+ xp = c * x - s * y;
+ yp = s * x + c * y;
+ lineRel (xp - x, yp - y);
- wc_to_ndc (x, y, &xndc, &yndc);
- pntndc (_sgp2_cwin, xndc, yndc);
- _sgp2_cwin->curx = x;
- _sgp2_cwin->cury = y;
+ x = r * cos ((double) stop);
+ y = r * sin ((double) stop);
+ moveRel (-x, -y); // move back to center of circle
}
-void
-sgp2_point_rel (double x, double y)
+
+///////////////////////////////////////////////////////////////////////
+// Coordinate Transformations
+///////////////////////////////////////////////////////////////////////
+
+
+void
+SGP::transformNDCtoMC (double* x, double* y)
{
- sgp2_point_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
+ if (m_bRecalcTransform)
+ calc_transform();
+ ndc_to_mc.transformPoint (x, y);
}
-/* NAME
- * sgp2_draw_rect Draw box in graphics mode
- *
- * SYNOPSIS
- * drawbox (xmin, ymin, xmax, ymax)
- * double xmin, ymin Lower left corner of box
- * double xmax, ymax Upper left corner of box
- *
- * NOTES
- * This routine leaves the current position of graphic cursor at lower
- * left corner of box.
- */
+void
+SGP::transformMCtoNDC (double* x, double* y)
+{
+ if (m_bRecalcTransform)
+ calc_transform();
+ mc_to_ndc.transformPoint (x, y);
+}
+
void
-sgp2_draw_rect(double xmin, double ymin, double xmax, double ymax)
+SGP::transformMCtoNDC (double xIn, double yIn, double* x, double* y)
{
- sgp2_move_abs (xmin, ymin);
- sgp2_line_abs (xmax, ymin);
- sgp2_line_abs (xmax, ymax);
- sgp2_line_abs (xmin, ymax);
- sgp2_line_abs (xmin, ymin);
+ if (m_bRecalcTransform)
+ calc_transform();
+ *x = xIn;
+ *y = yIn;
+ mc_to_ndc.transformPoint (x, y);
}
-/* FUNCTION
- * sgp2_circle - draw circle of radius r at current center
- */
-void
-sgp2_draw_circle (const double r)
+// NAME
+// calc_transform Calculate transform matrices
+
+void
+SGP::calc_transform ()
{
- sgp2_draw_arc (0.0, 7.0, r);
+ double scaleX = (xv_max - xv_min) / (xw_max - xw_min);
+ double scaleY = (yv_max - yv_min) / (yw_max - yw_min);
+
+ wc_to_ndc.setIdentity();
+ wc_to_ndc.mtx[0][0] = scaleX;
+ wc_to_ndc.mtx[2][0] = xv_min - scaleX * xw_min;
+ wc_to_ndc.mtx[1][1] = scaleY;
+ wc_to_ndc.mtx[2][1] = yv_min - scaleY * yw_min;
+
+ mc_to_ndc = m_ctm * wc_to_ndc;
+ ndc_to_mc = mc_to_ndc.invert();
+
+ m_bRecalcTransform = false;
}
-/*==============================================================*/
-/* draw arc around current center. pass angles and radius */
-/*==============================================================*/
+void
+SGP::ctmClear ()
+{
+ m_ctm.setIdentity();
+ calc_transform();
+}
void
-sgp2_draw_arc (double start, double stop, const double r)
+SGP::ctmSet (const TransformationMatrix2D& m)
{
- double c, s, theta, angle;
- float x, y, xp, yp;
+ m_ctm = m;
+ calc_transform();
+}
- if ((stop-start) > 2 * PI)
- stop = start + 2 * PI;
- if ((start-stop) > 2 * PI)
- stop = start + 2 * PI;
- while (start >= stop)
- stop += 2*PI;
- x = r * cos ((double) start);
- y = r * sin ((double) start);
- sgp2_move_rel (x, y); /* move from center to start of arc */
+void
+SGP::preTranslate (double x, double y)
+{
+ TransformationMatrix2D m;
- theta = 5 * PI / 180;
- c = cos(theta);
- s = sin(theta);
+ m.setTranslate (x, y);
+ ctmSet (m * m_ctm);
+}
- for (angle = start; angle < stop - theta; angle += theta) {
- xp = c * x - s * y;
- yp = s * x + c * y;
- sgp2_line_rel (xp - x, yp - y);
- x = xp; y = yp;
- }
- c = cos (stop - angle);
- s = sin (stop - angle);
- xp = c * x - s * y;
- yp = s * x + c * y;
- sgp2_line_rel (xp - x, yp - y);
+void
+SGP::postTranslate (double x, double y)
+{
+ TransformationMatrix2D m;
- x = r * cos ((double) stop);
- y = r * sin ((double) stop);
- sgp2_move_rel (-x, -y); /* move back to center of circle */
+ m.setTranslate (x, y);
+ ctmSet (m_ctm * m);
}
-/*----------------------------------------------------------------------*/
-/* Current Transformation Matrix Routine */
-/*----------------------------------------------------------------------*/
+void
+SGP::preScale (double sx, double sy)
+{
+ TransformationMatrix2D m;
+ m.setScale (sx, sy);
+ ctmSet (m * m_ctm);
+}
-/* NAME
- * ctm_clr_2 Clear current transformation matrix
- *
- * SYNOPSIS
- * ctm_clr_2()
- */
void
-ctm_clr_2 (void)
+SGP::postScale (double sx, double sy)
{
- GRFMTX_2D m;
+ TransformationMatrix2D m;
- ident_gmtx_2 (m);
- ctm_set_2 (m);
+ m.setScale (sx, sy);
+ m_ctm = m_ctm * m;
+ ctmSet (m_ctm * m);
}
-/* NAME
- * ctm_get_2 Get ctm
- *
- * SYNOPSIS
- * ctm_get_2 (m)
- * OUT GRFMTX_2D m Copy of ctm
- */
-
void
-ctm_get_2 (GRFMTX_2D m)
+SGP::preRotate (double theta)
{
- int x, y;
+ TransformationMatrix2D m;
- if (_sgp2_cwin == NULL)
- return;
-
- for (x = 0; x < 3; x++)
- for (y = 0; y < 3; y++)
- m[x][y] = _sgp2_cwin->ctm_2_x[x][y];
+ m.setRotate (theta);
+ m_ctm = m * m_ctm;
+ ctmSet (m * m_ctm);
}
-/* NAME
- * ctm_set_2 Set ctm to a matrix
- *
- * SYNOPSIS
- * ctm_get_ctm_2 (m)
- * IN GRFMTX m New ctm
- */
-
void
-ctm_set_2 (GRFMTX_2D m)
+SGP::postRotate (double theta)
{
- int x, y;
- if (_sgp2_cwin == NULL)
- return;
+ TransformationMatrix2D m;
- for (x = 0; x < 3; x++)
- for (y = 0; y < 3; y++)
- _sgp2_cwin->ctm_2_x[x][y] = m[x][y];
-
- _sgp2_cwin->recalc_ndc_to_mc = TRUE;
- _sgp2_cwin->recalc_mc_to_ndc = TRUE;
+ m.setRotate (theta);
+ ctmSet (m_ctm * m);
}
void
-ctm_pre_mult_2 (GRFMTX_2D m)
+SGP::preShear (double shrx, double shry)
{
- GRFMTX_2D new_ctm;
+ TransformationMatrix2D m;
- mult_gmtx_2 (m, _sgp2_cwin->ctm_2_x, new_ctm);
- ctm_set_2 (new_ctm);
+ m.setShear (shrx, shry);
+ ctmSet (m * m_ctm);
}
void
-ctm_post_mult_2 (GRFMTX_2D m)
+SGP::postShear (double shrx, double shry)
{
- GRFMTX_2D new_ctm;
+ TransformationMatrix2D m;
- mult_gmtx_2 (_sgp2_cwin->ctm_2_x, m, new_ctm);
- ctm_set_2 (new_ctm);
+ m.setShear (shrx, shry);
+ ctmSet (m_ctm * m);
}
+
+
+////////////////////////////////////////////////////////////////////////
+// Bitmap Markers
+////////////////////////////////////////////////////////////////////////
+
+// Pixel patterns of marker symbols (1x1 to 5x5 matrix)
+const unsigned char SGP::MARKER_BITMAP[MARK_COUNT][5] =
+{
+ {'\000', '\000', '\010', '\000', '\000'}, // small dot
+ {'\000', '\034', '\024', '\034', '\000'}, // empty square
+ {'\000', '\034', '\034', '\034', '\000'}, // filled square
+ {'\000', '\010', '\024', '\010', '\000'}, // empty diamond
+ {'\000', '\010', '\034', '\010', '\000'}, // filled diamond
+ {'\010', '\010', '\076', '\010', '\010'}, // cross
+ {'\000', '\024', '\010', '\024', '\000'}, // X
+ {'\034', '\042', '\042', '\042', '\034'}, // open circle
+ {'\034', '\076', '\076', '\076', '\034'}, // filled circle
+ {'\076', '\042', '\042', '\042', '\076'}, // big open square
+ {'\010', '\024', '\042', '\024', '\010'}, // big open diamond
+};
+++ /dev/null
-/*****************************************************************************
-** This is part of the CTSim program
-** Copyright (C) 1983-2000 Kevin Rosenberg
-**
-** $Id: sgpdriver.cpp,v 1.1 2000/06/19 19:20:11 kevin Exp $
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License (version 2) as
-** published by the Free Software Foundation.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-******************************************************************************/
-
-/* Device Driver for IBM PC Kevin Rosenberg March 84 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "ctsupport.h"
-#include "sgp.h"
-
-
-static int init_prt(void);
-static void term_prt(void);
-
-/*===========================================================*/
-/* fundamental device drivers */
-/*===========================================================*/
-
-#define XCHARSIZ (1.0 / 80.0) /* size of standard characters */
-#define YCHARSIZ (1.0 / 25.0) /* on screen in NDC */
-
-#define CRTASPT (0.75) /* for IBM ECD */
-
-/*-------------------*/
-/* print buffer data */
-/*-------------------*/
-#define PRTINIT 1
-#define PRTLIN 2
-#define PRTTERM 3
-
-#define PRTSIZE 200
-#define PRTMODE 1 /* Epson 120 dot/in graphic mode */
-#define PRTASPT (120.0 / 72.0) /* dots/in vectical / horizontal */
-
-static DEVICE crt, prt;
-CHARSPEC cspec;
-static GRFSTATE state;
-
-
-
-/* NAME
- * gp_init Initialize graphics package
- *
- * SYNOPSIS
- * gp_init()
- */
-
-
-int
-_sgp2_init_dev (SGP_ID cwin)
-{
-#if 0
- initdevice (CRTDEV, GM_ENHANCED, 0, 0);
- initdevice (PRTDEV, PRTMODE, (int) (PRTSIZE * PRTASPT), PRTSIZE);
- opendevice (CRTDEV);
- setlinestyle (LS_SOLID);
- setcolor (1);
- _sgp2_set_text (XCHARSIZ, YCHARSIZ, 0.0, 0);
- setbackg (0);
- settextclr (1, 0);
- gp_set_aspect (CRTDEV, CRTASPT);
- gp_set_aspect (PRTDEV, 1.0);
-#endif
-
- state.xndc = 10.; /* to guarntee a move */
- _sgp2_stylus (cwin, 0.0,0.0,0); /* move to starting corner */
-
- return (TRUE);
-}
-
-
-/* NAME
- * gp_initdev Initializes graphic device
- *
- * SYNOPSIS
- * initdevice (dev, mode, xsize, ysize)
- * int dev Device handle
- * int mode Mode for device (device specific)
- * int xsize Size of x buffer for PRTDEV
- * int ysize Size of y buffer for PRTDEV
- */
-
-int
-initdevice (int dev, int mode, int xsize, int ysize)
-{
- if (dev & CRTDEV)
- {
- // crt.dotfunc = crt_wdot;
- // crt.linefunc = crt_line;
- crt.xmin = 0;
- crt.ymin = 0;
- switch (crt.mode)
- {
-#if 0
- case 4:
- case 5:
- crt.xmax = 319;
- crt.xsize = 320;
- crt.ymax = 199;
- crt.ysize = 200;
- crt.colormax = 3;
- break;
- case GM_640x200:
- crt.xmax = 639;
- crt.xsize = 640;
- crt.ymax = 199;
- crt.ysize = 200;
- crt.colormax = 1;
- break;
- case GM_ENHANCED:
- case GM_MONOGRF:
- crt.xmax = 639;
- crt.xsize = 640;
- crt.ymax = 349;
- crt.ysize = 350;
- crt.colormax = 15;
- break;
- case GM_640x480x16:
- crt.xmax = 639;
- crt.xsize = 640;
- crt.ymax = 479;
- crt.ysize = 480;
- crt.colormax = 15;
- break;
- case GM_640x480x256:
- crt.xmax = 639;
- crt.xsize = 640;
- crt.ymax = 479;
- crt.ysize = 480;
- crt.colormax = 255;
- break;
- case GM_1024x768x16:
- crt.xmax = 1023;
- crt.xsize = 1024;
- crt.ymax = 767;
- crt.ysize = 768;
- crt.colormax = 15;
- break;
- case GM_1024x768x256:
- crt.xmax = 1023;
- crt.xsize = 1024;
- crt.ymax = 767;
- crt.ysize = 768;
- crt.colormax = 255;
- break;
-#endif
- default:
- return (FALSE);
- }
- // crt_set_mode (crt.mode, TRUE); /* Initialize device */
- }
-
- if (dev & PRTDEV) {
- if (prt.open == TRUE)
- closedevice (PRTDEV);
- prt.buf = NULL;
- if (mode < 0)
- prt.mode = PRTMODE;
- if (mode > 6)
- prt.mode = PRTMODE;
- else
- prt.mode = mode;
-
- if (xsize > 1 && ysize > 1) {
- prt.xsize = xsize;
- prt.ysize = ysize;
- prt.xmin = 0;
- prt.ymin = 0;
- prt.xmax = prt.xsize - 1;
- prt.ymax = prt.ysize - 1;
- }
-
- prt.colormax = 1;
- // prt.dotfunc = prtdot;
- // prt.linefunc = prtline;
-
- init_prt (); /* Initialize the device */
- }
-
- return (TRUE);
-}
-
-
-/* NAME
- * gp_opendev Open device for output
- *
- * SYNOPSIS
- * gp_opendev (dev)
- * int dev Device handle
- * devices are number in powers of two
- */
-
-int
-opendevice (int dev)
-{
- if (dev & CRTDEV)
- crt.open = TRUE;
-
- if (dev & PRTDEV)
- prt.open = TRUE;
-
- return(TRUE);
-}
-
-
-/* NAME
- * gp_closedev Close device for output
- *
- * SYNOPSIS
- * gp_closedev (dev)
- * int dev Device handle
- *
- * DESCRIPTION
- * Temporarily suspends output from going to a device
- */
-
-void
-closedevice (int dev)
-{
- if (dev & CRTDEV) /* close crt */
- crt.open = FALSE;
-
- if (dev & PRTDEV)
- prt.open = FALSE;
-}
-
-
-void
-termdevice (int dev)
-{
- if (dev & PRTDEV)
- term_prt ();
-}
-
-static int init_prt(void)
-{
- return(0);
-}
-
-
-static void term_prt(void)
-{
-}
-
-/*===========================================================*/
-/* stylus draws a line to the absolute point x,y in NDC's */
-/* t=0 for move, t=1 for draw */
-/*===========================================================*/
-void
-_sgp2_stylus (SGP_ID cwin, double x, double y, int beam)
-{
- int xp, yp;
-
- if ((state.xndc == x) && (state.yndc == y) && (beam == 0))
- return; /* no need to move */
-
- state.xndc = x; /* save current beam location */
- state.yndc = y;
-
- if (cwin != NULL) {
- xp = (int) (x * cwin->pw_xsize + 0.5);
- yp = (int) (y * cwin->pw_ysize + 0.5);
-#if HAVE_G2_H
- if (beam != 0)
- g2_line (cwin->g2_id, (double) cwin->phys_curx, (double) cwin->phys_cury, (double) xp, (double) yp);
-#endif
- cwin->phys_curx = xp;
- cwin->phys_cury = yp;
- }
-}
-
-void
-pntndc (SGP_ID cwin, double x, double y)
-{
- _sgp2_stylus (cwin, x, y, 0); /* move to point */
- // if (crt.open == TRUE)
- // cpix_set (crt.icurx, crt.icury, crt.color);
-}
-
-void
-markndc (SGP_ID cwin, double x, double y)
-{
- _sgp2_stylus (cwin, x, y, 0); /* move to point */
-
- if (crt.open == TRUE)
- wrtsymbol (state.marktype, crt.icurx, crt.icury, &crt);
-
- if (prt.open == TRUE)
- wrtsymbol (state.marktype, prt.icurx, prt.icury, &prt);
-}
-
-GRFSTATE *
-inqstate (void)
-{
- return (&state);
-}
-
-void
-gp_set_aspect (int dev, double asp)
-{
- if (asp > 0.0) {
- if (dev & CRTDEV)
- crt.asp = asp;
- if (dev & PRTDEV)
- prt.asp = asp;
- }
-}
-
-void
-setlinestyle (int style)
-{
- if (style == state.linestyle)
- return;
-
- state.linestyle = style;
-
- crt.style = style;
- prt.style = style;
-
- // crt_line_style (crt.style);
-}
-
-void
-setlinewidth (int wid)
-{
- state.linewidth = wid;
-}
-
-DEVICE *
-inqdev (int dev)
-{
- if (dev & CRTDEV)
- return (&crt);
- else if (dev & PRTDEV)
- return (&prt);
- else
- return (NULL);
-}
-
-/*===========================================================*/
-/* set text size */
-/*===========================================================*/
-void
-_sgp2_set_text ( SGP_ID cwin,
- double width,
- double height, /* size of character in NDC */
- double textangle, /* text angle */
- int font /* text font */
- )
-{
- double temp;
-
-#if HAVE_G2_H
- g2_set_font_size(cwin->g2_id, (height * cwin->pw_ysize));
-#endif
- height = clamp (height, 0.0, 1.0);
- width = clamp (width, 0.0, 1.0);
- /* textangle = textangle - (2 * PI * (int) (textangle / (2 * PI)));
- */
- cspec.width = width;
- cspec.height = height;
- cspec.textangle = textangle;
- cspec.font = font;
-
- if (textangle > - HALFPI / 2 && textangle < HALFPI / 2) {
- cspec.updir = YPLUS;
- cspec.textdir = XPLUS;
- } else if (textangle > HALFPI / 2 && textangle < 3 * HALFPI / 2) {
- cspec.updir = XMINUS;
- cspec.textdir = YPLUS;
- } else if (textangle > 3 * HALFPI / 2 && textangle < 5 * HALFPI / 2) {
- cspec.updir = YMINUS;
- cspec.textdir = XMINUS;
- } else if (textangle > 5 * HALFPI / 2 && textangle < 7 * HALFPI / 2) {
- cspec.updir = XPLUS;
- cspec.textdir = YMINUS;
- } else {
- cspec.updir = YPLUS;
- cspec.textdir = XPLUS;
- }
-
- if (cspec.updir == XMINUS || cspec.updir == XPLUS) {
- temp = height;
- height = width;
- width = temp;
- }
-
- crt.icwidth = (int) (width * crt.xsize + 0.5);
- crt.icheight = (int) (height * crt.ysize + 0.5);
- crt.icwidth = clamp (crt.icwidth, 8, crt.xsize);
- crt.icheight = clamp (crt.icheight, 8, crt.ysize);
-
- prt.icwidth = (int) (width * prt.xsize + 0.5);
- prt.icheight = (int) (height * prt.ysize + 0.5);
- prt.icwidth = clamp (prt.icwidth, 8, prt.xsize);
- prt.icheight = clamp (prt.icheight, 8, prt.ysize);
-}
-
-void
-settextclr (int fore, int back)
-{
- cspec.fore = fore;
- cspec.back = back;
- crt.cfore = fore;
- crt.cback = back;
- prt.cfore = clamp (fore, 0, prt.colormax);
- prt.cback = back;
-}
-
-void
-setcolor (int fore)
-{
- int back;
-
- state.foregnd = fore;
- back = state.backgnd;
- crtcolor (crt.mode, &fore, &back); /* set colors on crt */
- crt.color = fore;
- prt.color = clamp (fore, 0, prt.colormax);
-}
-
-void
-setbackg (int back)
-{
- int fore;
-
- state.backgnd = back;
- fore = state.foregnd;
- crtcolor (crt.mode, &fore, &back);
-}
-
-/*
- * INITMARKER (<SYMBOL>)
- *
- * Sets the current marker symbol (cross, square, diamond..)
- */
-int
-initmarker (int marker, int color)
-{
- if (marker > NMARKERS || marker < 0)
- return(-1);
- else {
- state.marktype = marker;
- state.markcolor = color;
- }
- return(0);
-} /* end initmarker */
-
-/*
- * SETCHARDIR ( <DIRECTION> )
- *
- * indicates in which direction a string should be printed, e.g.:
- * direction = YPLUS -> print on the horizontal from left to right
- * direction = YMINUS -> print upside-down characters from right to left
- * direction = XMINUS -> print on the vertical from down to up
- * direction = XPLUS -> print on the vertical from up to down
- */
-int
-settextdir (
- int direction /* direction flag */
- )
-{
-
- if (direction != XPLUS &&
- direction != XMINUS &&
- direction != YPLUS &&
- direction != YMINUS ) {
- printf("Error in character direction: %d\n", direction);
- return(-1);
- }
- cspec.textdir = direction;
- charsize (cspec.width, cspec.height);
-
- return(0);
-} /* end setchardir */
-
-
-void
-_sgp2_dev_text (SGP_ID cwin, char *message)
-{
-#if HAVE_G2_H
- g2_string (cwin->g2_id, cwin->phys_curx, cwin->phys_cury, message);
-#endif
-}
-
-/*===========================================================*/
-/* terminate graphics to current device */
-/* close any files, and output any buffers */
-/*===========================================================*/
-void
-termgrf2 (void)
-{
- if (prt.open == TRUE) {
- flushdevice (PRTDEV);
- closedevice (PRTDEV);
- termdevice (PRTDEV);
- }
-
- if (crt.open == TRUE) {
- closedevice (CRTDEV);
- }
-}
-
-
-void
-flushdevice (int dev)
-{
- // if (dev & PRTDEV)
- // prtline (PRTTERM, 0, 0, 0, 0, 0, 0); /* print contents of printer buffer */
-}
+++ /dev/null
-/*****************************************************************************
-** This is part of the CTSim program
-** Copyright (C) 1983-2000 Kevin Rosenberg
-**
-** $Id: sgptext.cpp,v 1.2 2000/06/19 19:04:05 kevin Exp $
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License (version 2) as
-** published by the Free Software Foundation.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-******************************************************************************/
-
-/* FILE
- * sgptext.c Text routines for graphics package
- */
-
-#include <stdio.h>
-#include "ctsupport.h"
-#include "sgp.h"
-
-
-/* Pixel patterns of marker symbols (1x1 to 5x5 matrix) */
-char MARKER[NMARKERS][5] = {
- { '\0', '\0', '\010', '\0', '\0'}, /* small dot */
- { '\0', '\034', '\024', '\034', '\0'}, /* empty square */
- { '\0', '\034', '\034', '\034', '\0'}, /* filled square */
- { '\0', '\010', '\024', '\010', '\0'}, /* empty diamond */
- { '\0', '\010', '\034', '\010', '\0'}, /* filled diamond */
- { '\010', '\010', '\076', '\010', '\010'}, /* cross */
- { '\0', '\024', '\010', '\024', '\0'}, /* x */
- { '\034', '\042', '\042', '\042', '\034'}, /* open circle */
- { '\034', '\076', '\076', '\076', '\034'}, /* filled circle */
- { '\076', '\042', '\042', '\042', '\076'}, /* big open square */
- { '\010', '\024', '\042', '\024', '\010'}}; /* big open diamond */
-
-/* WRTSYMBOL (sym, x, y, dev)
- *
- * puts marker symbols on the screen
- * input in screen pixels
- * Calls: dot()
- */
-
-void
-wrtsymbol (
- int sym,
- int x,
- int y, /* Coordinates in screen pixels */
- DEVICE *dev
-)
-{
-}
-
-/*
- * WRTCHAR(<CH>, <X>, <Y>, cspec, dev)
- *
- * puts marker symbols on the screen
- * input in screen pixels
- * Calls: dot(), peek()
- */
-
-void
-wrtchar (
- int ch, /* Character to be put on the screen */
- int x,
- int y, /* Coordinates in screen pixels of lower left corner*/
- CHARSPEC *cspec,
- DEVICE *dev
-)
-{
-}
-
-/*
- * WRTTEXT (<STRING>)
- *
- * prints a string starting from current position writing in the current
- * printing direction (at right angle to the character direction)
- * The pen is return to the original position.
- */
-
-void
-wrttext (char txtstr[], int x, int y, CHARSPEC *cspec, DEVICE *dev)
-{
-}
-
-
-/*
- * SETCOLOR( <COLOR>)
- *
- * Set current color
- */
-void
-crtcolor (int mode, int *f, int *b)
-{
-}
--- /dev/null
+/*****************************************************************************
+** FILE IDENTIFICATION
+**
+** Name: transformmatrix.cpp
+** Function: Transform Matrix routine for graphic library
+** Programmer: Kevin Rosenberg
+** Date Started: 1-22-85
+**
+** This is part of the CTSim program
+** Copyright (C) 1983-2000 Kevin Rosenberg
+**
+** $Id: transformmatrix.cpp,v 1.1 2000/07/28 08:28:08 kevin Exp $
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License (version 2) as
+** published by the Free Software Foundation.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+******************************************************************************/
+
+#include "ctsupport.h"
+#include "transformmatrix.h"
+#include <iostream>
+
+
+TransformationMatrix2D::TransformationMatrix2D (double m[3][3])
+{
+ mtx[0][0] = m[0][0]; mtx[0][1] = m[0][1]; mtx[0][2] = m[0][2];
+ mtx[1][0] = m[1][0]; mtx[1][1] = m[1][1]; mtx[1][2] = m[1][2];
+ mtx[2][0] = m[2][0]; mtx[2][1] = m[2][1]; mtx[2][2] = m[2][2];
+}
+
+void
+TransformationMatrix2D::setTranslate (double x, double y)
+{
+ setIdentity();
+ mtx[2][0] = x;
+ mtx[2][1] = y;
+}
+
+
+void
+TransformationMatrix2D::setScale (double sx, double sy)
+{
+ setIdentity();
+ mtx[0][0] = sx;
+ mtx[1][1] = sy;
+}
+
+
+void
+TransformationMatrix2D::setShear (double shrx, double shry)
+{
+ setIdentity();
+ mtx[1][0] = shrx;
+ mtx[0][1] = shry;
+}
+
+void
+TransformationMatrix2D::setRotate (double theta)
+{
+ double s = sin (theta);
+ double c = cos (theta);
+
+ setIdentity();
+
+ mtx[0][0] = c; mtx[0][1] = s;
+ mtx[1][0] = -s; mtx[1][1] = c;
+}
+
+
+void
+TransformationMatrix2D::setIdentity ()
+{
+ mtx[0][0] = 1.; mtx[0][1] = 0.; mtx[0][2] = 0.;
+ mtx[1][0] = 0.; mtx[1][1] = 1.; mtx[1][2] = 0.;
+ mtx[2][0] = 0.; mtx[2][1] = 0.; mtx[2][2] = 1.;
+}
+
+
+const TransformationMatrix2D
+TransformationMatrix2D::invert () const
+{
+ double b[3][3];
+
+ double determ = determinant ();
+ if (fabs(determ) < 1E-6) {
+ sys_error (ERR_WARNING, "Determinant = %g [TransformationMatrix2D::invert]", determ);
+ print (cout);
+ cout << endl;
+ }
+
+ b[0][0] = (mtx[1][1] * mtx[2][2] - mtx[2][1] * mtx[1][2]) / determ;
+ b[1][0] = -(mtx[1][0] * mtx[2][2] - mtx[2][0] * mtx[1][2]) / determ;
+ b[2][0] = (mtx[1][0] * mtx[2][1] - mtx[2][0] * mtx[1][1]) / determ;
+
+ b[0][1] = -(mtx[0][1] * mtx[2][2] - mtx[2][1] * mtx[0][2]) / determ;
+ b[1][1] = (mtx[0][0] * mtx[2][2] - mtx[2][0] * mtx[0][2]) / determ;
+ b[2][1] = -(mtx[0][0] * mtx[2][1] - mtx[2][0] * mtx[0][1]) / determ;
+
+ b[0][2] = (mtx[0][1] * mtx[1][2] - mtx[1][1] * mtx[0][2]) / determ;
+ b[1][2] = -(mtx[0][0] * mtx[1][2] - mtx[1][0] * mtx[0][2]) / determ;
+ b[2][2] = (mtx[0][0] * mtx[1][1] - mtx[1][0] * mtx[0][1]) / determ;
+
+ return TransformationMatrix2D (b);
+}
+
+
+double
+TransformationMatrix2D::determinant () const
+{
+ return
+ (mtx[0][0] * mtx[1][1] * mtx[2][2] - mtx[0][0] * mtx[2][1] * mtx[1][2] -
+ mtx[0][1] * mtx[1][0] * mtx[2][2] + mtx[0][1] * mtx[2][0] * mtx[1][2] +
+ mtx[0][2] * mtx[1][0] * mtx[2][1] - mtx[0][2] * mtx[2][0] * mtx[1][1]);
+}
+
+
+void
+TransformationMatrix2D::transformPoint (double* pX, double *pY) const
+{
+ double x = *pX * mtx[0][0] + *pY * mtx[1][0] + mtx[2][0];
+ double y = *pX * mtx[0][1] + *pY * mtx[1][1] + mtx[2][1];
+
+ *pX = x;
+ *pY = y;
+}
+
+void
+TransformationMatrix2D::print (ostream& ostr) const
+{
+ cout << mtx[0][0] << " " << mtx[0][1] << " " << mtx[0][2] << endl;
+ cout << mtx[1][0] << " " << mtx[1][1] << " " << mtx[1][2] << endl;
+ cout << mtx[2][0] << " " << mtx[2][1] << " " << mtx[2][2] << endl;
+}
+
+
+// Friend of TransformMatrix2D
+
+const TransformationMatrix2D operator* (const TransformationMatrix2D& a, const TransformationMatrix2D& b)
+{
+ double c[3][3];
+
+ for (int row = 0; row < 3; row++)
+ for (int col = 0; col < 3; col++) {
+ c[row][col] = 0.;
+ for (int calc = 0; calc < 3; calc++)
+ c[row][col] += a.mtx[row][calc] * b.mtx[calc][col];
+ }
+
+ return TransformationMatrix2D (c);
+}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: phantom.cpp,v 1.10 2000/07/22 15:45:33 kevin Exp $
+** $Id: phantom.cpp,v 1.11 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
void
Phantom::show () const
{
- double wsize = m_xmax - m_xmin;
- double xmin = m_xmin;
- double ymin = m_ymin;
- double xmax, ymax;
- SGP_ID gid;
-
- if ((m_ymax - m_ymin) > wsize)
- wsize = m_ymax - m_ymin;
- wsize *= 1.1;
-
- xmax = xmin + wsize;
- ymax = ymin + wsize;
-
- printf("Drawing Phantom:\n\n");
- printf(" data limits: %9.3g, %9.3g, %9.3g, %9.3g\n", m_xmin, m_ymin, m_xmax, m_ymax);
- printf(" window size: %9.3g, %9.3g, %9.3g, %9.3g\n", xmin, ymin, xmax, ymax);
-
- gid = sgp2_init (0, 0, "Phantom Show");
- sgp2_window (xmin, ymin, xmax, ymax);
+ SGPDriver driverSGP ("Phantom Show");
+ SGP sgp (driverSGP);
+ draw (sgp);
- draw();
-
- sgp2_close (gid);
+ cout << "Press return to continue";
+ cio_kb_getc();
}
#endif
#ifdef HAVE_SGP
void
-Phantom::draw () const
+Phantom::draw (SGP& sgp) const
{
+ double wsize = m_xmax - m_xmin;
+ double xmin = m_xmin;
+ double ymin = m_ymin;
+
+ if ((m_ymax - m_ymin) > wsize)
+ wsize = m_ymax - m_ymin;
+ wsize *= 1.1;
+
+ double xmax = xmin + wsize;
+ double ymax = ymin + wsize;
+
+ sgp.setWindow (xmin, ymin, xmax, ymax);
for (PElemIterator i = m_listPElem.begin(); i != m_listPElem.end(); i++)
- sgp2_polyline_abs ((*i)->xOutline(), (*i)->yOutline(), (*i)->nOutlinePoints());
+ sgp.polylineAbs ((*i)->xOutline(), (*i)->yOutline(), (*i)->nOutlinePoints());
}
#endif
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: projections.cpp,v 1.15 2000/07/15 08:36:13 kevin Exp $
+** $Id: projections.cpp,v 1.16 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
cout << "Reconstruct: filter="<<filterName<< ", interp="<<interpName<<", backproject="<<backprojectName<<endl;
#if HAVE_SGP
- SGP_ID gid;
int nVecFilter = filter.getNFilterPoints();
double plot_xaxis [nVecFilter]; // array for plotting
int i;
double f;
double filterInc = filter.getFilterIncrement();
- for (i = 0, f = filter.getFilterMin(); i < nVecFilter; i++, f += filterInc)
+ for (i = 0, f = filter.getFilterMin(); i < nVecFilter; i++, f += filterInc)
plot_xaxis[i] = f;
if (filter.getFilter()) {
- gid = ezplot (plot_xaxis, filter.getFilter(), nVecFilter);
+ SGPDriver sgpDriver ("Filter Function");
+ SGP sgp (sgpDriver);
+ EZPlot ezplot (sgp);
+
+ ezplot.addCurve (plot_xaxis, filter.getFilter(), nVecFilter);
cio_put_str ("Press any key to continue");
cio_kb_getc ();
- sgp2_close (gid);
}
}
if (trace >= TRACE_TEXT) {
#ifdef HAVE_SGP
if (trace >= TRACE_PLOT) {
- ezset ("clear.");
- ezset ("xticks major 5.");
- ezset ("xlabel ");
- ezset ("ylabel ");
- ezset ("xlength .5.");
- ezset ("box.");
- ezset ("grid.");
- ezset ("ufinish yes.");
- ezplot (detval, plot_xaxis, m_nDet);
- ezset ("clear.");
- ezset ("xticks major 5.");
- ezset ("xlabel ");
- ezset ("ylabel ");
- ezset ("ustart yes.");
- ezset ("xporigin .5.");
- ezset ("xlength .5.");
- ezset ("box");
-
- ezset ("grid");
- gid = ezplot (filteredProj, plot_xaxis, n_filteredProj);
+ SGPDriver sgpDriverProj ("Projection");
+ SGP sgpProj (sgpDriverProj);
+ EZPlot ezplotProj (sgpProj);
+
+ ezplotProj.ezset ("clear");
+ ezplotProj.ezset ("xticks major 5.");
+ ezplotProj.ezset ("xlabel ");
+ ezplotProj.ezset ("ylabel ");
+ ezplotProj.ezset ("xlength .5.");
+ ezplotProj.ezset ("box.");
+ ezplotProj.ezset ("grid.");
+ ezplotProj.addCurve (detval, plot_xaxis, m_nDet);
+ ezplotProj.ezset ("clear.");
+ ezplotProj.ezset ("xticks major 5.");
+ ezplotProj.ezset ("xlabel ");
+ ezplotProj.ezset ("ylabel ");
+ ezplotProj.ezset ("xporigin .5.");
+ ezplotProj.ezset ("xlength .5.");
+ ezplotProj.ezset ("box");
+ ezplotProj.ezset ("grid");
+ ezplotProj.addCurve (filteredProj, plot_xaxis, n_filteredProj);
+ ezplotProj.plot ();
+ cout << "Press enter to continue\n";
+ cio_kb_getc();
}
#endif //HAVE_SGP
char str[256];
printf ("Do you want to exit with current pic (y/n) -- ");
fgets(str, sizeof(str), stdin);
- sgp2_close (sgp2_get_active_win());
if (tolower(str[0]) == 'y') {
break;
}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: scanner.cpp,v 1.5 2000/07/22 15:45:33 kevin Exp $
+** $Id: scanner.cpp,v 1.6 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
*/
void
-Scanner::collectProjections (Projections& proj, const Phantom& phm, const int start_view, const int trace)
+Scanner::collectProjections (Projections& proj, const Phantom& phm, const int start_view, const int trace = TRACE_NONE, SGP* pSGP = NULL)
{
GRFMTX_2D rotmtx_initial, temp;
GRFMTX_2D rotmtx_incr;
m_trace = trace;
#ifdef HAVE_SGP
- SGP_ID gid;
- if (m_trace >= TRACE_PHM) {
+ if (pSGP && m_trace >= TRACE_PHM) {
double wsize = 1.42 * m_phmLen / 2; /* sqrt(2) * radius */
-
- gid = sgp2_init (512, 512, "RayCollect");
- sgp2_color (C_LTBLUE);
- sgp2_window (xcent - wsize, ycent - wsize, xcent + wsize, ycent + wsize);
- sgp2_color (C_BROWN);
+
+ pSGP->setColor (C_LTBLUE);
+ pSGP->setWindow (xcent - wsize, ycent - wsize, xcent + wsize, ycent + wsize);
+ pSGP->setColor (C_BROWN);
#if RADIUS
- sgp2_draw_circle (m_phmLen / 2);
+ pSGP->drawCircle (m_phmLen / 2);
#else
- sgp2_draw_rect (xcent - m_phmLen / 2, ycent - m_phmLen / 2,
+ pSGP->drawRect (xcent - m_phmLen / 2, ycent - m_phmLen / 2,
xcent + m_phmLen / 2, ycent + m_phmLen / 2);
#endif
- sgp2_color (C_BROWN);
- sgp2_move_abs (0., 0.);
- sgp2_draw_circle (wsize);
+ pSGP->setColor (C_BROWN);
+ pSGP->moveAbs (0., 0.);
+ pSGP->drawCircle (wsize);
// raysum_trace_menu_column = (crt->xsize * crt->asp) / 8 + 3;
traceShowParam ("X-Ray Simulator", "%s", RAYSUM_TRACE_ROW_TITLE, 8+C_LTWHITE, " ");
traceShowParam ("---------------", "%s", RAYSUM_TRACE_ROW_TITLE2, 8+C_LTWHITE, " ");
traceShowParam ("Num Views :", "%5d", RAYSUM_TRACE_ROW_NVIEW, C_LTRED, proj.nView());
traceShowParam ("Samples / Ray:", "%5d", RAYSUM_TRACE_ROW_SAMPLES, C_LTRED, m_nSample);
- sgp2_color (C_LTGREEN);
- phm.draw();
+ pSGP->setColor (C_LTGREEN);
+ phm.draw (*pSGP);
- initmarker (BDIAMOND, 129);
+ pSGP->setMarker (SGP::MARK_BDIAMOND, C_LTGREEN);
}
#endif
DetectorArray& detArray = proj.getDetectorArray( iview );
#ifdef HAVE_SGP
- if (m_trace >= TRACE_PHM) {
- sgp2_move_abs (xd1, yd1);
- sgp2_line_abs (xd2, yd2);
- sgp2_move_abs (xs1, ys1);
- sgp2_line_abs (xs2, ys2);
+ if (pSGP && m_trace >= TRACE_PHM) {
+ pSGP->moveAbs (xd1, yd1);
+ pSGP->lineAbs (xd2, yd2);
+ pSGP->moveAbs (xs1, ys1);
+ pSGP->lineAbs (xs2, ys2);
}
#endif
if (m_trace)
traceShowParam ("Current View :", "%5d", RAYSUM_TRACE_ROW_CURR_VIEW, C_LTMAGENTA, iview);
- projectSingleView (phm, detArray, xd1, yd1, xd2, yd2, xs1, ys1, xs2, ys2);
+ projectSingleView (phm, detArray, xd1, yd1, xd2, yd2, xs1, ys1, xs2, ys2, pSGP);
detArray.setViewAngle (viewAngle);
#ifdef HAVE_SGP
- if (m_trace >= TRACE_PHM) {
+ if (pSGP && m_trace >= TRACE_PHM) {
// rs_plot (detArray, xd1, yd1, xcent, ycent, theta);
- sgp2_move_abs (xd1, yd1);
- sgp2_line_abs (xd2, yd2);
- sgp2_move_abs (xs1, ys1);
- sgp2_line_abs (xs2, ys2);
+ pSGP->moveAbs (xd1, yd1);
+ pSGP->lineAbs (xd2, yd2);
+ pSGP->moveAbs (xs1, ys1);
+ pSGP->lineAbs (xs2, ys2);
}
#endif
xform_mtx2 (rotmtx_incr, xd1, yd1); // rotate detector endpoints
*/
void
-Scanner::projectSingleView (const Phantom& phm, DetectorArray& detArray, const double xd1, const double yd1, const double xd2, const double yd2, const double xs1, const double ys1, const double xs2, const double ys2)
+Scanner::projectSingleView (const Phantom& phm, DetectorArray& detArray, const double xd1, const double yd1, const double xd2, const double yd2, const double xs1, const double ys1, const double xs2, const double ys2, SGP* pSGP)
{
double ddx = (xd2 - xd1) / detArray.nDet(); // change in coords between detectors
double ddy = (yd2 - yd1) / detArray.nDet();
double sum = 0.0;
for (unsigned int i = 0; i < m_nSample; i++) {
#ifdef HAVE_SGP
- if (m_trace >= TRACE_RAYS) {
- sgp2_move_abs (xs, ys);
- sgp2_line_abs (xd, yd);
+ if (pSGP && m_trace >= TRACE_RAYS) {
+ pSGP->moveAbs (xs, ys);
+ pSGP->lineAbs (xd, yd);
}
#endif
- sum += projectSingleLine (phm, xd, yd, xs, ys);
+ sum += projectSingleLine (phm, xd, yd, xs, ys, pSGP);
if (m_trace >= TRACE_RAYS)
traceShowParam ("Attenuation :", "%5.2f", RAYSUM_TRACE_ROW_ATTEN, C_LTMAGENTA, "sum");
#ifdef HAVE_SGP
- if (m_trace >= TRACE_RAYS) {
- sgp2_move_abs (xs, ys);
- sgp2_line_abs (xd, yd);
+ if (pSGP && m_trace >= TRACE_RAYS) {
+ pSGP->moveAbs (xs, ys);
+ pSGP->lineAbs (xd, yd);
}
#endif
xd += ddx2;
vsnprintf (s, sizeof(s), fmt, arg);
// cio_set_text_clr (color, 0);
cio_put_str (s);
-
+ cout << "\n";
va_end(arg);
}
*/
double
-Scanner::projectSingleLine (const Phantom& phm, const double x1, const double y1, const double x2, const double y2)
+Scanner::projectSingleLine (const Phantom& phm, const double x1, const double y1, const double x2, const double y2, SGP* pSGP)
{
// check ray against each pelem in Phantom
double rsum = 0.0;
for (PElemConstIterator i = phm.listPElem().begin(); i != phm.listPElem().end(); i++)
- rsum += projectLineAgainstPElem (**i, x1, y1, x2, y2);
+ rsum += projectLineAgainstPElem (**i, x1, y1, x2, y2, pSGP);
return (rsum);
}
*/
double
-Scanner::projectLineAgainstPElem (const PhantomElement& pelem, double x1, double y1, double x2, double y2)
+Scanner::projectLineAgainstPElem (const PhantomElement& pelem, double x1, double y1, double x2, double y2, SGP* pSGP)
{
if (! pelem.clipLineWorldCoords (x1, y1, x2, y2)) {
if (m_trace == TRACE_CLIPPING)
}
#ifdef HAVE_SGP
- if (m_trace == TRACE_CLIPPING) {
- sgp2_move_abs (x1, y1);
- sgp2_line_abs (x2, y2);
+ if (pSGP && m_trace == TRACE_CLIPPING) {
+ pSGP->moveAbs (x1, y1);
+ pSGP->lineAbs (x2, y2);
cio_tone (8000., 0.05);
- sgp2_move_abs (x1, y1);
- sgp2_line_abs (x2, y2);
+ pSGP->moveAbs (x1, y1);
+ pSGP->lineAbs (x2, y2);
}
#endif
man_MANS=ctrec.1 phm2rs.1 phm2if.1 if2img.1 ifinfo.1 if-1.1
-info_INFO=ctsim.texi
-EXTRA_DIST = $(man_MANS) $(info_INFO)
+EXTRA_DIST = $(man_MANS)
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: dialogs.h,v 1.7 2000/07/22 16:14:49 kevin Exp $
+** $Id: dialogs.h,v 1.8 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
};
+#include "backprojectors.h"
class DialogGetReconstructionParameters : public wxDialog
{
public:
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: views.cpp,v 1.8 2000/07/22 15:45:33 kevin Exp $
+** $Id: views.cpp,v 1.9 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
// PhantomCanvas
PhantomCanvas::PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style)
- : wxPanel(frame, -1, pos, size, style)
+ : wxScrolledWindow(frame, -1, pos, size, style)
{
m_pView = v;
}
m_pView->OnDraw(& dc);
}
+
// PhantomView
IMPLEMENT_DYNAMIC_CLASS(PhantomView, wxView)
m_frame->Show(true);
Activate(true);
-
- return true;
-}
-void
-PhantomView::OnDraw (wxDC* dc)
-{
- // if (m_bitmap.Ok())
- // dc->DrawBitmap (m_bitmap, 0, 0, false);
+ return true;
}
return true;
}
+void
+PhantomView::OnDraw (wxDC* dc)
+{
+ int xsize, ysize;
+ m_canvas->GetClientSize (&xsize, &ysize);
+ SGPDriver driver (dc, "", xsize, ysize);
+ SGP sgp (driver);
+ const Phantom& rPhantom = GetDocument()->getPhantom();
+ rPhantom.draw (sgp);
+}
// ProjectionCanvas
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: views.h,v 1.5 2000/07/18 16:20:53 kevin Exp $
+** $Id: views.h,v 1.6 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
virtual ~PhantomView(void);
bool OnCreate(wxDocument *doc, long flags);
- void OnDraw(wxDC* dc);
void OnUpdate(wxView *sender, wxObject *hint = NULL);
bool OnClose (bool deleteWindow = true);
+ void OnDraw(wxDC* dc);
void OnProperties (wxCommandEvent& event);
void OnRasterize (wxCommandEvent& event);
void OnProjections (wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
-class PhantomCanvas: public wxPanel
+class PhantomCanvas: public wxScrolledWindow
{
public:
PhantomView* m_pView;
PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style);
+
virtual void OnDraw(wxDC& dc);
};
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: if-2.cpp,v 1.1 2000/07/13 07:01:35 kevin Exp $
+** $Id: if-2.cpp,v 1.2 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
for (int i = 0; i < nx; i++)
plot_xaxis[i] = i;
#if HAVE_SGP
-#if 0
-#else
- ezset ("clear.");
- ezset ("xticks major 5.");
- ezset ("xlabel Column");
- ezset ("ylabel Pixel");
- ezset ("curves 2");
- ezset ("box.");
- ezset ("grid.");
- ezplot (v1[opt_columnPlot], plot_xaxis, im_in1.ny());
- ezplot (v2[opt_columnPlot], plot_xaxis, im_in2.ny());
-#endif
- char str[256];
+ SGPDriver driver ("Column Plot");
+ SGP sgp (driver);
+ EZPlot ezplot (sgp);
+ ezplot.ezset ("clear.");
+ ezplot.ezset ("xticks major 5.");
+ ezplot.ezset ("xlabel Column");
+ ezplot.ezset ("ylabel Pixel");
+ ezplot.ezset ("curves 2");
+ ezplot.ezset ("box.");
+ ezplot.ezset ("grid.");
+ ezplot.addCurve (v1[opt_columnPlot], plot_xaxis, im_in1.ny());
+ ezplot.addCurve (v2[opt_columnPlot], plot_xaxis, im_in2.ny());
cout << "Press enter to continue" << flush;
- fgets(str, sizeof(str), stdin);
- sgp2_close (sgp2_get_active_win());
+ cio_kb_getc();
#endif
}
v2Row[i] = v2[opt_rowPlot][i];
#if HAVE_SGP
-#if 0
-#else
- ezset ("clear.");
- ezset ("xticks major 5.");
- ezset ("xlabel Column");
- ezset ("ylabel Pixel");
- ezset ("curves 2");
- ezset ("box.");
- ezset ("grid.");
- ezplot (v1Row, plot_xaxis, im_in1.nx());
- ezplot (v2Row, plot_xaxis, im_in2.nx());
-#endif
- char str[256];
+ SGPDriver driver ("Column Plot");
+ SGP sgp (driver);
+ EZPlot ezplot (sgp);
+ ezplot.ezset ("clear.");
+ ezplot.ezset ("xticks major 5.");
+ ezplot.ezset ("xlabel Column");
+ ezplot.ezset ("ylabel Pixel");
+ ezplot.ezset ("curves 2");
+ ezplot.ezset ("box.");
+ ezplot.ezset ("grid.");
+ ezplot.addCurve (v1Row, plot_xaxis, im_in1.nx());
+ ezplot.addCurve (v2Row, plot_xaxis, im_in2.nx());
cout << "Press enter to continue" << flush;
- fgets(str, sizeof(str), stdin);
- sgp2_close (sgp2_get_active_win());
+ cio_kb_getc();
#endif
}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: if2img.cpp,v 1.1 2000/07/13 07:01:35 kevin Exp $
+** $Id: if2img.cpp,v 1.2 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
im.displayScaling (opt_scale, densmin, densmax);
cout << "Press enter to continue\n";
cio_kb_getc();
- sgp2_close(sgp2_get_active_win());
#endif
}
else
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: phm2pj.cpp,v 1.4 2000/07/23 01:49:03 kevin Exp $
+** $Id: phm2pj.cpp,v 1.5 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#else
Projections pjGlobal (scanner);
- scanner.collectProjections (pjGlobal, phm, 0, opt_trace);
+
+ SGPDriver* pSGPDriver = NULL;
+ SGP* pSGP = NULL;
+
+ if (opt_trace >= TRACE_PHM) {
+ pSGPDriver = new SGPDriver ("phm2pj");
+ pSGP = new SGP (*pSGPDriver);
+ }
+
+ scanner.collectProjections (pjGlobal, phm, 0, opt_trace, pSGP);
+
+ if (opt_trace >= TRACE_PHM) {
+ cout << "Press enter to continue\n";
+ cio_kb_getc();
+ delete pSGP; pSGP = NULL;
+ delete pSGPDriver; pSGPDriver = NULL;
+ }
+
#endif
#ifdef HAVE_MPI
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: pjrec.cpp,v 1.5 2000/07/22 15:45:33 kevin Exp $
+** $Id: pjrec.cpp,v 1.6 2000/07/28 08:28:08 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#endif
cout << " --zeropad n Set zeropad level (default = 0)\n";
cout << " set n to number of powers to two to pad\n";
+ cout << " --frequency-filter Set type of frequency filter\n";
+ cout << " direct Use direct frequency filter\n";
+ cout << " ifourier Use inverse fourier transform of spatial filter\n";
cout << " --backproj Backprojection Method" << endl;
cout << " trig Trigometric functions at every point" << endl;
cout << " table Trigometric functions with precalculated table" << endl;