42 #ifndef EGS_CYLINDERS_
43 #define EGS_CYLINDERS_
55 #ifdef BUILD_ROUNDRECT_CYLINDERS_DLL
56 #define EGS_ROUNDRECT_CYLINDERS_EXPORT __declspec(dllexport)
58 #define EGS_ROUNDRECT_CYLINDERS_EXPORT __declspec(dllimport)
60 #define EGS_ROUNDRECT_CYLINDERS_LOCAL
64 #ifdef HAVE_VISIBILITY
65 #define EGS_ROUNDRECT_CYLINDERS_EXPORT __attribute__ ((visibility ("default")))
66 #define EGS_ROUNDRECT_CYLINDERS_LOCAL __attribute__ ((visibility ("hidden")))
68 #define EGS_ROUNDRECT_CYLINDERS_EXPORT
69 #define EGS_ROUNDRECT_CYLINDERS_LOCAL
159 template <
class Tx,
class Ty>
199 const vector<EGS_Float> &y_wid,
200 const vector<EGS_Float> &rad,
201 const EGS_Vector &position,
const string &Name,
203 xo(position), Ax(A_x), Ay(A_y) {
206 ax =
new EGS_Float [nc];
207 ay =
new EGS_Float [nc];
208 ar =
new EGS_Float [nc];
209 for (
int i=0; i<nc; i++) {
216 mytype = Ax.
getType() + Ay.getType();
220 return inRing(nreg-1, src);
227 for (
int j=0; j<nreg; j++) {
240 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
246 EGS_Float px = Ax*xp;
247 EGS_Float py = Ay*xp;
251 if (qx == 0.0 && qy == 0.0) {
258 int xflip = px < 0 ? -1 : 1;
259 int yflip = py < 0 ? -1 : 1;
266 EGS_Float norm_x = 0.;
267 EGS_Float norm_y = 0.;
271 bool haveInternal =
false;
272 if ((ireg < 0 || ireg > 0)) {
275 int n = ireg < 0 ? nreg - 1 : ireg - 1;
276 bool found = findLineIntersection(n, px, py, qx,qy,
277 norm_x, norm_y, ux, uy);
279 bool forward = (qx * (ux-px) + qy * (uy - py) > 0) || (px == ux && py == uy);
282 dist = sqrt((ux-px)*(ux-px) + (uy-py)*(uy-py));
289 if (ireg >= 0 && !haveInternal) {
292 EGS_Float sc = 1 / sqrt(qx*qx+qy*qy);
294 EGS_Float skip = 2 * (ax[ireg] + ay[ireg]);
295 EGS_Float bx = px + qx * skip * sc;
296 EGS_Float by = py + qy * skip * sc;
297 EGS_Float xeflip = bx < 0 ? -1 : 1;
298 EGS_Float yeflip = by < 0 ? -1 : 1;
301 EGS_Float cx = -qx*xeflip;
302 EGS_Float cy = -qy*yeflip;
303 EGS_Float ux=0.,uy=0.;
304 bool found = findLineIntersection(ireg, bx, by, cx, cy,
305 norm_x, norm_y, ux, uy);
312 dist = sqrt((ux-px)*(ux-px) + (uy-py)*(uy-py));
313 inew = (nreg == ireg + 1) ? -1 : ireg+1;
329 dist *= sqrt(u.length2() / (qx*qx + qy*qy));
332 t = dist + boundaryTolerance;
334 *newmed = inew < 0 ? -1 : medium(inew);
337 *normal = Ax.normal()*norm_x*xflip + Ay.normal() * norm_y * yflip;
346 EGS_Float hownear(
int ireg,
const EGS_Vector &src) {
347 EGS_Float x = fabs(Ax*(src-xo));
348 EGS_Float y = fabs(Ay*(src-xo));
351 return getRingDist(nreg - 1, x, y);
354 return getRingDist(0, x, y);
356 EGS_Float outdist = getRingDist(ireg, x, y);
357 EGS_Float indist = getRingDist(ireg-1, x, y);
358 return fmin(outdist,indist);
361 const string &getType()
const {
365 void printInfo()
const {
368 egsInformation(
" midpoint of cylinders = (%g,%g,%g)\n",xo.x,xo.y,xo.z);
371 for (j=0; j<nreg; j++) {
376 for (j=0; j<nreg; j++) {
380 egsInformation(
"===================================================\n");
385 bool inRing(
int ireg,
const EGS_Vector &src) {
387 EGS_Float x = fabs(Ax*rc);
388 EGS_Float y = fabs(Ay*rc);
389 if (x >= ax[ireg] || y >= ay[ireg]) {
392 EGS_Float dx = (x - (ax[ireg]-ar[ireg]));
393 EGS_Float dy = (y - (ay[ireg]-ar[ireg]));
394 if (dx < 0 || dy < 0) {
397 bool incirc = (dx*dx + dy*dy) <= ar[ireg]*ar[ireg];
401 EGS_Float getRingDist(
int ireg, EGS_Float x, EGS_Float y) {
403 EGS_Float dx = (x - (ax[ireg] - ar[ireg]));
404 EGS_Float dy = (y - (ay[ireg] - ar[ireg]));
405 if (dx > 0 && dy > 0) {
407 return fabs(sqrt(dx*dx+dy*dy)-ar[ireg]);
411 return fabs(y - ay[ireg]);
414 return fabs(x - ax[ireg]);
418 return fmin(fabs(x - ax[ireg]), fabs(y - ay[ireg]));
422 bool findLineIntersection(
int ring,
423 EGS_Float px, EGS_Float py, EGS_Float qx, EGS_Float qy,
424 EGS_Float &norm_x, EGS_Float &norm_y, EGS_Float &ux, EGS_Float &uy) {
427 if (px <= ax[ring] - ar[ring]) {
434 else if (px <= ax[ring]) {
435 EGS_Float dx = px - (ax[ring] - ar[ring]);
436 EGS_Float dy = sqrt(ar[ring]*ar[ring]-dx*dx);
437 EGS_Float md = 1/sqrt(dx*dx+dy*dy);
441 uy = dy + ay[ring]- ar[ring];
449 else if (qy == 0.0) {
451 if (py <= ay[ring] - ar[ring]) {
458 else if (py <= ay[ring]) {
459 EGS_Float dy = py - (ay[ring] - ar[ring]);
460 EGS_Float dx = sqrt(ar[ring]*ar[ring]-dy*dy);
461 EGS_Float md = 1/sqrt(dx*dx+dy*dy);
464 ux = dx + ax[ring]- ar[ring];
475 EGS_Float ix = px + (qx / qy) * (ay[ring] - py);
476 EGS_Float iy = py + (qy / qx) * (ax[ring] - px);
479 bool topface = fabs(ix) <= ax[ring] - ar[ring];
480 bool sideface = fabs(iy) <= ay[ring] - ar[ring];
482 if (fabs(ix) > ax[ring] + boundaryTolerance && fabs(iy) > ay[ring] + boundaryTolerance) {
487 bool sidehit =
false;
489 if (topface && sideface) {
490 EGS_Float d2side = (px-ax[ring])*(px-ax[ring])+(py-iy)*(py-iy);
491 EGS_Float d2top = (py-ay[ring])*(py-ay[ring])+(px-ix)*(px-ix);
492 if (d2side < d2top) {
499 else if (topface && py > ay[ring]) {
502 else if (sideface && px > ax[ring]) {
523 EGS_Float f = 1 / sqrt(qx*qx+qy*qy);
524 EGS_Float nqx = qx * f;
525 EGS_Float nqy = qy * f;
528 EGS_Float rx = (ax[ring] - ar[ring]);
529 EGS_Float ry = (ay[ring] - ar[ring]);
532 if (px <= ax[ring] && py <= ay[ring]) {
535 else if (px <= ax[ring]) {
541 else if (py <= ay[ring]) {
549 if (ix < 0 && iy < 0) {
562 EGS_Float s = (nqy * (px - rx) - nqx * (py - ry));
565 if (fabs(s) <= ar[ring]) {
567 EGS_Float v = sqrt(fmax(ar[ring]*ar[ring] - s*s,0));
569 norm_x = -nqy * (-s);
572 if (nqx * (norm_x + nqx*v) + nqy * (norm_y + nqy*v) < 0) {
583 norm_x *= 1/ar[ring];
584 norm_y *= 1/ar[ring];
virtual const string & getType() const =0
Get the geometry type.
virtual void printInfo() const
Print information about this geometry.
A class representing 3D vectors.
Global egspp functions header file.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
Ty Ay
The projection operator for the second ('y') axis.
Tx Ax
The projection operator for the first ('x') axis.
~EGS_RoundRectCylindersT()
Desctructor.
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_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
Attempts to fix broken math header files.
A set of concentric rounded rectangles.
EGS_Vector xo
A point on the cylinder axis.
EGS_Projector and EGS_2DVector class header file.
EGS_BaseGeometry class header file.
string mytype
The cylinder type.
EGS_Float * ay
Widths along the axis defined by Ay,.