43 #ifndef EGS_CYLINDERS_
44 #define EGS_CYLINDERS_
56 #ifdef BUILD_ROUNDRECT_CYLINDERS_DLL
57 #define EGS_ROUNDRECT_CYLINDERS_EXPORT __declspec(dllexport)
59 #define EGS_ROUNDRECT_CYLINDERS_EXPORT __declspec(dllimport)
61 #define EGS_ROUNDRECT_CYLINDERS_LOCAL
65 #ifdef HAVE_VISIBILITY
66 #define EGS_ROUNDRECT_CYLINDERS_EXPORT __attribute__ ((visibility ("default")))
67 #define EGS_ROUNDRECT_CYLINDERS_LOCAL __attribute__ ((visibility ("hidden")))
69 #define EGS_ROUNDRECT_CYLINDERS_EXPORT
70 #define EGS_ROUNDRECT_CYLINDERS_LOCAL
160 template <
class Tx,
class Ty>
200 const vector<EGS_Float> &y_wid,
201 const vector<EGS_Float> &rad,
202 const EGS_Vector &position,
const string &Name,
204 xo(position), Ax(A_x), Ay(A_y) {
207 ax =
new EGS_Float [nc];
208 ay =
new EGS_Float [nc];
209 ar =
new EGS_Float [nc];
210 for (
int i=0; i<nc; i++) {
217 mytype = Ax.getType() + Ay.getType();
221 return inRing(nreg-1, src);
228 for (
int j=0; j<nreg; j++) {
241 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
247 EGS_Float px = Ax*xp;
248 EGS_Float py = Ay*xp;
252 if (qx == 0.0 && qy == 0.0) {
259 int xflip = px < 0 ? -1 : 1;
260 int yflip = py < 0 ? -1 : 1;
267 EGS_Float norm_x = 0.;
268 EGS_Float norm_y = 0.;
272 bool haveInternal =
false;
273 if ((ireg < 0 || ireg > 0)) {
276 int n = ireg < 0 ? nreg - 1 : ireg - 1;
277 bool found = findLineIntersection(n, px, py, qx,qy,
278 norm_x, norm_y, ux, uy);
280 bool forward = (qx * (ux-px) + qy * (uy - py) > 0) || (px == ux && py == uy);
283 dist = sqrt((ux-px)*(ux-px) + (uy-py)*(uy-py));
290 if (ireg >= 0 && !haveInternal) {
293 EGS_Float sc = 1 / sqrt(qx*qx+qy*qy);
295 EGS_Float skip = 2 * (ax[ireg] + ay[ireg]);
296 EGS_Float bx = px + qx * skip * sc;
297 EGS_Float by = py + qy * skip * sc;
298 EGS_Float xeflip = bx < 0 ? -1 : 1;
299 EGS_Float yeflip = by < 0 ? -1 : 1;
302 EGS_Float cx = -qx*xeflip;
303 EGS_Float cy = -qy*yeflip;
304 EGS_Float ux=0.,uy=0.;
305 bool found = findLineIntersection(ireg, bx, by, cx, cy,
306 norm_x, norm_y, ux, uy);
313 dist = sqrt((ux-px)*(ux-px) + (uy-py)*(uy-py));
314 inew = (nreg == ireg + 1) ? -1 : ireg+1;
330 dist *= sqrt(u.length2() / (qx*qx + qy*qy));
333 t = dist + boundaryTolerance;
335 *newmed = inew < 0 ? -1 : medium(inew);
338 *normal = Ax.normal()*norm_x*xflip + Ay.normal() * norm_y * yflip;
347 EGS_Float hownear(
int ireg,
const EGS_Vector &src) {
348 EGS_Float x = fabs(Ax*(src-xo));
349 EGS_Float y = fabs(Ay*(src-xo));
352 return getRingDist(nreg - 1, x, y);
355 return getRingDist(0, x, y);
357 EGS_Float outdist = getRingDist(ireg, x, y);
358 EGS_Float indist = getRingDist(ireg-1, x, y);
359 return fmin(outdist,indist);
362 const string &getType()
const {
366 void printInfo()
const {
372 for (j=0; j<nreg; j++) {
377 for (j=0; j<nreg; j++) {
381 egsInformation(
"===================================================\n");
386 bool inRing(
int ireg,
const EGS_Vector &src) {
388 EGS_Float x = fabs(Ax*rc);
389 EGS_Float y = fabs(Ay*rc);
390 if (x >= ax[ireg] || y >= ay[ireg]) {
393 EGS_Float dx = (x - (ax[ireg]-ar[ireg]));
394 EGS_Float dy = (y - (ay[ireg]-ar[ireg]));
395 if (dx < 0 || dy < 0) {
398 bool incirc = (dx*dx + dy*dy) <= ar[ireg]*ar[ireg];
402 EGS_Float getRingDist(
int ireg, EGS_Float x, EGS_Float y) {
404 EGS_Float dx = (x - (ax[ireg] - ar[ireg]));
405 EGS_Float dy = (y - (ay[ireg] - ar[ireg]));
406 if (dx > 0 && dy > 0) {
408 return fabs(sqrt(dx*dx+dy*dy)-ar[ireg]);
412 return fabs(y - ay[ireg]);
415 return fabs(x - ax[ireg]);
419 return fmin(fabs(x - ax[ireg]), fabs(y - ay[ireg]));
423 bool findLineIntersection(
int ring,
424 EGS_Float px, EGS_Float py, EGS_Float qx, EGS_Float qy,
425 EGS_Float &norm_x, EGS_Float &norm_y, EGS_Float &ux, EGS_Float &uy) {
428 if (px <= ax[ring] - ar[ring]) {
435 else if (px <= ax[ring]) {
436 EGS_Float dx = px - (ax[ring] - ar[ring]);
437 EGS_Float dy = sqrt(ar[ring]*ar[ring]-dx*dx);
438 EGS_Float md = 1/sqrt(dx*dx+dy*dy);
442 uy = dy + ay[ring]- ar[ring];
450 else if (qy == 0.0) {
452 if (py <= ay[ring] - ar[ring]) {
459 else if (py <= ay[ring]) {
460 EGS_Float dy = py - (ay[ring] - ar[ring]);
461 EGS_Float dx = sqrt(ar[ring]*ar[ring]-dy*dy);
462 EGS_Float md = 1/sqrt(dx*dx+dy*dy);
465 ux = dx + ax[ring]- ar[ring];
476 EGS_Float ix = px + (qx / qy) * (ay[ring] - py);
477 EGS_Float iy = py + (qy / qx) * (ax[ring] - px);
480 bool topface = fabs(ix) <= ax[ring] - ar[ring];
481 bool sideface = fabs(iy) <= ay[ring] - ar[ring];
483 if (fabs(ix) > ax[ring] + boundaryTolerance && fabs(iy) > ay[ring] + boundaryTolerance) {
488 bool sidehit =
false;
490 if (topface && sideface) {
491 EGS_Float d2side = (px-ax[ring])*(px-ax[ring])+(py-iy)*(py-iy);
492 EGS_Float d2top = (py-ay[ring])*(py-ay[ring])+(px-ix)*(px-ix);
493 if (d2side < d2top) {
500 else if (topface && py > ay[ring]) {
503 else if (sideface && px > ax[ring]) {
524 EGS_Float f = 1 / sqrt(qx*qx+qy*qy);
525 EGS_Float nqx = qx * f;
526 EGS_Float nqy = qy * f;
529 EGS_Float rx = (ax[ring] - ar[ring]);
530 EGS_Float ry = (ay[ring] - ar[ring]);
533 if (px <= ax[ring] && py <= ay[ring]) {
536 else if (px <= ax[ring]) {
542 else if (py <= ay[ring]) {
550 if (ix < 0 && iy < 0) {
563 EGS_Float s = (nqy * (px - rx) - nqx * (py - ry));
566 if (fabs(s) <= ar[ring]) {
568 EGS_Float v = sqrt(fmax(ar[ring]*ar[ring] - s*s,0));
570 norm_x = -nqy * (-s);
573 if (nqx * (norm_x + nqx*v) + nqy * (norm_y + nqy*v) < 0) {
584 norm_x *= 1/ar[ring];
585 norm_y *= 1/ar[ring];
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual void printInfo() const
Print information about this geometry.
A set of concentric rounded rectangles.
Tx Ax
The projection operator for the first ('x') axis.
EGS_Float * ar
Radii of roundings for each rect.
~EGS_RoundRectCylindersT()
Desctructor.
Ty Ay
The projection operator for the second ('y') axis.
EGS_Float * ay
Widths along the axis defined by Ay,.
EGS_Float * ax
Widths along the axis defined by Ax,.
string mytype
The cylinder type.
EGS_RoundRectCylindersT(const vector< EGS_Float > &x_wid, const vector< EGS_Float > &y_wid, const vector< EGS_Float > &rad, const EGS_Vector &position, const string &Name, const Tx &A_x, const Ty &A_y)
Construct a set of concentric rounded rectangles.
EGS_Vector xo
A point on the cylinder axis.
A class representing 3D vectors.
EGS_BaseGeometry class header file.
Global egspp functions header file.
Attempts to fix broken math header files.
EGS_Projector and EGS_2DVector class header file.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...