X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=libctgraphics%2Fsgp.cpp;h=9757fe9fb03449e911e7d0fcee351488be47540a;hp=ec6b89d4a936dcff1fe103a2a362232525bb4b15;hb=f7ee98f7d964ed361068179f0e7ea4475ed1abdf;hpb=ed576a069b0ba9de2e9153707012eba620ac606e diff --git a/libctgraphics/sgp.cpp b/libctgraphics/sgp.cpp index ec6b89d..9757fe9 100644 --- a/libctgraphics/sgp.cpp +++ b/libctgraphics/sgp.cpp @@ -1,13 +1,13 @@ /***************************************************************************** ** FILE IDENTIFICATION ** -** Name: sgp.cpp Simple Graphics Package -** Programmer: Kevin Rosenberg +** Name: sgp.cpp Simple Graphics Package +** Programmer: Kevin Rosenberg ** ** This is part of the CTSim program -** Copyright (C) 1983-2000 Kevin Rosenberg +** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: sgp.cpp,v 1.27 2001/01/12 21:53:27 kevin Exp $ +** $Id$ ** ** 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 @@ -29,27 +29,27 @@ #include "sgp.h" -RGBColor SGP::s_aRGBColor[] = -{ - RGBColor (0, 0, 0), - RGBColor (0, 0, 128), - RGBColor (0, 128, 0), - RGBColor (0, 128, 128), - RGBColor (128, 0, 0), - RGBColor (128, 0, 128), - RGBColor (128, 128, 0), - RGBColor (80, 80, 80), - RGBColor (160, 160, 160), - RGBColor (0, 0, 255), - RGBColor (0, 255, 0), - RGBColor (0, 255, 255), - RGBColor (255, 0, 0), - RGBColor (255, 0, 255), - RGBColor (255, 255, 0), - RGBColor (255, 255, 255), +SGP_RGBColor SGP::s_aRGBColor[] = +{ + SGP_RGBColor (0, 0, 0), + SGP_RGBColor (0, 0, 128), + SGP_RGBColor (0, 128, 0), + SGP_RGBColor (0, 128, 128), + SGP_RGBColor (128, 0, 0), + SGP_RGBColor (128, 0, 128), + SGP_RGBColor (128, 128, 0), + SGP_RGBColor (80, 80, 80), + SGP_RGBColor (160, 160, 160), + SGP_RGBColor (0, 0, 255), + SGP_RGBColor (0, 255, 0), + SGP_RGBColor (0, 255, 255), + SGP_RGBColor (255, 0, 0), + SGP_RGBColor (255, 0, 255), + SGP_RGBColor (255, 255, 0), + SGP_RGBColor (255, 255, 255), }; -int SGP::s_iRGBColorCount = sizeof(s_aRGBColor) / sizeof(class RGBColor); +int SGP::s_iRGBColorCount = sizeof(s_aRGBColor) / sizeof(class SGP_RGBColor); #ifdef HAVE_WXWINDOWS SGPDriver::SGPDriver (wxDC* pDC, int xsize, int ysize) @@ -71,7 +71,7 @@ SGPDriver::SGPDriver (const char* szWinTitle, int xsize, int ysize) SGPDriver::~SGPDriver () { #if HAVE_G2_H - if (isG2()) + if (isG2()) g2_close (m_idG2); #endif } @@ -99,11 +99,12 @@ SGP::SGP (const SGPDriver& driver) setViewport (0., 0., 1., 1.); moveAbs (0., 0.); stylusNDC (0., 0., false); - + setTextAngle (0.); setTextPointSize (12); setColor (C_BLACK); setLineStyle (LS_SOLID); + setMarker (MARKER_POINT); } @@ -129,7 +130,7 @@ SGP::initFromDC (wxDC* pDC) m_driver.idWX()->SetFont (*m_pFont); double dTestCharHeight = m_driver.idWX()->GetCharHeight(); m_dPointsPerPixel = iTestPointSize / dTestCharHeight; - m_driver.idWX()->SetBackground (*wxWHITE_BRUSH); + m_driver.idWX()->SetBackground (*wxWHITE_BRUSH); } } #endif @@ -170,18 +171,45 @@ SGP::stylusNDC (double x, double y, bool beam) void SGP::markerNDC (double x, double y) { + int xp = static_cast(x * (m_iPhysicalXSize - 1) + 0.5); + int yp = static_cast(y * (m_iPhysicalYSize - 1) + 0.5); + if (m_driver.isWX()) + yp = m_iPhysicalYSize - yp; + +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + m_driver.idWX()->DrawPoint (xp, yp); + m_driver.idWX()->DrawPoint (xp-1, yp-1); + m_driver.idWX()->DrawPoint (xp+1, yp+1); + m_driver.idWX()->DrawPoint (xp+1, yp-1); + m_driver.idWX()->DrawPoint (xp-1, yp+1); + } +#endif + m_iCurrentPhysicalX = xp; + m_iCurrentPhysicalY = yp; } void SGP::pointNDC (double x, double y) { + int xp = static_cast(x * (m_iPhysicalXSize - 1) + 0.5); + int yp = static_cast(y * (m_iPhysicalYSize - 1) + 0.5); + if (m_driver.isWX()) + yp = m_iPhysicalYSize - yp; + +#if HAVE_WXWINDOWS + if (m_driver.isWX()) + m_driver.idWX()->DrawPoint (xp, yp); +#endif + m_iCurrentPhysicalX = xp; + m_iCurrentPhysicalY = yp; } // NAME // clear Clear Window -void +void SGP::eraseWindow () { #if HAVE_G2_H @@ -190,25 +218,25 @@ SGP::eraseWindow () #endif #if HAVE_WXWINDOWS if (m_driver.isWX()) { - wxBrush brushWhite; - brushWhite.SetColour(255,255,255); - m_driver.idWX()->SetBackground(brushWhite); - m_driver.idWX()->Clear(); - m_driver.idWX()->SetBackground(wxNullBrush); + wxBrush brushWhite; + brushWhite.SetColour(255,255,255); + m_driver.idWX()->SetBackground(brushWhite); + m_driver.idWX()->Clear(); + m_driver.idWX()->SetBackground(wxNullBrush); #if 1 - wxPen pen; - pen.SetColour(255,255,255); - m_driver.idWX()->SetBrush (brushWhite); - m_driver.idWX()->DrawRectangle (0, 0, m_iPhysicalXSize, m_iPhysicalYSize); - m_driver.idWX()->SetBrush (wxNullBrush); + wxPen pen; + pen.SetColour(255,255,255); + m_driver.idWX()->SetBrush (brushWhite); + m_driver.idWX()->DrawRectangle (0, 0, m_iPhysicalXSize, m_iPhysicalYSize); + m_driver.idWX()->SetBrush (wxNullBrush); #endif } #endif } // NAME -// sgp2_window Set window in world coordinates - +// sgp2_window Set window in world coordinates + void SGP::setWindow (double xmin, double ymin, double xmax, double ymax) @@ -217,7 +245,7 @@ SGP::setWindow (double xmin, double ymin, double xmax, double ymax) sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_window]"); return; } - + xw_min = xmin; yw_min = ymin; xw_max = xmax; @@ -227,7 +255,7 @@ SGP::setWindow (double xmin, double ymin, double xmax, double ymax) // NAME -// sgp2_viewport Set viewport in NDC +// sgp2_viewport Set viewport in NDC void SGP::setViewport (double xmin, double ymin, double xmax, double ymax) @@ -236,14 +264,14 @@ SGP::setViewport (double xmin, double ymin, double xmax, double ymax) sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_viewport]"); return; } - + xv_min = xmin; yv_min = ymin; xv_max = xmax; yv_max = ymax; m_bRecalcTransform = true; - - viewNDC[0] = xmin; // Array for clip_rect() + + viewNDC[0] = xmin; // Array for clip_rect() viewNDC[1] = ymin; viewNDC[2] = xmax; viewNDC[3] = ymax; @@ -269,7 +297,7 @@ SGP::getWindow (double& xmin, double& ymin, double& xmax, double& ymax) // NAME -// frameViewport draw box around viewport +// frameViewport draw box around viewport void SGP::frameViewport (void) @@ -298,7 +326,7 @@ SGP::setTextColor (int iFGcolor, int iBGcolor) #endif } -void +void SGP::setColor (int icol) { if (icol >= 0 && icol < s_iRGBColorCount) { @@ -318,7 +346,7 @@ SGP::setColor (int icol) } } -void +void SGP::setPenWidth (int iWidth) { if (iWidth >= 0) { @@ -395,14 +423,15 @@ SGP::setRasterOp (int ro) void -SGP::setMarker (int idMarke, int iColor) +SGP::setMarker (int idMarker) { + m_iMarker = idMarker; } //============================================================== -// set line style. Pass 16 bit repeating pattern +// set line style. Pass 16 bit repeating pattern //============================================================== -void +void SGP::setLineStyle (int style) { m_iLinestyle = style; @@ -438,10 +467,10 @@ SGP::setLineStyle (int style) } //============================================================== -// absolute draw to +// absolute draw to //*============================================================== -void +void SGP::lineAbs (double x, double y) { if (m_bRecalcTransform) @@ -454,30 +483,30 @@ SGP::lineAbs (double x, double y) double x2 = x; double y2 = y; mc_to_ndc.transformPoint (&x2, &y2); - - if (clip_rect (x1, y1, x2, y2, viewNDC) == true) { // clip to viewport + + if (clip_rect (x1, y1, x2, y2, viewNDC) == true) { // clip to viewport stylusNDC (x1, y1, false); // move to first point - stylusNDC (x2, y2, true); // draw to second point + stylusNDC (x2, y2, true); // draw to second point } m_dCurrentWorldX = x; m_dCurrentWorldY = y; } -void +void SGP::moveAbs (double x, double y) { m_dCurrentWorldX = x; - m_dCurrentWorldY = y; /* moves are not clipped */ + m_dCurrentWorldY = y; /* moves are not clipped */ } -void +void SGP::lineRel (double x, double y) { lineAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); } -void +void SGP::moveRel (double x, double y) { moveAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); @@ -541,9 +570,8 @@ SGP::getTextExtent (const char* szText, double* worldW, double* worldH) { #if HAVE_WXWINDOWS if (m_driver.isWX()) { - wxString sText (szText); wxCoord deviceW, deviceH; - m_driver.idWX()->GetTextExtent (sText, &deviceW, &deviceH); + m_driver.idWX()->GetTextExtent (wxConvCurrent->cMB2WC(szText), &deviceW, &deviceH); if (m_dTextAngle == 90 || m_dTextAngle == -90) { wxCoord temp = deviceW; deviceW = deviceH; @@ -564,7 +592,7 @@ SGP::getCharHeight () if (m_driver.isWX()) { dHeight = m_driver.idWX()->GetCharHeight(); dHeight /= static_cast(m_iPhysicalYSize); - dHeight /= (yv_max - yv_min); // scale to viewport; + dHeight /= (yv_max - yv_min); // scale to viewport; } #endif dHeight *= (yw_max - yw_min); // scale to world coordinates @@ -580,7 +608,7 @@ SGP::getCharWidth () if (m_driver.isWX()) { dWidth = m_driver.idWX()->GetCharWidth(); dWidth /= static_cast(m_iPhysicalXSize); - dWidth /= (xv_max - xv_min); // scale to viewport + dWidth /= (xv_max - xv_min); // scale to viewport } #endif dWidth *= (xw_max - xw_min); //scale to world coordinates @@ -593,7 +621,7 @@ SGP::setTextAngle (double angle) m_dTextAngle = convertRadiansToDegrees(angle); } -void +void SGP::polylineAbs (double x[], double y[], int n) { if (m_bRecalcTransform) @@ -604,16 +632,16 @@ SGP::polylineAbs (double x[], double y[], int n) 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 + 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, false); stylusNDC (xt, yt, true); } - + for (int i = 2; i < n; i++) { - x1 = x2; y1 = y2; // NDC endpoint of last line + x1 = x2; y1 = y2; // NDC endpoint of last line x2 = x[i]; y2 = y[i]; mc_to_ndc.transformPoint (&x2, &y2); xt = x2; @@ -626,7 +654,7 @@ SGP::polylineAbs (double x[], double y[], int n) } -void +void SGP::markerAbs (double x, double y) { if (m_bRecalcTransform) @@ -635,21 +663,20 @@ SGP::markerAbs (double x, double y) double xndc = x; double yndc = y; mc_to_ndc.transformPoint (&xndc, &yndc); - markerNDC (xndc, yndc); - stylusNDC (xndc, yndc, false); // move to location + markerNDC (xndc, yndc); m_dCurrentWorldX = x; m_dCurrentWorldY = y; } -void +void SGP::markerRel (double x, double y) { markerAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); } -void +void SGP::pointAbs (double x, double y) { if (m_bRecalcTransform) @@ -657,13 +684,12 @@ SGP::pointAbs (double x, double y) 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; } -void +void SGP::pointRel (double x, double y) { pointAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); @@ -676,7 +702,7 @@ SGP::drawText (const std::string& rsMessage) drawText (rsMessage.c_str()); } -void +void SGP::drawText (const char *pszMessage) { if (m_bRecalcTransform) @@ -686,7 +712,7 @@ SGP::drawText (const char *pszMessage) double yndc = m_dCurrentWorldY; mc_to_ndc.transformPoint (&xndc, &yndc); - stylusNDC (xndc, yndc, false); // move to location + stylusNDC (xndc, yndc, false); // move to location #if HAVE_G2_H if (m_driver.isG2()) { @@ -695,20 +721,19 @@ SGP::drawText (const char *pszMessage) #endif #if HAVE_WXWINDOWS if (m_driver.isWX()) { - wxString str (pszMessage); - m_driver.idWX()->DrawRotatedText (str, m_iCurrentPhysicalX, m_iCurrentPhysicalY, m_dTextAngle); + m_driver.idWX()->DrawRotatedText (wxConvCurrent->cMB2WC(pszMessage), m_iCurrentPhysicalX, m_iCurrentPhysicalY, m_dTextAngle); } #endif } // NAME -// drawRect Draw box in graphics mode +// 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 +// 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 @@ -717,27 +742,27 @@ SGP::drawText (const char *pszMessage) 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); + moveAbs (xmin, ymin); + lineAbs (xmax, ymin); + lineAbs (xmax, ymax); + lineAbs (xmin, ymax); + lineAbs (xmin, ymin); } // FUNCTION -// sgp2_circle - draw circle of radius r at current center - -void +// sgp2_circle - draw circle of radius r at current center + +void SGP::drawCircle (const double r) { - drawArc (r, 0.0, TWOPI); + drawArc (r, 0.0, TWOPI); } //============================================================== -// draw arc around current center. angles in radius +// draw arc around current center. angles in radius //============================================================== -void +void SGP::drawArc (const double r, double start, double stop) { if (start > stop) { @@ -746,31 +771,32 @@ SGP::drawArc (const double r, double start, double stop) stop = temp; } - double x = r * cos ((double) start); - double y = r * sin ((double) start); - moveRel (x, y); // move from center to start of arc + double xCent = m_dCurrentWorldX; + double yCent = m_dCurrentWorldY; + + double x = r * cos (start); + double y = r * sin (start); + moveAbs (xCent + x, yCent + y); // move from center to start of arc - const double thetaIncrement = (5 * (TWOPI / 360)); - double cosTheta = cos(thetaIncrement); - double sinTheta = sin(thetaIncrement); + const double thetaIncrement = (5 * (TWOPI / 360)); // 5 degree increments + double cosTheta = cos (thetaIncrement); + double sinTheta = sin (thetaIncrement); - double angle, xp, yp; - for (angle = start; angle < stop - thetaIncrement; angle += thetaIncrement) { - xp = cosTheta * x - sinTheta * y; // translate point by thetaIncrement - yp = sinTheta * x + cosTheta * y; - lineAbs (xp, yp); + double angle; + for (angle = start; angle < stop; angle += thetaIncrement) { + double xp = cosTheta * x - sinTheta * y; // translate point by thetaIncrement + double yp = sinTheta * x + cosTheta * y; + lineAbs (xCent + xp, yCent + yp); x = xp; y = yp; } double c = cos (stop - angle); double s = sin (stop - angle); - xp = c * x - s * y; - yp = s * x + c * y; - lineAbs (xp, yp); + double xp = c * x - s * y; + double yp = s * x + c * y; + lineAbs (xCent + xp, yCent + yp); - x = r * cos (stop); - y = r * sin (stop); - moveRel (-x, -y); // move back to center of circle + moveAbs (xCent, yCent); // move back to center of circle } @@ -810,14 +836,14 @@ SGP::transformMCtoNDC (double xIn, double yIn, double* x, double* y) // NAME -// calc_transform Calculate transform matrices +// calc_transform Calculate transform matrices void SGP::calc_transform () { 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; @@ -837,7 +863,7 @@ SGP::ctmClear () calc_transform(); } -void +void SGP::ctmSet (const TransformationMatrix2D& m) { m_ctm = m; @@ -855,7 +881,7 @@ SGP::preTranslate (double x, double y) } -void +void SGP::postTranslate (double x, double y) { TransformationMatrix2D m; @@ -865,7 +891,7 @@ SGP::postTranslate (double x, double y) } -void +void SGP::preScale (double sx, double sy) { TransformationMatrix2D m; @@ -875,7 +901,7 @@ SGP::preScale (double sx, double sy) } -void +void SGP::postScale (double sx, double sy) { TransformationMatrix2D m; @@ -886,7 +912,7 @@ SGP::postScale (double sx, double sy) } -void +void SGP::preRotate (double theta) { TransformationMatrix2D m; @@ -897,7 +923,7 @@ SGP::preRotate (double theta) } -void +void SGP::postRotate (double theta) { TransformationMatrix2D m; @@ -907,7 +933,7 @@ SGP::postRotate (double theta) } -void +void SGP::preShear (double shrx, double shry) { TransformationMatrix2D m; @@ -917,7 +943,7 @@ SGP::preShear (double shrx, double shry) } -void +void SGP::postShear (double shrx, double shry) { TransformationMatrix2D m; @@ -932,19 +958,19 @@ SGP::postShear (double shrx, double shry) //////////////////////////////////////////////////////////////////////// // 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 +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 };