r162: *** empty log message ***
authorKevin M. Rosenberg <kevin@rosenberg.net>
Fri, 28 Jul 2000 08:28:08 +0000 (08:28 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Fri, 28 Jul 2000 08:28:08 +0000 (08:28 +0000)
29 files changed:
ChangeLog
NEWS
doc/Makefile.am
doc/ctsim.tex
include/Makefile.am
include/ezplot.h
include/phantom.h
include/scanner.h
include/sgp.h
include/transformmatrix.h [new file with mode: 0644]
libctgraphics/Makefile.am
libctgraphics/ezplot.cpp
libctgraphics/ezset.cpp
libctgraphics/ezsupport.cpp
libctgraphics/sgp.cpp
libctgraphics/sgpdriver.cpp [deleted file]
libctgraphics/sgptext.cpp [deleted file]
libctgraphics/transformmatrix.cpp [new file with mode: 0644]
libctsim/phantom.cpp
libctsim/projections.cpp
libctsim/scanner.cpp
man/Makefile.am
src/dialogs.h
src/views.cpp
src/views.h
tools/if-2.cpp
tools/if2img.cpp
tools/phm2pj.cpp
tools/pjrec.cpp

index c824c4d66432f68fa9c346e55306af76e19543ec..3609c14562e6a7b1087c66564e3fb6bb37a47c44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 2.0.0-b7 - 7/25/00
    Finished support for dmallocxx library
    Fixed bug in SignalFilter::convertFilterMethodNameToID()
 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 
        
 2.0.0-b6 - 7/22/00
    ctsim program: improved initial size and scroll area for image 
diff --git a/NEWS b/NEWS
index 5048b7920c2ca69ddf562c2fe942b822b3a961be..8baa49358e7855af1567e3263bf19624d91af104 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,8 +3,7 @@ Version 2.0 of CTSim is near completion!
 
 New Features of CTSim version 2.0:
 
 
 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)
 
 - Integrated G2 library for graphical display from command line tools
   (UNIX only)
index d41b2399dc20e4e8e47b6c624896edeeda52b4b0..29d4c6b6283f77bc96c29bd5d167aa738ead7fd6 100644 (file)
@@ -1,4 +1,6 @@
-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
 
 dvi: ctsim.tex
        latex ctsim.tex
index 8f89aac2e5af30a1d3abffc3faeafdc08698037d..bb38e0a1c920f3236b4a6981593a4d07db33497d 100644 (file)
@@ -1,29 +1,65 @@
-\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} 
 \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} 
 \date{July 2000} 
-\begin{document} 
 \maketitle 
 
 \chapter{Introduction} 
 \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}
 \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}
 
 \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}
 \subsection{phm2pj}
-\begin{description}
 Converts a phantom object to a set of projections
 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.
 
 {\tt phm2pj} simulates the process of collection of X-Ray projection data
 such as collected by a CT scanner.
@@ -31,12 +67,9 @@ such as collected by a CT scanner.
 \subsection{pjrec}
 
 \subsection{phm2if}
 \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} 
 
 \end{document} 
index 15c2b696a335d5854396e34496e0ad1fbb731850..28950d336134db6c4f71149b15974c2c704995da 100644 (file)
@@ -1,4 +1,5 @@
-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
+
 
 
 
 
 
 
index 30fe4e56b501f32325cf0d69ba912576ebbeb469..06601db5515413c006fab7e8a9b21121bff585e6 100644 (file)
@@ -1,8 +1,13 @@
 /*****************************************************************************
 /*****************************************************************************
+** FILE IDENTIFICATION
+**
+**         Name:  ezplot.h
+**         Purpose: Header file for EZplot library
+**
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
 ******************************************************************************/
 
 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************/
 
-/*----------------------------------------------------------------------*/
-/*                             EZPLOT                                  */
-/*                                                                     */
-/*----------------------------------------------------------------------*/
 
 #ifndef __H_EZPLOT
 #define __H_EZPLOT
 
 
 #ifndef __H_EZPLOT
 #define __H_EZPLOT
 
-
 #include <stdio.h>
 #include <stddef.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <ctype.h>
 #include "ctsupport.h"
 #include "sgp.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                                  */
 
 /*----------------------------------------------------------------------*/
 /*                     Codes from LEX                                  */
@@ -117,8 +291,6 @@ struct ezp_curve_st {
 #define S_CLEAR                -61
 #define S_STORE                -62
 #define S_RESTORE      -63
 #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_AMARK                -66
 #define S_NO           -67
 #define S_INTERACTIVE  -68
@@ -136,202 +308,7 @@ struct ezp_curve_st {
 #define S_LEGENDBOX    -107
 #define S_TAG          -108
 
 #define S_LEGENDBOX    -107
 #define S_TAG          -108
 
-#define S_EPSON                -110
-#define S_CRT          -111
-
 #define S_TEXTSIZE     -120
 #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
 
 
 #endif
index 416b83301799c8078375a8ee31763fb51b1a43e0..ae6a2350d845ded0409afc111ae36ab8f6009fc4 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -30,8 +30,6 @@
 
 #include <slist>
 #include "ctsupport.h"
 
 #include <slist>
 #include "ctsupport.h"
-#include "backprojectors.h"
-class ImageFile;
 
 using namespace std;
 
 
 using namespace std;
 
@@ -129,6 +127,8 @@ typedef enum {
 // Phantom Class Declaration
 //////////////////////////////////////////////////////
 
 // Phantom Class Declaration
 //////////////////////////////////////////////////////
 
+class SGP;
+class ImageFile;
 class Phantom
 {
  public:
 class Phantom
 {
  public:
@@ -171,7 +171,7 @@ class Phantom
 
 #if HAVE_SGP
     void show () const;
 
 #if HAVE_SGP
     void show () const;
-    void draw () const;
+    void draw (SGP& sgp) const;
 #endif
     
     void addStdHerman ();
 #endif
     
     void addStdHerman ();
index c446280fb799ef4c107bf503fac2ac7e7fabfa91..0ab132c0c79633e020b5f6d01841f98a44897e6c 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **
 **  This program is free software; you can redistribute it and/or modify
 #ifndef SCANNER_H
 #define SCANNER_H
 
 #ifndef SCANNER_H
 #define SCANNER_H
 
+#include "trace.h"
+
 class Projections;
 class Phantom;
 class PhantomElement;
 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
 
 // Projections are collected along an array of ndet detectors.  The data
 // for these detectors is stored in the class DetectorArray
@@ -74,7 +77,7 @@ class Scanner
   Scanner (const Phantom& phm, const char* const geometryName, int nDet, int nView, int nSample, const double rot_anglen);
   ~Scanner();
   
   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);
 
 
   void setNView (int nView);
 
@@ -119,11 +122,11 @@ class Scanner
   static const int s_iGeometryCount;
   static const int N_EXTRA_DETECTORS=4;           /* Number of extra detectors widths when calculating detlen */
 
   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, ...);
 
 
   void traceShowParam (const char *label, const char *fmt, int row, int color, ...);
 
index 15f0c35a567c3e7ccd20a80d115b2a13ccca458d..b2d31eec0fbf7818e2d1728a3ac1deba444337fc 100644 (file)
@@ -1,8 +1,15 @@
 /*****************************************************************************
 /*****************************************************************************
+** 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
 **
 **  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
 **
 **  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
 ******************************************************************************/
 
 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************/
 
-/*----------------------------------------------------------------------*/
-/*                Standard Graphics Package Header File                */
-/*----------------------------------------------------------------------*/
-
 #ifndef __H_SGP
 #define __H_SGP
 
 #ifndef __H_SGP
 #define __H_SGP
 
 #include "config.h"
 #endif
 
 #include "config.h"
 #endif
 
-#include "ctsupport.h"
+#include "transformmatrix.h"
+
+#ifdef HAVE_WXWINDOWS
+#include <wx/wx.h>
+#endif
 
 #if HAVE_G2_H
 extern "C" {
 
 #if HAVE_G2_H
 extern "C" {
@@ -38,225 +45,168 @@ extern "C" {
 }
 #endif
 
 }
 #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
 
 
 #endif
diff --git a/include/transformmatrix.h b/include/transformmatrix.h
new file mode 100644 (file)
index 0000000..5274b30
--- /dev/null
@@ -0,0 +1,60 @@
+/*****************************************************************************
+** 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
index 5daeb60c880a9b064acb0a57cea1a9f6edbff3e9..a7f9f275e9a9cc06d7f91cf013ad7d77fc12195b 100644 (file)
@@ -1,5 +1,5 @@
 noinst_LIBRARIES = libctgraphics.a
 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
 
 INCLUDES=@my_includes@
 EXTRA_DIST=Makefile.nt
 
index 7b7bb55e8c4e6b373db89d1a1731af86222f5ce4..6ffd0b05b2f2fc9bc2b9f090b64987dd3cd26774 100644 (file)
@@ -6,7 +6,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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 "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];
 
 {
   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);
 }
 
 
 }
 
 
@@ -195,731 +204,760 @@ ezplot (const double x[], const double y[], int num)
  *   EZPLOT() only
  *
  * CALLS
  *   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
     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
 }
 
 
 /* NAME
- *   drawaxis                  INTERNAL routine to draw axis & label them
+ *   drawAxes                  INTERNAL routine to draw axis & label them
  *
  * SYNOPSIS
  *
  * 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();
-}
index 7b95e30dcddb2f32e23a551696dbb067e0c59a9f..662351306231d995146a163b8c2a0e63cf6dd3c4 100644 (file)
 /*****************************************************************************
 /*****************************************************************************
-**  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"
 
 
 #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 
 
 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";
 }
 
 /*----------------------------------------------------------------------*/
 }
 
 /*----------------------------------------------------------------------*/
@@ -561,104 +414,98 @@ bad_option (char *opt)
 /*----------------------------------------------------------------------*/
 
 static struct key {
 /*----------------------------------------------------------------------*/
 
 static struct key {
-       char *keyword;
-       int code;
+  char *keyword;
+  int code;
 } keytab[] = {
 } keytab[] = {
-       {"solid",       S_SOLID},
-       {"dash",                S_DASH},
-       {"noline",      S_NOLINE},
+  {"solid",    S_SOLID},
+    {"dash",           S_DASH},
+      {"noline",       S_NOLINE},
        {"black",       S_BLACK},
        {"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 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)
 {
   for (unsigned int i = 0; i < NKEYS; i++)
     if (pol_install(keytab[i].keyword, keytab[i].code) == FALSE)
index f788b2e75965b218f29fdabeff03021053dd490c..a6a2cd5c38e1147451288b44bfa7e0e5d082947a 100644 (file)
@@ -2,7 +2,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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 "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);
-}
index 8a5400fc00e620ffbbc802a558a1ed2dd47afe98..e1a1142e8448a476252010fe899b8cb4614eb8c9 100644 (file)
@@ -1,13 +1,13 @@
 /*****************************************************************************
 ** FILE IDENTIFICATION
 **
 /*****************************************************************************
 ** 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
 **
 **     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
 **
 **  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"
 
 
 #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
 }
 
 
 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
 }
 
 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 
 
 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
 
 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
 
 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
 
 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
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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
 
 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 
 }
 
 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 
 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 
 
 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
 
 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 
 
 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 
 
 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 
 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 
 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 
 }
 
 
 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 
 }
 
 
 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 
+};
diff --git a/libctgraphics/sgpdriver.cpp b/libctgraphics/sgpdriver.cpp
deleted file mode 100644 (file)
index 76e08ef..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-/*****************************************************************************
-**  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 */
-}
diff --git a/libctgraphics/sgptext.cpp b/libctgraphics/sgptext.cpp
deleted file mode 100644 (file)
index 9657a07..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*****************************************************************************
-**  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)
-{
-}
diff --git a/libctgraphics/transformmatrix.cpp b/libctgraphics/transformmatrix.cpp
new file mode 100644 (file)
index 0000000..12c5192
--- /dev/null
@@ -0,0 +1,159 @@
+/*****************************************************************************
+** 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);
+}
index 2063683d0675d8532a2a31feb635c4ecf8e3a82a..f8b1278cef478037b28352f45537e8e8185b22ce 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -306,29 +306,12 @@ Phantom::print () const
 void 
 Phantom::show () const
 {
 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
 
 }
 #endif
 
@@ -342,10 +325,22 @@ Phantom::show () const
 
 #ifdef HAVE_SGP
 void 
 
 #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++)
   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
 
 }
 #endif
 
index a29d7c5a6ca967ab5e569349a46acc0ef2082797..35d8418a070edd3029684246f8e8eea645d1ffff 100644 (file)
@@ -8,7 +8,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -515,7 +515,6 @@ Projections::reconstruct (ImageFile& im, const char* const filterName, double fi
     cout << "Reconstruct: filter="<<filterName<< ", interp="<<interpName<<", backproject="<<backprojectName<<endl;
 
 #if HAVE_SGP
     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 nVecFilter = filter.getNFilterPoints();
   double plot_xaxis [nVecFilter];                      // array for plotting 
 
@@ -523,14 +522,17 @@ Projections::reconstruct (ImageFile& im, const char* const filterName, double fi
     int i;
     double f;
     double filterInc = filter.getFilterIncrement();
     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()) {
       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 ();
       cio_put_str ("Press any key to continue");
       cio_kb_getc ();
-      sgp2_close (gid);
     }
   }
   if (trace >= TRACE_TEXT) {
     }
   }
   if (trace >= TRACE_TEXT) {
@@ -555,26 +557,30 @@ Projections::reconstruct (ImageFile& im, const char* const filterName, double fi
 
 #ifdef HAVE_SGP
     if (trace >= TRACE_PLOT)  {
 
 #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
 
     }
 #endif  //HAVE_SGP
 
@@ -597,7 +603,6 @@ Projections::reconstruct (ImageFile& im, const char* const filterName, double fi
       char str[256];
       printf ("Do you want to exit with current pic (y/n) -- ");
       fgets(str, sizeof(str), stdin);
       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;
       }
       if (tolower(str[0]) == 'y') {
        break;
       }
index ae665f207894f1e43e790c577969029a446b7443..d4a398ef995006d1e1eca15f9ecec17a40482aaf 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -180,7 +180,7 @@ Scanner::convertGeometryNameToID (const char* const geomName)
 */
 
 void
 */
 
 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;
 {
   GRFMTX_2D rotmtx_initial, temp;
   GRFMTX_2D rotmtx_incr;
@@ -201,23 +201,21 @@ Scanner::collectProjections (Projections& proj, const Phantom& phm, const int st
   m_trace = trace;
 
 #ifdef HAVE_SGP 
   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 */
     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
 #if RADIUS
-    sgp2_draw_circle (m_phmLen / 2);
+    pSGP->drawCircle (m_phmLen / 2);
 #else
 #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
                    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, " ");
     //      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, " ");
@@ -229,10 +227,10 @@ Scanner::collectProjections (Projections& proj, const Phantom& phm, const int st
     traceShowParam ("Num Views    :", "%5d", RAYSUM_TRACE_ROW_NVIEW, C_LTRED, proj.nView());
     traceShowParam ("Samples / Ray:", "%5d", RAYSUM_TRACE_ROW_SAMPLES, C_LTRED, m_nSample);
     
     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
 
   }
 #endif
 
@@ -261,26 +259,26 @@ Scanner::collectProjections (Projections& proj, const Phantom& phm, const int st
       DetectorArray& detArray = proj.getDetectorArray( iview );
 
 #ifdef HAVE_SGP
       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);
            
     }
 #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
     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);
       //       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 
     }
 #endif
     xform_mtx2 (rotmtx_incr, xd1, yd1);         // rotate detector endpoints 
@@ -315,7 +313,7 @@ Scanner::collectProjections (Projections& proj, const Phantom& phm, const int st
  */
 
 void 
  */
 
 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 ddx = (xd2 - xd1) / detArray.nDet();  // change in coords between detectors
   double ddy = (yd2 - yd1) / detArray.nDet();
@@ -349,20 +347,20 @@ Scanner::projectSingleView (const Phantom& phm, DetectorArray& detArray, const d
       double sum = 0.0;
       for (unsigned int i = 0; i < m_nSample; i++) {
 #ifdef HAVE_SGP
       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
        }
 #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)
          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;
        }
 #endif
        xd += ddx2;
@@ -393,7 +391,7 @@ Scanner::traceShowParam (const char *label, const char *fmt, int row, int color,
   vsnprintf (s, sizeof(s), fmt, arg);
   //  cio_set_text_clr (color, 0);
   cio_put_str (s);
   vsnprintf (s, sizeof(s), fmt, arg);
   //  cio_set_text_clr (color, 0);
   cio_put_str (s);
-
+  cout << "\n";
   va_end(arg);
 }
 
   va_end(arg);
 }
 
@@ -409,12 +407,12 @@ Scanner::traceShowParam (const char *label, const char *fmt, int row, int color,
  */
 
 double 
  */
 
 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++)
 {
   // 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);
 }
 
   return (rsum);
 }
@@ -431,7 +429,7 @@ Scanner::projectSingleLine (const Phantom& phm, const double x1, const double y1
  */
 
 double 
  */
 
 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)
 {
   if (! pelem.clipLineWorldCoords (x1, y1, x2, y2)) {
     if (m_trace == TRACE_CLIPPING)
@@ -440,12 +438,12 @@ Scanner::projectLineAgainstPElem (const PhantomElement& pelem, double x1, double
   }
 
 #ifdef HAVE_SGP
   }
 
 #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);
     cio_tone (8000., 0.05);
-    sgp2_move_abs (x1, y1);
-    sgp2_line_abs (x2, y2);
+    pSGP->moveAbs (x1, y1);
+    pSGP->lineAbs (x2, y2);
   }
 #endif
 
   }
 #endif
 
index 18b5ae46f5e0538d7066b6c0e77bd5c72e0540fa..825aa32dd5495632bb074f7d9afcdf8ed64f87f2 100644 (file)
@@ -1,3 +1,2 @@
 man_MANS=ctrec.1 phm2rs.1 phm2if.1 if2img.1 ifinfo.1 if-1.1
 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) 
index e942d3318fcae7c034b8d776286e8d032154dbed..6dcc2988cd5f5379114f045b8a741b67d64708e4 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -132,6 +132,7 @@ class DialogGetProjectionParameters : public wxDialog
 };
 
 
 };
 
 
+#include "backprojectors.h"
 class DialogGetReconstructionParameters : public wxDialog
 {
  public:
 class DialogGetReconstructionParameters : public wxDialog
 {
  public:
index 536db90ca0cc6c0e88b401b27c68d13f220565df..8ec1df2bff80bf1e17529210fd503e4bdf1e312b 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -341,7 +341,7 @@ ImageFileView::OnClose (bool deleteWindow)
 // PhantomCanvas
 
 PhantomCanvas::PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style)
 // 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 = v;
 }
@@ -353,6 +353,7 @@ PhantomCanvas::OnDraw(wxDC& dc)
         m_pView->OnDraw(& dc);
 }
 
         m_pView->OnDraw(& dc);
 }
 
+
 // PhantomView
 
 IMPLEMENT_DYNAMIC_CLASS(PhantomView, wxView)
 // PhantomView
 
 IMPLEMENT_DYNAMIC_CLASS(PhantomView, wxView)
@@ -518,15 +519,8 @@ PhantomView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
 
     m_frame->Show(true);
     Activate(true);
 
     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;
 }
 
 
 }
 
 
@@ -560,6 +554,16 @@ PhantomView::OnClose (bool deleteWindow)
     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
 
 
 // ProjectionCanvas
 
index 43751338e6ea68c031241c70d379154c114335ee..3c29c77cf385dc7e6f4d3bd77dc1269cd18a12d8 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -144,9 +144,9 @@ public:
     virtual ~PhantomView(void);
 
     bool OnCreate(wxDocument *doc, long flags);
     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 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);
     void OnProperties (wxCommandEvent& event);
     void OnRasterize (wxCommandEvent& event);
     void OnProjections (wxCommandEvent& event);
@@ -157,12 +157,13 @@ public:
     DECLARE_EVENT_TABLE()
 };
 
     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);
 {
 public:
     PhantomView* m_pView;
     
     PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style);
+
     virtual void OnDraw(wxDC& dc);
 
 };
     virtual void OnDraw(wxDC& dc);
 
 };
index 525330ea568fcf0813da766d724ba2ad412a21b4..2558360f32341352d12a4ab612fbc93ae4405d76 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -228,22 +228,20 @@ if2_main (int argc, char *const argv[])
     for (int i = 0; i < nx; i++)
       plot_xaxis[i] = i;
 #if HAVE_SGP
     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;
     cout << "Press enter to continue" << flush;
-    fgets(str, sizeof(str), stdin);
-    sgp2_close (sgp2_get_active_win());
+    cio_kb_getc();
 #endif
   }
 
 #endif
   }
 
@@ -263,22 +261,20 @@ if2_main (int argc, char *const argv[])
       v2Row[i] = v2[opt_rowPlot][i];
 
 #if HAVE_SGP
       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;
     cout << "Press enter to continue" << flush;
-    fgets(str, sizeof(str), stdin);
-    sgp2_close (sgp2_get_active_win());
+    cio_kb_getc();
 #endif
   }
 
 #endif
   }
 
index b00c1775f9f03093c8864d66a505b03ce53bc01e..fcf214de49192d634a5ba78c3f21709e1c1e2e7a 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -357,7 +357,6 @@ if2img_main (int argc, char *const argv[])
     im.displayScaling (opt_scale, densmin, densmax);
     cout << "Press enter to continue\n";
     cio_kb_getc();
     im.displayScaling (opt_scale, densmin, densmax);
     cout << "Press enter to continue\n";
     cio_kb_getc();
-    sgp2_close(sgp2_get_active_win());
 #endif
   }
   else
 #endif
   }
   else
index 46246117a43f674e00e9e2f154d951c0a9b1a289..4c12ecf6f1e1d037bafdd731dc1821757ad4467f 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -285,7 +285,24 @@ phm2pj_main (int argc, char* argv[])
 
 #else
   Projections pjGlobal (scanner);
 
 #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
 #endif
   
 #ifdef HAVE_MPI
index 03ee9e874520770e76e160dc5673a739c0165708..1cc9bd292117141083cbef06a53b40712dcc4d52 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
 **  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
 **
 **  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
@@ -89,6 +89,9 @@ pjrec_usage (const char *program)
 #endif
   cout << "  --zeropad n   Set zeropad level (default = 0)\n";
   cout << "                set n to number of powers to two to pad\n";
 #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;
   cout << "  --backproj    Backprojection Method" << endl;
   cout << "    trig        Trigometric functions at every point" << endl;
   cout << "    table       Trigometric functions with precalculated table" << endl;