X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=libctsim%2Fphantom.cpp;h=48123fabb0ce2b2b21e212c7e337358105a5f80f;hp=1a8c6b174aab01003667fd01e187a8a7a81fd752;hb=1a050c98763fbbc0662731b0b76953acede6f5d7;hpb=c8b19dfaffba9f06d8b6c40cb1bb83a8964867f7 diff --git a/libctsim/phantom.cpp b/libctsim/phantom.cpp index 1a8c6b1..48123fa 100644 --- a/libctsim/phantom.cpp +++ b/libctsim/phantom.cpp @@ -1,9 +1,9 @@ /***************************************************************************** ** FILE IDENTIFICATION -** +** ** Name: phm.cpp ** Purpose: Routines for phantom objects -** Progammer: Kevin Rosenberg +** Progammer: Kevin Rosenberg ** Date Started: Aug 1984 ** ** This is part of the CTSim program @@ -28,22 +28,22 @@ #include "ct.h" const int PhantomElement::POINTS_PER_CIRCLE = 360; -const double PhantomElement::SCALE_PELEM_EXTENT=0.000; // increase pelem limits by 0.5% -//const double PhantomElement::SCALE_PELEM_EXTENT=0.005; // increase pelem limits by 0.5% +const double PhantomElement::SCALE_PELEM_EXTENT=0.000; // increase pelem limits by 0.5% +//const double PhantomElement::SCALE_PELEM_EXTENT=0.005; // increase pelem limits by 0.5% const int Phantom::PHM_INVALID = -1; const int Phantom::PHM_HERMAN = 0; const int Phantom::PHM_SHEPP_LOGAN = 1; const int Phantom::PHM_UNITPULSE = 2; -const char* Phantom::s_aszPhantomName[] = +const char* Phantom::s_aszPhantomName[] = { "herman", "shepp-logan", "unit-pulse", }; -const char* Phantom::s_aszPhantomTitle[] = +const char* Phantom::s_aszPhantomTitle[] = { "Herman Head", "Shepp-Logan", @@ -69,7 +69,7 @@ Phantom::Phantom (const char* const phmName) createFromPhantom (phmName); } -void +void Phantom::init () { m_nPElem = 0; @@ -94,10 +94,10 @@ const char* Phantom::convertPhantomIDToName (int phmID) { static const char *name = ""; - + if (phmID >= 0 && phmID < s_iPhantomCount) return (s_aszPhantomName[phmID]); - + return (name); } @@ -105,24 +105,24 @@ const char* Phantom::convertPhantomIDToTitle (int phmID) { static const char *title = ""; - + if (phmID >= 0 && phmID < s_iPhantomCount) return (s_aszPhantomName[phmID]); - + return (title); } int -Phantom::convertNameToPhantomID (const char* const phmName) +Phantom::convertNameToPhantomID (const char* const phmName) { int id = PHM_INVALID; - + for (int i = 0; i < s_iPhantomCount; i++) if (strcasecmp (phmName, s_aszPhantomName[i]) == 0) { id = i; break; } - + return (id); } @@ -137,7 +137,7 @@ Phantom::createFromPhantom (const char* const phmName) m_failMessage += phmName; return false; } - + m_name = phmName; createFromPhantom (phmid); return true; @@ -146,7 +146,7 @@ Phantom::createFromPhantom (const char* const phmName) bool Phantom::createFromPhantom (const int phmid) { - switch (phmid) + switch (phmid) { case PHM_HERMAN: addStdHerman(); @@ -156,8 +156,8 @@ Phantom::createFromPhantom (const int phmid) break; case PHM_UNITPULSE: m_composition = P_UNIT_PULSE; - addPElem ("rectangle", 0., 0., 100., 100., 0., 0.); // outline - addPElem ("ellipse", 0., 0., 1., 1., 0., 1.); // pulse + addPElem ("rectangle", 0., 0., 100., 100., 0., 0.); // outline + addPElem ("ellipse", 0., 0., 1., 1., 0., 1.); // pulse break; default: m_fail = true; @@ -165,9 +165,9 @@ Phantom::createFromPhantom (const int phmid) m_failMessage += phmid; return false; } - + m_id = phmid; - + return true; } @@ -188,19 +188,19 @@ Phantom::createFromFile (const char* const fname) { bool bGoodFile = true; FILE *fp; - + if ((fp = fopen (fname, "r")) == NULL) return (false); - + m_name = fname; - + while (1) { double cx, cy, u, v, rot, dens; char pelemtype[80]; - + int status = fscanf (fp, "%79s %lf %lf %lf %lf %lf %lf", pelemtype, &cx, &cy, &u, &v, &rot, &dens); - - if (status == static_cast(EOF)) + + if (status == static_cast(EOF)) break; else if (status != 7) { sys_error (ERR_WARNING, "Insufficient fields reading phantom file %s [Phantom::createFromFile]", fname); @@ -208,9 +208,9 @@ Phantom::createFromFile (const char* const fname) } addPElem (pelemtype, cx, cy, u, v, rot, dens); } - + fclose (fp); - + return (bGoodFile); } @@ -218,25 +218,25 @@ bool Phantom::fileWrite (const char* const fname) { fstream file (fname, std::ios::out); - + if (! file.fail()) printDefinitions (file); return ! file.fail(); } /* NAME -* addPElem Add pelem +* addPElem Add pelem * * SYNOPSIS * addPElem (type, cx, cy, u, v, rot, atten) -* char *type type of pelem (box, ellipse, etc) -* double cx, cy pelem center -* double u,v pelem size -* double rot rotation angle of pelem (in degrees) -* double atten x-ray attenuation cooefficient +* char *type type of pelem (box, ellipse, etc) +* double cx, cy pelem center +* double u,v pelem size +* double rot rotation angle of pelem (in degrees) +* double atten x-ray attenuation cooefficient */ -void +void Phantom::addPElem (const char *type, const double cx, const double cy, const double u, const double v, const double rot, const double atten) { PhmElemType pe_type = PhantomElement::convertNameToType (type); @@ -244,61 +244,61 @@ Phantom::addPElem (const char *type, const double cx, const double cy, const dou sys_error (ERR_WARNING, "Unknown PhantomElement type %s [PhantomElement::PhantomElement]", type); return; } - + PhantomElement *pelem = new PhantomElement (type, cx, cy, u, v, rot, atten); m_listPElem.push_front (pelem); - + // update phantom limits if (m_xmin > pelem->xmin()) m_xmin = pelem->xmin(); if (m_xmax < pelem->xmax()) m_xmax = pelem->xmax(); if (m_ymin > pelem->ymin()) m_ymin = pelem->ymin(); if (m_ymax < pelem->ymax()) m_ymax = pelem->ymax(); - + m_nPElem++; } /*----------------------------------------------------------------------*/ -/* Input-Output Routines */ +/* Input-Output Routines */ /*----------------------------------------------------------------------*/ /* NAME -* print Print vertices of Phantom pelems +* print Print vertices of Phantom pelems * * SYNOPSIS * print (phm) */ -void +void Phantom::print (std::ostream& os) const { os << "Number of PElements: " << m_nPElem << "\n"; os << "Limits: xmin=" << m_xmin << ", ymin=" << m_ymin << ", xmax=" << m_xmax << ", ymax=" << m_ymax << "\n"; - + for (PElemConstIterator i = m_listPElem.begin(); i != m_listPElem.end(); i++) { const PhantomElement& rPE = **i; os << "PhantomElement: nPoints=" << rPE.nOutlinePoints(); os << ", atten=" << rPE.atten() << " rot=" << convertRadiansToDegrees (rPE.rot()) << "\n"; os << "xmin=" << rPE.xmin() << ", ymin=" << rPE.ymin() << ", xmax=" << rPE.xmax() << ", ymax=" << rPE.ymax() << "\n"; - + if (false) for (int i = 0; i < rPE.nOutlinePoints(); i++) os << rPE.xOutline()[i] << "," << rPE.yOutline()[i] << "\n"; } } -void +void Phantom::print (std::ostringstream& os) const { os << "Number of PElements: " << m_nPElem << "\n"; os << "Limits: xmin=" << m_xmin << ", ymin=" << m_ymin << ", xmax=" << m_xmax << ", ymax=" << m_ymax << "\n"; - + for (PElemConstIterator i = m_listPElem.begin(); i != m_listPElem.end(); i++) { const PhantomElement& rPE = **i; os << "PhantomElement: nPoints=" << rPE.nOutlinePoints(); os << ", atten=" << rPE.atten() << " rot=" << convertRadiansToDegrees (rPE.rot()) << "\n"; os << "xmin=" << rPE.xmin() << ", ymin=" << rPE.ymin() << ", xmax=" << rPE.xmax() << ", ymax=" << rPE.ymax() << "\n"; - + if (false) for (int i = 0; i < rPE.nOutlinePoints(); i++) os << rPE.xOutline()[i] << "," << rPE.yOutline()[i] << "\n"; @@ -325,53 +325,53 @@ Phantom::printDefinitions (std::ostringstream& os) const /* NAME -* show Show vector outline of Phantom to user +* show Show vector outline of Phantom to user * * SYNOPSIS * show (pic) */ #ifdef HAVE_SGP -void +void Phantom::show () const { SGPDriver driverSGP ("Phantom Show"); SGP sgp (driverSGP); - + show (sgp); - + std::cout << "Press return to continue"; cio_kb_getc(); } -void +void Phantom::show (SGP& sgp) const { double wsize = m_xmax - m_xmin; - if ((m_ymax - m_ymin) > wsize) + if ((m_ymax - m_ymin) > wsize) wsize = m_ymax - m_ymin; wsize *= 1.01; double halfWindow = wsize / 2; - + double xcent = m_xmin + (m_xmax - m_xmin) / 2; double ycent = m_ymin + (m_ymax - m_ymin) / 2; - + sgp.setWindow (xcent - halfWindow, ycent - halfWindow, xcent + halfWindow, ycent + halfWindow); - + draw (sgp); } #endif /* NAME -* draw Draw vector outline of Phantom +* draw Draw vector outline of Phantom * * SYNOPSIS * draw () */ #ifdef HAVE_SGP -void +void Phantom::draw (SGP& sgp) const { for (PElemIterator i = m_listPElem.begin(); i != m_listPElem.end(); i++) @@ -381,15 +381,15 @@ Phantom::draw (SGP& sgp) const /* NAME -* addStdSheppLogan Make head phantom of Shepp-Logan +* addStdSheppLogan Make head phantom of Shepp-Logan * * REFERENCES * S. W. Rowland, "Computer Implementation of Image Reconstruction -* Formulas", in "Image Reconstruction from Projections: Implementation -* and Applications", edited by G. T. Herman, 1978. +* Formulas", in "Image Reconstruction from Projections: Implementation +* and Applications", edited by G. T. Herman, 1978. */ -void +void Phantom::addStdSheppLogan () { addPElem ("ellipse", 0.0000, 0.0000, 0.6900, 0.9200, 0.0, 1.00); @@ -407,14 +407,14 @@ Phantom::addStdSheppLogan () /* NAME -* addStdHerman Standard head phantom of G. T. Herman +* addStdHerman Standard head phantom of G. T. Herman * * REFERENCES * G. T. Herman, "Image Reconstructions from Projections: The Fundementals -* of Computed Tomography", 1979. +* of Computed Tomography", 1979. */ -void +void Phantom::addStdHerman () { addPElem ("ellipse", 0.000, 1.50, 0.375, 0.3000, 90.00, -0.003); @@ -437,14 +437,14 @@ Phantom::addStdHerman () /* NAME -* convertToImagefile Make image array from Phantom +* convertToImagefile Make image array from Phantom * * SYNOPSIS * pic_to_imagefile (pic, im, nsample) -* Phantom& pic Phantom definitions -* ImageFile *im Computed pixel array -* int nsample Number of samples along each axis for each pixel -* (total samples per pixel = nsample * nsample) +* Phantom& pic Phantom definitions +* ImageFile *im Computed pixel array +* int nsample Number of samples along each axis for each pixel +* (total samples per pixel = nsample * nsample) */ void @@ -453,62 +453,62 @@ Phantom::convertToImagefile (ImageFile& im, double dViewRatio, const int in_nsam convertToImagefile (im, dViewRatio, in_nsample, trace, 0, im.nx(), true); } -void -Phantom::convertToImagefile (ImageFile& im, const double dViewRatio, const int in_nsample, const int trace, +void +Phantom::convertToImagefile (ImageFile& im, const double dViewRatio, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const { int iStorageOffset = (bStoreAtColumnPos ? colStart : 0); convertToImagefile (im, im.nx(), dViewRatio, in_nsample, trace, colStart, colCount, iStorageOffset); } -void -Phantom::convertToImagefile (ImageFile& im, const int iTotalRasterCols, const double dViewRatio, +void +Phantom::convertToImagefile (ImageFile& im, const int iTotalRasterCols, const double dViewRatio, const int in_nsample, const int trace, const int colStart, const int colCount, int iStorageOffset) const { const int nx = im.nx(); const int ny = im.ny(); if (nx < 2 || ny < 2) return; - + int nsample = in_nsample; - if (nsample < 1) + if (nsample < 1) nsample = 1; - + double dx = m_xmax - m_xmin; double dy = m_ymax - m_ymin; double xcent = m_xmin + dx / 2; double ycent = m_ymin + dy / 2; double dHalflen = dViewRatio * (getDiameterBoundaryCircle() / SQRT2 / 2); - + double xmin = xcent - dHalflen; double xmax = xcent + dHalflen; double ymin = ycent - dHalflen; double ymax = ycent + dHalflen; - + // Each pixel holds the average of the intensity of the cell with (ix,iy) at the center of the pixel // Set major increments so that the last cell v[nx-1][ny-1] will start at xmax - xinc, ymax - yinc). // Set minor increments so that sample points are centered in cell - + double xinc = (xmax - xmin) / (iTotalRasterCols); double yinc = (ymax - ymin) / ny; - - double kxinc = xinc / nsample; /* interval between samples */ + + double kxinc = xinc / nsample; /* interval between samples */ double kyinc = yinc / nsample; - double kxofs = kxinc / 2; /* offset of 1st point */ + double kxofs = kxinc / 2; /* offset of 1st point */ double kyofs = kyinc / 2; - + im.setAxisExtent (xmin, xmax, ymin, ymax); im.setAxisIncrement (xinc, yinc); - + ImageFileArray v = im.getArray(); - + for (int ix = 0; ix < colCount; ix++) { int iColStore = ix + iStorageOffset; ImageFileColumn vCol = v[iColStore]; for (int iy = 0; iy < ny; iy++) *vCol++ = 0; } - + double x_start = xmin + (colStart * xinc); for (PElemConstIterator pelem = m_listPElem.begin(); pelem != m_listPElem.end(); pelem++) { const PhantomElement& rPElem = **pelem; @@ -528,12 +528,12 @@ Phantom::convertToImagefile (ImageFile& im, const int iTotalRasterCols, const do } /* for iy */ } /* for ix */ } /* for pelem */ - - + + if (nsample > 1) { double factor = 1.0 / static_cast(nsample * nsample); - - + + for (int ix = 0; ix < colCount; ix++) { int iColStore = ix + iStorageOffset; ImageFileColumn vCol = v[iColStore]; @@ -557,12 +557,12 @@ PhantomElement::PhantomElement (const char *type, const double cx, const double : m_cx(cx), m_cy(cy), m_u(u), m_v(v), m_atten(atten), m_nPoints(0), m_xOutline(0), m_yOutline(0) { m_rot = convertDegreesToRadians (rot); // convert angle to radians - + m_type = convertNameToType (type); - + makeTransformMatrices (); // calc transform matrices between phantom and normalized phantomelement - makeVectorOutline (); // calculate vector outline of pelem - + makeVectorOutline (); // calculate vector outline of pelem + m_rectLimits[0] = m_xmin; m_rectLimits[1] = m_ymin; m_rectLimits[2] = m_xmax; m_rectLimits[3] = m_ymax; } @@ -593,7 +593,7 @@ PhmElemType PhantomElement::convertNameToType (const char* const typeName) { PhmElemType type = PELEM_INVALID; - + if (strcasecmp (typeName, "rectangle") == 0) type = PELEM_RECTANGLE; else if (strcasecmp (typeName, "triangle") == 0) @@ -604,7 +604,7 @@ PhantomElement::convertNameToType (const char* const typeName) type = PELEM_SECTOR; else if (strcasecmp (typeName, "segment") == 0) type = PELEM_SEGMENT; - + return (type); } @@ -612,7 +612,7 @@ const char* const PhantomElement::convertTypeToName (PhmElemType iType) { static char* pszType = "Unknown"; - + if (iType == PELEM_RECTANGLE) pszType = "rectangle"; else if (iType == PELEM_TRIANGLE) @@ -623,32 +623,32 @@ PhantomElement::convertTypeToName (PhmElemType iType) pszType = "sector"; else if (iType == PELEM_SEGMENT) pszType = "segment"; - + return pszType; } -void +void PhantomElement::makeTransformMatrices () { GRFMTX_2D temp; - - // To map normalized Pelem coords to world Phantom - // scale by (u, v) - // rotate by rot - // translate by (cx, cy) - + + // To map normalized Pelem coords to world Phantom + // scale by (u, v) + // rotate by rot + // translate by (cx, cy) + scale_mtx2 (m_xformObjToPhm, m_u, m_v); rot_mtx2 (temp, m_rot); mult_mtx2 (m_xformObjToPhm, temp, m_xformObjToPhm); xlat_mtx2 (temp, m_cx, m_cy); mult_mtx2 (m_xformObjToPhm, temp, m_xformObjToPhm); - + // to map world Phantom coodinates to normalized PElem coords // translate by (-cx, -cy) // rotate by -rot // scale by (1/u, 1/v) - + xlat_mtx2 (m_xformPhmToObj, -m_cx, -m_cy); rot_mtx2 (temp, -m_rot); mult_mtx2 (m_xformPhmToObj, temp, m_xformPhmToObj); @@ -658,11 +658,11 @@ PhantomElement::makeTransformMatrices () /* NAME -* pelem_make_points INTERNAL routine to calculate point array for an pelem +* pelem_make_points INTERNAL routine to calculate point array for an pelem * * SYNOPSIS * makepelempts (pelem) -* PELEM *pelem pelem whose points we are calculating +* PELEM *pelem pelem whose points we are calculating * * NOTES * Called by phm_add_pelem() @@ -674,27 +674,27 @@ PhantomElement::makeVectorOutline () double radius, theta, start, stop; double xfact, yfact; int cpts; - + m_nPoints = 0; switch (m_type) { case PELEM_RECTANGLE: m_nPoints = 5; m_xOutline = new double [m_nPoints]; m_yOutline = new double [m_nPoints]; - m_xOutline[0] =-m_u; m_yOutline[0] =-m_v; - m_xOutline[1] = m_u; m_yOutline[1] =-m_v; - m_xOutline[2] = m_u; m_yOutline[2] = m_v; - m_xOutline[3] =-m_u; m_yOutline[3] = m_v; - m_xOutline[4] =-m_u; m_yOutline[4] =-m_v; + m_xOutline[0] =-m_u; m_yOutline[0] =-m_v; + m_xOutline[1] = m_u; m_yOutline[1] =-m_v; + m_xOutline[2] = m_u; m_yOutline[2] = m_v; + m_xOutline[3] =-m_u; m_yOutline[3] = m_v; + m_xOutline[4] =-m_u; m_yOutline[4] =-m_v; break; case PELEM_TRIANGLE: m_nPoints = 4; m_xOutline = new double [m_nPoints]; m_yOutline = new double [m_nPoints]; - m_xOutline[0] =-m_u; m_yOutline[0] = 0.0; - m_xOutline[1] = m_u; m_yOutline[1] = 0.0; - m_xOutline[2] = 0.0; m_yOutline[2] = m_v; - m_xOutline[3] =-m_u; m_yOutline[3] = 0.0; + m_xOutline[0] =-m_u; m_yOutline[0] = 0.0; + m_xOutline[1] = m_u; m_yOutline[1] = 0.0; + m_xOutline[2] = 0.0; m_yOutline[2] = m_v; + m_xOutline[3] =-m_u; m_yOutline[3] = 0.0; break; case PELEM_ELLIPSE: cpts = numCirclePoints (TWOPI); @@ -705,31 +705,31 @@ PhantomElement::makeVectorOutline () break; case PELEM_SECTOR: radius = sqrt(m_u * m_u + m_v * m_v); - theta = atan(m_u / m_v); // angle with y-axis + theta = atan(m_u / m_v); // angle with y-axis start = 3.0 * HALFPI - theta; stop = 3.0 * HALFPI + theta; cpts = numCirclePoints (stop - start); m_nPoints = 3 + cpts; m_xOutline = new double [m_nPoints]; m_yOutline = new double [m_nPoints]; - - m_xOutline[0] = 0.0; m_yOutline[0] = m_v; - m_xOutline[1] =-m_u; m_yOutline[1] = 0.0; + + m_xOutline[0] = 0.0; m_yOutline[0] = m_v; + m_xOutline[1] =-m_u; m_yOutline[1] = 0.0; calcArcPoints (&m_xOutline[2], &m_yOutline[2], cpts, 0.0, m_v, radius, start, stop); m_xOutline[cpts + 2] = 0.0; m_yOutline[cpts + 2] = m_v; break; case PELEM_SEGMENT: radius = sqrt(m_u * m_u + m_v * m_v); - theta = atan (m_u / m_v); // angle with y-axis + theta = atan (m_u / m_v); // angle with y-axis start = 3.0 * HALFPI - theta; stop = 3.0 * HALFPI + theta; - + cpts = numCirclePoints (stop - start); m_nPoints = cpts + 1; m_xOutline = new double [m_nPoints]; m_yOutline = new double [m_nPoints]; - + calcArcPoints (m_xOutline, m_yOutline, cpts, 0.0, m_v, radius, start, stop); m_xOutline[cpts] = -m_u; m_yOutline[cpts] = 0.0; @@ -738,19 +738,19 @@ PhantomElement::makeVectorOutline () sys_error(ERR_WARNING, "Illegal phantom element type %d [makeVectorOutline]", m_type); return; } - + rotate2d (m_xOutline, m_yOutline, m_nPoints, m_rot); xlat2d (m_xOutline, m_yOutline, m_nPoints, m_cx, m_cy); - + minmax_array (m_xOutline, m_nPoints, m_xmin, m_xmax); minmax_array (m_yOutline, m_nPoints, m_ymin, m_ymax); - + // increase pelem extent by SCALE_PELEM_EXTENT to eliminate chance of - // missing actual pelem maximum due to polygonal sampling - + // missing actual pelem maximum due to polygonal sampling + xfact = (m_xmax - m_xmin) * SCALE_PELEM_EXTENT; yfact = (m_ymax - m_ymin) * SCALE_PELEM_EXTENT; - + m_xmin -= xfact; m_ymin -= yfact; m_xmax += xfact; @@ -759,30 +759,30 @@ PhantomElement::makeVectorOutline () /* NAME -* calc_arc Calculate outline of a arc of a circle +* calc_arc Calculate outline of a arc of a circle * * SYNOPSIS * calc_arc (x, y, xcent, ycent, pts, r, start, stop) -* double x[], y[]; Array of points -* int pts Number of points in array -* double xcent, ycent Center of cirlce -* double r Radius of circle -* double start, stop Beginning & ending angles +* double x[], y[]; Array of points +* int pts Number of points in array +* double xcent, ycent Center of cirlce +* double r Radius of circle +* double start, stop Beginning & ending angles */ -void +void PhantomElement::calcArcPoints (double x[], double y[], const int pts, const double xcent, const double ycent, const double r, const double start, const double stop) { if (r <= 0.0) sys_error (ERR_WARNING, "negative or zero radius in calc_arc()"); - - double theta = (stop - start) / (pts - 1); // angle incr. between points + + double theta = (stop - start) / (pts - 1); // angle incr. between points double c = cos(theta); double s = sin(theta); - + x[0] = r * cos (start) + xcent; y[0] = r * sin (start) + ycent; - + double xp = x[0] - xcent; double yp = y[0] - ycent; for (int i = 1; i < pts; i++) { @@ -803,28 +803,28 @@ PhantomElement::calcArcPoints (double x[], double y[], const int pts, const doub // -void +void PhantomElement::calcEllipsePoints (double x[], double y[], const int pts, const double u, const double v) { - calcArcPoints (x, y, m_nPoints, 0.0, 0.0, 1.0, 0.0, TWOPI); // make a unit circle - scale2d (x, y, m_nPoints, m_u, m_v); // scale to ellipse + calcArcPoints (x, y, m_nPoints, 0.0, 0.0, 1.0, 0.0, TWOPI); // make a unit circle + scale2d (x, y, m_nPoints, m_u, m_v); // scale to ellipse } /* NAME -* circle_pts Calculate number of points to use for circle segment +* circle_pts Calculate number of points to use for circle segment * * SYNOPSIS * n = circle_pts (theta) -* int n Number of points to use for arc -* double theta Length of arc in radians +* int n Number of points to use for arc +* double theta Length of arc in radians */ -int +int PhantomElement::numCirclePoints (double theta) { theta = clamp (theta, 0., TWOPI); - + return static_cast (POINTS_PER_CIRCLE * theta / TWOPI + 1.5); } @@ -836,42 +836,42 @@ PhantomElement::clipLineWorldCoords (double& x1, double& y1, double& x2, double double cx1 = x1, cy1 = y1, cx2 = x2, cy2 = y2; if (! clip_rect (cx1, cy1, cx2, cy2, m_rectLimits)) return false; - - // convert phantom coordinates to pelem coordinates + + // convert phantom coordinates to pelem coordinates xform_mtx2 (m_xformPhmToObj, x1, y1); xform_mtx2 (m_xformPhmToObj, x2, y2); - + if (! clipLineNormalizedCoords (x1, y1, x2, y2)) return false; - - // convert standard pelem coordinates back to phantom coordinates + + // convert standard pelem coordinates back to phantom coordinates xform_mtx2 (m_xformObjToPhm, x1, y1); xform_mtx2 (m_xformObjToPhm, x2, y2); - + return true; } /* NAME -* pelem_clip_line Clip pelem against an arbitrary line +* pelem_clip_line Clip pelem against an arbitrary line * * SYNOPSIS * pelem_clip_line (pelem, x1, y1, x2, y2) -* PhantomElement& pelem; Pelem to be clipped -* double *x1, *y1, *x2, *y2 Endpoints of line to be clipped +* PhantomElement& pelem; Pelem to be clipped +* double *x1, *y1, *x2, *y2 Endpoints of line to be clipped * * RETURNS * true if line passes through pelem -* (x1, y1, x2, y2 hold coordinates of new line) +* (x1, y1, x2, y2 hold coordinates of new line) * false if line do not pass through pelem -* (x1, y1, x2, y2 are undefined) +* (x1, y1, x2, y2 are undefined) */ bool PhantomElement::clipLineNormalizedCoords (double& x1, double& y1, double& x2, double& y2) const { bool accept = false; - + switch (m_type) { case PELEM_RECTANGLE: double rect[4]; @@ -895,18 +895,18 @@ PhantomElement::clipLineNormalizedCoords (double& x1, double& y1, double& x2, do sys_error (ERR_WARNING, "Illegal pelem type %d [pelem_clip_line]", m_type); break; } - + return(accept); } -// METHOD IDENTIFICATION -// PhantomElement::isPointInside Check if point is inside pelem +// METHOD IDENTIFICATION +// PhantomElement::isPointInside Check if point is inside pelem // // SYNOPSIS // is_point_inside (pelem, x, y, coord_type) -// double x, y Point to see if lies in pelem -// int coord_type Coordinate type (PELEM_COORD or PHM_COORD) +// double x, y Point to see if lies in pelem +// int coord_type Coordinate type (PELEM_COORD or PHM_COORD) // // RETURNS // true if point lies within pelem @@ -921,7 +921,7 @@ PhantomElement::isPointInside (double x, double y, const CoordType coord_type) c sys_error(ERR_WARNING, "Illegal coordinate type in pelem_is_point_inside"); return (false); } - + switch (m_type) { case PELEM_RECTANGLE: if (x > 1. || x < -1. || y > 1. || y < -1.) @@ -938,34 +938,34 @@ PhantomElement::isPointInside (double x, double y, const CoordType coord_type) c case PELEM_ELLIPSE: if (x > 1. || x < -1. || y > 1. || y < -1.) return (false); - if (x * x + y * y > 1.) // check if inside unit circle + if (x * x + y * y > 1.) // check if inside unit circle return (false); else return (true); break; - + // for clipping segments & sectors, must NOT scale by (1/u, 1/v) - // because this destroys information about size of arc component - + // because this destroys information about size of arc component + case PELEM_SEGMENT: if (x > 1. || x < -1. || y > 0.) - return (false); // clip against y > 0 - x *= m_u; // put back u & v scale + return (false); // clip against y > 0 + x *= m_u; // put back u & v scale y *= m_v; if (x * x + (y-m_v) * (y-m_v) > m_u * m_u + m_v * m_v) - return (false); // clip against circle, r = sqrt(@) + return (false); // clip against circle, r = sqrt(@) else return (true); break; case PELEM_SECTOR: - if (x > 1. || x < -1. || y > 1.) // extent + if (x > 1. || x < -1. || y > 1.) // extent return (false); - if (y > 1. - x || y > 1. + x) // triangle - return (false); // clip against triangle - x *= m_u; // circle: put back u & v scale + if (y > 1. - x || y > 1. + x) // triangle + return (false); // clip against triangle + x *= m_u; // circle: put back u & v scale y *= m_v; if (x * x + (y-m_v) * (y-m_v) > m_u * m_u + m_v * m_v) - return (false); // clip against circle + return (false); // clip against circle else return (true); break; @@ -973,7 +973,7 @@ PhantomElement::isPointInside (double x, double y, const CoordType coord_type) c sys_error (ERR_WARNING, "Illegal pelem type in pelem_is_point_inside()"); break; } - + return (false); }