44#define GRAPH_LENGTH_FRAC 1.e-4
47Polygon :: testPoint(
double x,
double y)
const
49 bool oddNODES =
false;
51 Polygon :: PolygonEdgeIterator it(
this);
53 double x1, x2, y1, y2;
54 while ( it.giveNext(p1, p2) ) {
60 if ( ( ( y1 < y ) && ( y2 >= y ) ) ||
61 ( ( y2 < y ) && ( y1 >= y ) ) ) {
62 if ( x1 + ( y - y1 ) / ( y2 - y1 ) * ( x2 - x1 ) < x ) {
72Polygon :: computeVolume()
const
75 double x1, x2, x3, y1, y2, y3;
77 Polygon :: PolygonVertexIterator it(
this);
85 while ( it.giveNext(p) ) {
88 area += ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 );
93 return 0.5 * fabs(area);
98Polygon :: pointDistance(
double xp,
double yp)
const
105 Polygon :: PolygonEdgeIterator it(
this);
107 double x1, x2, y1, y2, d, l, tx, ty, t, nx, ny, dist = 0.0;
110 while ( it.giveNext(p1, p2) ) {
117 d = sqrt( ( xp - x1 ) * ( xp - x1 ) + ( yp - y1 ) * ( yp - y1 ) );
126 l = sqrt( ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
127 tx = ( x2 - x1 ) / l;
128 ty = ( y2 - y1 ) / l;
130 t = ( xp - x1 ) * tx + ( yp - y1 ) * ty;
132 if ( ( t >= 0.0 ) && ( t <= l ) ) {
136 d = fabs( ( xp - x1 ) * nx + ( yp - y1 ) * ny );
155 LIST ggroup = make_list();
157 EASValsSetLayer(layer);
162 double xc = 0.0, yc = 0.0;
165 Polygon :: PolygonVertexIterator it(
this);
167 while ( it.giveNext(p) ) {
176 EASValsSetFillStyle(FILL_SOLID);
180 Polygon :: PolygonEdgeIterator it2(
this);
182 while ( it2.giveNext(p1, p2) ) {
189 go = CreateTriangle3D(r);
190 add_to_tail(ggroup, go);
192 EGWithMaskChangeAttributes(COLOR_MASK | FILL_MASK | LAYER_MASK, go);
196 Polygon :: PolygonEdgeIterator it(
this);
198 EASValsSetFillStyle(FILL_HOLLOW);
199 while ( it.giveNext(p1, p2) ) {
207 go = CreateLine3D(p);
208 add_to_tail(ggroup, go);
210 EGWithMaskChangeAttributes(COLOR_MASK | FILL_MASK | LAYER_MASK, go);
214 go = CreateGgroup(ggroup);
215 EMAddGraphicsToModel(ESIModel(), go);
233 node *next, *auxs =
s, *auxc =
c;
239 }
while ( auxs !=
s );
247 }
while ( auxc !=
c );
255Graph :: testIfCoincident(
node *p1,
node *p2,
node *q1,
node *q2,
double *alpha1,
double *alpha2)
296 double par = ( ( p1->
x - p2->
x ) * ( q2->
y - q1->
y ) -
297 ( p1->
y - p2->
y ) * ( q2->
x - q1->
x ) );
299#ifdef GRAPH_DEBUG_PRINT
300 fprintf(stderr,
"p1 [%e %e] p2 [%e %e] q1 [%e %e] q2 [%e %e]\n", p1->
x, p1->
y, p2->
x, p2->
y, q1->
x, q1->
y, q2->
x, q2->
y);
301 fprintf(stderr,
"par %e\n", par);
306 double plength =
dist(p1->
x, p1->
y, p2->
x, p2->
y);
307 double qlength =
dist(q1->
x, q1->
y, q2->
x, q2->
y);
308 double ptx = ( p2->
x - p1->
x ) / plength;
309 double pty = ( p2->
y - p1->
y ) / plength;
312 double d1 = ( pnx * ( q1->
x - p1->
x ) + pny * ( q1->
y - p1->
y ) );
313 double d2 = ( pnx * ( q2->
x - p1->
x ) + pny * ( q2->
y - p1->
y ) );
314#ifdef GRAPH_DEBUG_PRINT
315 fprintf(stderr,
"dist (q-line, p-line)=%e\n", d1);
317 if ( ( fabs( d1 /
min(plength, qlength) ) >=
GT_EPS ) && ( fabs( d2 /
min(plength, qlength) ) >=
GT_EPS ) && (
sgn(d1) *
sgn(d2) > 0. ) ) {
321 double qt1 = ( ptx * ( q1->
x - p1->
x ) + pty * ( q1->
y - p1->
y ) ) / plength;
322 double qt2 = ( ptx * ( q2->
x - p1->
x ) + pty * ( q2->
y - p1->
y ) ) / plength;
323#ifdef GRAPH_DEBUG_PRINT
324 fprintf(stderr,
"param of q1 on pline t1=%e\n", qt1);
325 fprintf(stderr,
"param of q2 on pline t2=%e\n", qt2);
327 if ( ( qt1 < 0. ) && ( qt2 < 0. ) ) {
331 if ( ( qt1 > 1. ) && ( qt2 > 1. ) ) {
335 if ( ( fabs(qt1) <
GT_EPS ) && ( fabs(1. - qt2) <
GT_EPS ) ) {
339 if ( ( fabs(qt2) <
GT_EPS ) && ( fabs(1. - qt1) <
GT_EPS ) ) {
343 double qtx = ( q2->
x - q1->
x ) / qlength;
344 double qty = ( q2->
y - q1->
y ) / qlength;
345 double pt1 = ( qtx * ( p1->
x - q1->
x ) + qty * ( p1->
y - q1->
y ) ) / qlength;
346 double pt2 = ( qtx * ( p2->
x - q1->
x ) + qty * ( p2->
y - q1->
y ) ) / qlength;
353 }
else if ( ( qt2 < -
GT_EPS ) && ( qt1 > ( 1. +
GT_EPS ) ) ) {
361 }
else if ( fabs(qt1) <
GT_EPS ) {
365 }
else if ( ( pt2 >
GT_EPS ) && ( pt2 < ( 1. -
GT_EPS ) ) ) {
371 }
else if ( fabs(1. - qt1) <
GT_EPS ) {
375 }
else if ( ( pt1 >
GT_EPS ) && ( pt1 < ( 1. -
GT_EPS ) ) ) {
381 }
else if ( fabs(qt2) <
GT_EPS ) {
385 }
else if ( ( pt2 >
GT_EPS ) && ( pt2 < ( 1. -
GT_EPS ) ) ) {
391 }
else if ( fabs(1. - qt2) <
GT_EPS ) {
395 }
else if ( ( pt1 >
GT_EPS ) && ( pt1 < ( 1. -
GT_EPS ) ) ) {
401 }
else if ( ( qt1 >=
GT_EPS ) && ( qt1 <= ( 1. -
GT_EPS ) ) ) {
402 double qlength =
dist(q1->
x, q1->
y, q2->
x, q2->
y);
403 double qtx = ( q2->
x - q1->
x ) / qlength;
404 double qty = ( q2->
y - q1->
y ) / qlength;
405 double pt1 = ( qtx * ( p1->
x - q1->
x ) + qty * ( p1->
y - q1->
y ) ) / qlength;
406 double pt2 = ( qtx * ( p2->
x - q1->
x ) + qty * ( p2->
y - q1->
y ) ) / qlength;
407 if ( ( pt1 >=
GT_EPS ) && ( pt1 <= ( 1. -
GT_EPS ) ) ) {
411 }
else if ( ( pt2 >=
GT_EPS ) && ( pt2 <= ( 1. -
GT_EPS ) ) ) {
415 }
else if ( ( pt1 <=
GT_EPS || ( 1. - pt1 ) <=
GT_EPS ) && ( ( pt2 < 0. ) || ( pt2 > 1.0 ) ) ) {
419 }
else if ( ( pt2 <=
GT_EPS || ( 1. - pt2 ) <=
GT_EPS ) && ( ( pt1 < 0. ) || ( pt1 > 1.0 ) ) ) {
424 fprintf(stderr,
"testIfConcident: unresolved case q1 inside, q2 outside, pt1(t=%e), pt22(t=%e)\n", pt1, pt2);
427 }
else if ( ( qt2 >=
GT_EPS ) && ( qt2 <= ( 1. -
GT_EPS ) ) ) {
428 double qlength =
dist(q1->
x, q1->
y, q2->
x, q2->
y);
429 double qtx = ( q2->
x - q1->
x ) / qlength;
430 double qty = ( q2->
y - q1->
y ) / qlength;
431 double pt1 = ( qtx * ( p1->
x - q1->
x ) + qty * ( p1->
y - q1->
y ) ) / qlength;
432 double pt2 = ( qtx * ( p2->
x - q1->
x ) + qty * ( p2->
y - q1->
y ) ) / qlength;
433 if ( ( pt1 >=
GT_EPS ) && ( pt1 <= ( 1. -
GT_EPS ) ) ) {
437 }
else if ( ( pt2 >=
GT_EPS ) && ( pt2 <= ( 1. -
GT_EPS ) ) ) {
441 }
else if ( ( pt1 <=
GT_EPS || ( 1. - pt1 ) <=
GT_EPS ) && ( ( pt2 < 0. ) || ( pt2 > 1.0 ) ) ) {
445 }
else if ( ( pt2 <=
GT_EPS || ( 1. - pt2 ) <=
GT_EPS ) && ( ( pt1 < 0. ) || ( pt1 > 1.0 ) ) ) {
450 fprintf(stderr,
"testIfConcident: unresolved case q2 inside, q1 outside, pt1(t=%e), pt2(t=%e)\n", pt1, pt2);
454 fprintf(stderr,
"testIfConcident: unresolved case, q1(t=%e), q2(t=%e)\n", qt1, qt2);
464 double *alpha_p,
double *alpha_q,
double *xint,
double *yint)
485 double x, y, tp, tq, par;
487 par = ( ( p1->
x - p2->
x ) * ( q2->
y - q1->
y ) -
488 ( p1->
y - p2->
y ) * ( q2->
x - q1->
x ) );
490#ifdef GRAPH_DEBUG_PRINT
491 fprintf(stderr,
"p1 [%e %e] p2 [%e %e] q1 [%e %e] q2 [%e %e]\n", p1->
x, p1->
y, p2->
x, p2->
y, q1->
x, q1->
y, q2->
x, q2->
y);
492 fprintf(stderr,
"par %e\n", par);
496 fprintf(stderr,
"testIfIntersect: Parallel lines detected....\n");
497 fprintf(stderr,
"p1 [%e %e] p2 [%e %e] q1 [%e %e] q2 [%e %e]\n", p1->
x, p1->
y, p2->
x, p2->
y, q1->
x, q1->
y, q2->
x, q2->
y);
498 fprintf(stderr,
"par %e\n", par);
504 tp = ( ( p1->
x - q1->
x ) * ( q2->
y - q1->
y ) - ( q2->
x - q1->
x ) * ( p1->
y - q1->
y ) ) / par;
505 tq = ( ( p1->
x - p2->
x ) * ( p1->
y - q1->
y ) - ( p1->
x - q1->
x ) * ( p1->
y - p2->
y ) ) / par;
513 x = p1->
x + tp * ( p2->
x - p1->
x );
514 y = p1->
y + tp * ( p2->
y - p1->
y );
516 * alpha_p =
dist(p1->
x, p1->
y, x, y) /
dist(p1->
x, p1->
y, p2->
x, p2->
y);
517 * alpha_q =
dist(q1->
x, q1->
y, x, y) /
dist(q1->
x, q1->
y, q2->
x, q2->
y);
522 }
else if ( ( ( fabs(tp) <=
GT_EPS ) || ( fabs(1. - tp) <=
GT_EPS ) ) && ( ( tq >=
GT_EPS ) && ( tq <= ( 1. -
GT_EPS ) ) ) ) {
524 if ( fabs(tp) <=
GT_EPS ) {
526 * alpha_q =
dist(q1->
x, q1->
y, p1->
x, p1->
y) /
dist(q1->
x, q1->
y, q2->
x, q2->
y);
530 * alpha_q =
dist(q1->
x, q1->
y, p2->
x, p2->
y) /
dist(q1->
x, q1->
y, q2->
x, q2->
y);
533 }
else if ( ( ( fabs(tq) <=
GT_EPS ) || ( fabs(1. - tq) <=
GT_EPS ) ) && ( ( tp >=
GT_EPS ) && ( tp <= ( 1. -
GT_EPS ) ) ) ) {
535 if ( fabs(tq) <=
GT_EPS ) {
537 * alpha_p =
dist(p1->
x, p1->
y, q1->
x, q1->
y) /
dist(p1->
x, p1->
y, p2->
x, p2->
y);
541 * alpha_p =
dist(p1->
x, p1->
y, q2->
x, q2->
y) /
dist(p1->
x, p1->
y, p2->
x, p2->
y);
544 }
else if ( ( ( fabs(tq) <=
GT_EPS ) || ( fabs(1. - tq) <=
GT_EPS ) ) && ( ( fabs(tp) <=
GT_EPS ) || ( fabs(1. - tp) <=
GT_EPS ) ) ) {
546 if ( fabs(tq) <=
GT_EPS ) {
547 if ( ( fabs(tp) <=
GT_EPS ) ) {
555 if ( ( fabs(tp) <=
GT_EPS ) ) {
564 fprintf(stderr,
"testIfIntersect: unhandled case [tp %e, tq %e, par %e]\n", tp, tq, par);
578 Polygon :: PolygonVertexIterator it( &a);
583 node *auxs = NULL, *auxc = NULL, *is, *ic;
584 node *p1, *p2, *q1, *q2;
586 double alpha_s, alpha_c, alpha1, alpha2;
592 while ( it.giveNext(v) ) {
601 c->next =
c->prev =
c;
606 while ( it.giveNext(v) ) {
615 s->next =
s->prev =
s;
685 }
else if ( ret == 1 ) {
700 }
else if ( ret == 2 ) {
713 }
else if ( ret == 10 ) {
720 if ( alpha1 < alpha2 ) {
735 if ( alpha1 > alpha2 ) {
741 }
else if ( ret == 20 ) {
748 if ( alpha1 < alpha2 ) {
763 if ( alpha1 > alpha2 ) {
769 }
else if ( ret == 11 ) {
794 }
else if ( ret == 12 ) {
818 }
else if ( ret == 21 ) {
842 }
else if ( ret == 22 ) {
867 }
else if ( ret == 1102 ) {
883 }
else if ( ret == 1120 ) {
899 }
else if ( ret == 2102 ) {
917 }
else if ( ret == 2110 ) {
934 }
else if ( ret == 1201 ) {
950 }
else if ( ret == 1220 ) {
968 }
else if ( ret == 2201 ) {
986 }
else if ( ret == 2210 ) {
1004 }
else if ( ret == 110 ) {
1010 }
else if ( ret == 210 ) {
1016 }
else if ( ret == 120 ) {
1022 }
else if ( ret == 220 ) {
1028 }
else if ( ret == -1 ) {
1030 & alpha_s, & alpha_c, & xi, & yi);
1048 }
else if ( ret == 1 ) {
1053 bool _p1 =
false, _p2 =
false, _q1 =
false, _q2 =
false;
1057 if ( ( _p1 =
belongs(p1, q1, q2) ) ) {
1063 if ( ( _p2 =
belongs(p2, q1, q2) ) ) {
1069 if ( ( _q1 =
belongs(q1, p1, p2) ) ) {
1075 if ( ( _q2 =
belongs(q2, p1, p2) ) ) {
1080 if ( ( c1 == 1 ) || ( c2 == 1 ) ) {
1082 }
else if ( ( c1 > 1 ) || ( c2 > 1 ) ) {
1099 }
else if ( ret == 11 ) {
1105 }
else if ( ret == 22 ) {
1111 }
else if ( ret == 12 ) {
1117 }
else if ( ret == 21 ) {
1123 }
else if ( ret == 110 ) {
1132 }
else if ( ret == 120 ) {
1141 }
else if ( ret == 101 ) {
1150 }
else if ( ret == 102 ) {
1161 sprintf(buff,
"Graph::clip: unhandled return code (%d) from testIfIntersect service", ret);
1166 sprintf(buff,
"Graph::clip: unhandled return code (%d) from testIfCoincident service", ret);
1170 }
while ( ( auxc = auxc->next ) !=
c );
1172 }
while ( ( auxs = auxs->
next ) !=
s );
1174#ifdef GRAPH_DEBUG_PRINT
1184 bool identical =
true;
1189 if ( auxs->
entry != -1 ) {
1194 if ( auxs->
entry != -1 ) {
1204 xx = ( auxs->
x + xn ) * 0.5;
1205 yy = ( auxs->
y + yn ) * 0.5;
1210 if ( auxs->
entry != -1 ) {
1220 xx = ( 0.5 * ( auxs->
x + auxs->
neighbor->
x ) + xn ) * 0.5;
1221 yy = ( 0.5 * ( auxs->
y + auxs->
neighbor->
y ) + yn ) * 0.5;
1228 }
while ( auxs !=
s );
1234 if ( auxc->entry != -1 ) {
1237 xn = 0.5 * ( auxc->next->x + auxc->next->neighbor->x );
1238 yn = 0.5 * ( auxc->next->y + auxc->next->neighbor->y );
1244 xx = ( auxc->x + xn ) * 0.5;
1245 yy = ( auxc->y + yn ) * 0.5;
1249 if ( auxc->entry != -1 ) {
1252 xn = 0.5 * ( auxc->next->x + auxc->next->neighbor->x );
1253 yn = 0.5 * ( auxc->next->y + auxc->next->neighbor->y );
1259 xx = ( 0.5 * ( auxc->x + auxc->neighbor->x ) + xn ) * 0.5;
1260 yy = ( 0.5 * ( auxc->y + auxc->neighbor->y ) + yn ) * 0.5;
1266 }
while ( auxc !=
c );
1275 }
while ( auxs !=
s );
1276 }
else if ( cnt == 0 ) {
1277 xx = (
s->x +
s->next->x ) * 0.5;
1278 yy = (
s->y +
s->next->y ) * 0.5;
1286 }
while ( auxs !=
s );
1287 }
else if (
testPoint(
s, 0.5 * (
c->x +
c->next->x ), 0.5 * (
c->y +
c->next->y ) ) ) {
1294 }
while ( auxc !=
c );
1299 while ( ( crt =
first(
s) ) ) {
1303 if ( crt->
entry == 0 ) {
1307 if ( crt->
entry == 0 ) {
1310 }
else if ( crt->
entry == -1 ) {
1339#ifdef GRAPH_DEBUG_PRINT
1341 printf(
"Resulting Graph:\n");
1343 while ( it.giveNext(v) ) {
1344 printf(
"Node [xy %e %e %e]\n", v.
coords(0), v.
coords(1), 0.0);
1382 while ( aux->
next ) {
1407 }
while ( aux != p );
1438Graph :: dist(
double x1,
double y1,
double x2,
double y2)
1440 return sqrt( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) );
1444Graph :: createNode(
double x,
double y,
node *next,
node *prev,
node *nextPoly,
1445 node *neighbor,
nodeStatus st,
int entry,
int visited,
double alpha)
1473 while ( aux != last && aux->
alpha <= ins->
alpha ) {
1499 while ( aux != q2 ) {
1528 while ( aux != q2 ) {
1563 THROW_GT_EXCEPTIONM(
"Graph::vertex2IntersectionVertex: topology error, neighbor is unrelated intersectionVertex");
1596 double v_par, vp_par, vn_par;
1634 if ( v_par < vp_par ) {
1659 if ( v_par < vn_par ) {
1672 bool boundary =
false;
1684 THROW_GT_EXCEPTIONM(
"Graph::merge2vertex: consistency error (one of merged vertices (or both) linked to another vertex already");
1718Graph :: testPoint(
node *
s,
double x,
double y)
const
1720 bool oddNODES =
false;
1721 double x1, x2, y1, y2;
1731 if ( ( ( y1 < y ) && ( y2 >= y ) ) ||
1732 ( ( y2 < y ) && ( y1 >= y ) ) ) {
1733 if ( x1 + ( y - y1 ) / ( y2 - y1 ) * ( x2 - x1 ) < x ) {
1734 oddNODES = !oddNODES;
1739 }
while ( auxs !=
s );
1747Graph :: printYourself()
1751 printf(
"Graph 1/2:\n");
1755 printf(
"Vertex [xy %e %e %e] [e=%d]\n", auxs->
x, auxs->
y, 0.0, auxs->
entry);
1757 printf(
"IVertex [xy %e %e %e] [e=%d]\n", auxs->
x, auxs->
y, 0.0, auxs->
entry);
1759 printf(
"Intrsc [xy %e %e %e] [e=%d]\n", auxs->
x, auxs->
y, 0.0, auxs->
entry);
1763 }
while ( auxs !=
s );
1766 printf(
"Graph 2/2:\n");
1770 printf(
"Vertex [xy %e %e %e] [e=%d]\n", auxc->
x, auxc->
y, 0.0, auxc->
entry);
1772 printf(
"IVertex [xy %e %e %e] [e=%d]\n", auxc->
x, auxc->
y, 0.0, auxc->
entry);
1774 printf(
"Intrsc [xy %e %e %e] [e=%d]\n", auxc->
x, auxc->
y, 0.0, auxc->
entry);
1778 }
while ( auxc !=
c );
1785GT_Exception :: print()
1787 fprintf(stderr,
"\nGT_Exception thrown in %s:%d\n",
file,
line);
1789 fprintf(stderr,
"msg: %s\n",
msg);
void remove(std::vector< T > &cont, const T &t)
bool belongs(node *n, node *v1, node *v2)
int testIfIntersect(node *p1, node *p2, node *q1, node *q2, double *alpha_p, double *alpha_q, double *xint, double *yint)
int testPoint(node *poly, double x, double y) const
node * prev_node(node *p)
int testIfCoincident(node *p1, node *p2, node *q1, node *q2, double *alpha_1, double *alpha_2)
bool testCollapsedEdge(node *p1, node *p2)
node * createNode(double x, double y, node *next, node *prev, node *nextPoly, node *neighbor, nodeStatus st, int entry, int visited, double alpha)
double dist(double x1, double y1, double x2, double y2)
void merge2vertex(node *v1, node *v2)
void testNewIntersectionVertexEdgeCollapse(node *v, node *l1, node *l2)
void insert(node *ins, node *first, node *last)
node * next_node(node *p)
int vertex2IntersectionVertex(node *v, node *l1, node *l2)
void removeIntersectionIfExist(node *p1, node *p2, node *q1, node *q2)
int testPoint(double x, double y) const
void setCoords(double x, double y)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1).
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]