00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021
00022 #include <iostream>
00023
00024 #include "gul_types.h"
00025 #include "gul_error.h"
00026 #include "gul_vector.h"
00027 #include "gust_pool.h"
00028 #include "guge_normalize.h"
00029 #include "guar_exact.h"
00030 #include "gugr_basics.h"
00031 #include "gugr_regularize.h"
00032 #include "gugr_split.h"
00033 #include "gugr_triangulate.h"
00034 #include "gul_io.h"
00035 #include "gul_std.h"
00036 #include "gugr_planesweep.h"
00037 #include "gugr_io.h"
00038
00039
00040 namespace gul {
00041 GULAPI dump_format dump_defaults::m_format = human_readable;
00042 GULAPI dump_point_format dump_defaults::m_point_format = homogeneous;
00043 }
00044
00045 namespace gugr {
00046
00047
00048
00049 #ifdef __BORLANDC__
00050 template float Dump<float>::orgx;
00051 template float Dump<float>::orgy;
00052 template float Dump<float>::scalex;
00053 template float Dump<float>::scaley;
00054
00055 template double Dump<double>::orgx;
00056 template double Dump<double>::orgy;
00057 template double Dump<double>::scalex;
00058 template double Dump<double>::scaley;
00059 #else
00060 float Dump<float>::orgx;
00061 float Dump<float>::orgy;
00062 float Dump<float>::scalex;
00063 float Dump<float>::scaley;
00064
00065 double Dump<double>::orgx;
00066 double Dump<double>::orgy;
00067 double Dump<double>::scalex;
00068 double Dump<double>::scaley;
00069 #endif
00070
00071
00072
00073
00074
00075 #if 0
00076
00077
00078
00079 GULAPI
00080 bool TriangulatePolygon(
00081 int nContour, Ptr< polyline2<double> > contour, bool oddflag,
00082 int *nTA, Ptr< triangle2<double> > *TA )
00083 {
00084 double minx,maxx,miny,maxy,dx,dy,scale;
00085 int n,i;
00086 Ptr< point2<double> > P;
00087 graph_edge_list E;
00088 graph_vertex_list V;
00089 triangle_list T;
00090 rational farleft;
00091
00092 if( nContour == 0 ) return false;
00093
00094 if( (n = contour[0].n) <= 2 ) return false;
00095
00096 P = contour[0].P;
00097 if( P[0] != P[n-1] ) return false;
00098
00099 guge::CalcBoundingBoxE<double>( n-1, P, minx, maxx, miny, maxy );
00100 for( i = 1; i < nContour; i++ )
00101 {
00102 if( (n = contour[i].n) <= 2 ) return false;
00103 P = contour[i].P;
00104 if( P[0] != P[n-1] ) return false;
00105 guge::UpdateBoundingBoxE<double>( n-1, P, minx, maxx, miny, maxy );
00106 }
00107
00108 dx = maxx - minx;
00109 dy = maxy - miny;
00110 scale = dx > dy ? dx : dy;
00111 minx -= scale;
00112 miny -= scale;
00113
00114 SetDumpTransformation( minx, miny, scale, scale );
00115 for( i = 0; i < nContour; i++ )
00116 {
00117 PolygonToGraph( contour[i].n-1, (contour[i]).P, minx, miny, scale, scale,
00118 0, 1, &E, &V );
00119
00120 }
00121
00122 OrientEdges( E.head );
00123 Regularize( &E, &V );
00124
00125
00126
00127
00128
00129
00130 DrawEdges( E.head );
00131
00132
00133 Triangulate( &E, &V, farleft, &T );
00134 ConvertTriangles( &T, minx, miny, scale, scale, nTA, TA );
00135 return true;
00136 }
00137
00138
00139
00140
00141 GULAPI
00142 bool StripTriangulate(
00143 int nContour, Ptr< polyline2<double> > contour,
00144 int nStripsX, int nStripsY,
00145 double bx1, double by1, double bx2, double by2,
00146 Ptr< Ptr< int > > nTA,
00147 Ptr< Ptr< Ptr< triangle2<double> > > > TA )
00148 {
00149 double minx,maxx,miny,maxy,dx,dy,scale;
00150 Ptr< point2<double> > P;
00151 graph_edge_list E;
00152 graph_vertex_list V;
00153 int i, j, n, nMaxE;
00154 Ptr< cut_info > CutsX, CutsY;
00155 rational X1,X2,MinY,MaxY,FarMinY,FarMaxY,DeltaX;
00156 rational Y1,Y2,MinX,MaxX,FarMinX,FarMaxX,DeltaY;
00157 Ptr< point2<double> > dom;
00158 unsigned long *cbuf = (unsigned long *)alloca(gul::rtr<double>::mantissa_length());
00159 rational One(ULong(1));
00160 int k;
00161
00162
00163
00164
00165 dom.reserve_place( reserve_stack(point2<double>,2), 2 );
00166 graph_vertex *Vy1Sl, *Vy1Sr, *Vy2Sl, *Vy2Sr, *Vx1Sa, *Vx1Sb, *Vx2Sa, *Vx2Sb;
00167 int nCutsX, nCutsY;
00168 rational LeftX;
00169 graph_vertex *hvLeftT, *hvRightT;
00170 graph_edge *e, *er, **hE;
00171 vertex b;
00172 graph_vertex *a, *v, *v0;
00173 int match, iel, ier, cl, cr, nhE;
00174 bool oddflag;
00175 triangle_list T;
00176
00177 nCutsX = nStripsX+2; nCutsY = nStripsY+2;
00178
00179 if( (nCutsX < 4) || (nCutsY < 4) )
00180 return false;
00181
00182 minx = dom[0].x = bx1; miny = dom[0].y = by1;
00183 maxx = dom[1].x = bx2; maxy = dom[1].y = by2;
00184
00185 for( i = 0; i < nContour; i++ )
00186 {
00187 if( (n = contour[i].n) <= 2 ) return false;
00188 P = contour[i].P;
00189 if( P[0] != P[n-1] ) return false;
00190 guge::UpdateBoundingBoxE<double>( n-1, P, minx, maxx, miny, maxy );
00191 }
00192
00193 CutsX.reserve_place( reserve_stack(cut_info,nCutsX), nCutsX );
00194 CutsY.reserve_place( reserve_stack(cut_info,nCutsY), nCutsY );
00195
00196
00197
00198
00199
00200
00201 dx = maxx - minx;
00202 dy = maxy - miny;
00203 scale = dx > dy ? dx : dy;
00204 minx -= scale;
00205 miny -= scale;
00206
00207 guge::NormalizePointsE( 2, dom, minx, scale, miny, scale );
00208
00209 for( i = 0; i < nContour; i++ )
00210 {
00211 PolygonToGraph( contour[i].n-1, contour[i].P, minx, miny, scale, scale,
00212 0, 1, &E, &V );
00213 }
00214 SetDumpTransformation( minx, miny, scale, scale );
00215
00216 OrientEdges( E.head );
00217
00218 printf( "after construction of graph\n" );
00219 printf( "***************************\n" );
00220 DumpVertices( V.head );
00221 DumpEdges( E.head );
00222
00223 X1 = rational( coord2int(dom[0].x,cbuf),cbuf );
00224 X2 = rational( coord2int(dom[1].x,cbuf),cbuf );
00225 MinY = rational( ULong(1), -1 );
00226 MaxY = rational(coord2int((double)2,cbuf),cbuf)+One;
00227 FarMinY = rational(ULong(2),-1);
00228 FarMaxY = MaxY + One;
00229 DeltaX = (X2-X1)/rational(ULong(nCutsX-2));
00230
00231 Y1 = rational(coord2int(dom[0].y,cbuf),cbuf);
00232 Y2 = rational(coord2int(dom[1].y,cbuf),cbuf);
00233 MinX = MinY;
00234 MaxX = MaxY;
00235 FarMinX = FarMinY;
00236 FarMaxX = FarMaxY;
00237 DeltaY = (Y2-Y1)/rational(ULong(nCutsY-2));
00238
00239 CutsX[1].val = X1;
00240 for( i = 2; i < nCutsX-1; i++ )
00241 {
00242 CutsX[i].val = X1 + rational(ULong(i-1))*DeltaX;
00243 }
00244 CutsX[nCutsX-1].val = X2;
00245
00246 CutsY[1].val = Y1;
00247 for( i = 2; i < nCutsY-1; i++ )
00248 {
00249 CutsY[i].val = Y1 + rational(ULong(i-1))*DeltaY;
00250 }
00251 CutsY[nCutsY-1].val = Y2;
00252
00253 nMaxE = 10*E.nElems;
00254 hE = (graph_edge **)alloca( sizeof(graph_edge *) * nMaxE );
00255
00256
00257 IntersectWithVerticals( &E, &V, DeltaX, nCutsX, CutsX );
00258
00259
00260 DivideVerticalStrips( &CutsX[nCutsX-1], &CutsX[nCutsX-2], nMaxE,
00261 MinY, MaxY, FarMinY, FarMaxY,
00262 &Vy1Sr, &Vy1Sl, &Vy2Sr, &Vy2Sl );
00263
00264 printf( "after disconnecting X-Strip %d and %d\n", nCutsX-1, nCutsX-2 );
00265 printf( "****************************************\n" );
00266
00267 for( k = nCutsX-1; k >= 0; k-- )
00268 {
00269 printf( "X-Strip %d:\n", k );
00270 DumpVertices( CutsX[k].V.head );
00271 DumpEdges( CutsX[k].E.head );
00272 }
00273
00274 CutsX[nCutsX-1].R.DeleteElems();
00275 CutsX[nCutsX-1].E.DeleteElems();
00276 CutsX[nCutsX-1].V.DeleteElems();
00277
00278 for( i = nCutsX-2; i > 0; i-- )
00279 {
00280 DivideVerticalStrips( &CutsX[i], &CutsX[i-1], nMaxE,
00281 MinY, MaxY, FarMinY, FarMaxY,
00282 &Vy1Sr, &Vy1Sl, &Vy2Sr, &Vy2Sl );
00283
00284 printf( "after disconnecting X-Strip %d and %d\n", i, i-1 );
00285 printf( "****************************************\n" );
00286 for( k = i; k >= 0; k-- )
00287 {
00288 printf( "X-Strip %d:\n", k );
00289 DumpVertices( CutsX[k].V.head );
00290 DumpEdges( CutsX[k].E.head );
00291 }
00292
00293 LeftX = CutsX[i].val;
00294
00295
00296 IntersectWithHorizontals( &CutsX[i].E, &CutsX[i].V, DeltaY, nCutsY, CutsY );
00297
00298
00299 DivideHorizontalStrips( &CutsY[nCutsY-1], &CutsY[nCutsY-2], nMaxE,
00300 MinX, MaxX, FarMinX, FarMaxX,
00301 &Vx1Sa, &Vx1Sb, &Vx2Sa, &Vx2Sb );
00302
00303 printf( "after disconnecting Y-Strip %d and %d\n", j, j-1 );
00304 printf( "==========================================\n" );
00305 for( k = nCutsY-1; k >= 0; k-- )
00306 {
00307 printf( "Y-Strip %d:\n", k );
00308 DumpVertices( CutsY[k].V.head );
00309 DumpEdges( CutsY[k].E.head );
00310 }
00311
00312 CutsY[nCutsY-1].R.DeleteElems();
00313 CutsY[nCutsY-1].E.DeleteElems();
00314 CutsY[nCutsY-1].V.DeleteElems();
00315 hvLeftT = Vx1Sb; hvRightT = Vx2Sb;
00316
00317
00318 for( j = nCutsY-2; j > 0; j-- )
00319 {
00320 DivideHorizontalStrips( &CutsY[j], &CutsY[j-1], nMaxE,
00321 MinX, MaxX, FarMinX, FarMaxX,
00322 &Vx1Sa, &Vx1Sb, &Vx2Sa, &Vx2Sb );
00323
00324 printf( "after disconnecting Y-Strip %d and %d\n", j, j-1 );
00325 printf( "==========================================\n" );
00326 for( k = j; k >= 0; k-- )
00327 {
00328 printf( "Y-Strip %d:\n", k );
00329 DumpVertices( CutsY[k].V.head );
00330 DumpEdges( CutsY[k].E.head );
00331 }
00332
00333
00334 e = hvLeftT->e;
00335 a = e->v[0];
00336 b = vertex(point2<rational>(LeftX,FarMinY));
00337
00338 nhE = EdgeCycle( e, a, hE );
00339 match = EdgeInsertPosition( a->v, b, nhE, hE, &iel, &ier, &cl, &cr );
00340 gul::Assert<gul::InternalError>( ndebug || (match == 2) );
00341
00342 er = hE[ier];
00343 oddflag = (er->f[0] != 0);
00344
00345 v0 = hvLeftT;
00346 v = a;
00347 er = hE[nhE-1];
00348 if( er->v[0] == v ) er->e[0] = e->e[0]; else er->e[1] = e->e[0];
00349 v->e = er;
00350 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
00351 delete v0; delete e;
00352
00353 v0 = hvRightT;
00354 e = v0->e;
00355 v = e->v[1];
00356 nhE = EdgeCycle( e, v, hE );
00357 er = hE[nhE-1];
00358 if( er->v[0] == v ) er->e[0] = e->e[1]; else er->e[1] = e->e[1];
00359 v->e = er;
00360 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
00361 delete v0; delete e;
00362
00363 v0 = Vx2Sa;
00364 e = v0->e;
00365 v = e->v[1];
00366 nhE = EdgeCycle( e, v, hE );
00367 er = hE[nhE-1];
00368 if( er->v[0] == v ) er->e[0] = e->e[1]; else er->e[1] = e->e[1];
00369 v->e = er;
00370 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
00371 delete v0; delete e;
00372
00373 v0 = Vx1Sa;
00374 e = v0->e;
00375 v = e->v[0];
00376 nhE = EdgeCycle( e, v, hE );
00377 er = hE[nhE-1];
00378 if( er->v[0] == v ) er->e[0] = e->e[0]; else er->e[1] = e->e[0];
00379 v->e = er;
00380 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
00381 delete v0; delete e;
00382
00383 hvLeftT = Vx1Sb; hvRightT = Vx2Sb;
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 Regularize( &(CutsY[j].E), &(CutsY[j].V) );
00394
00395
00396
00397
00398 Triangulate( &(CutsY[j].E), &CutsY[j].V, FarMinX, &T );
00399 ConvertTriangles( &T, minx, miny, scale, scale,
00400 &(nTA[j-1][i-1]), &(TA[j-1][i-1]) );
00401 T.DeleteElems();
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 CutsY[j].R.DeleteElems();
00412 CutsY[j].E.DeleteElems();
00413 CutsY[j].V.DeleteElems();
00414 }
00415
00416
00417
00418
00419 CutsY[0].R.DeleteElems();
00420 CutsY[0].E.DeleteElems();
00421 CutsY[0].V.DeleteElems();
00422
00423 CutsX[i].R.DeleteElems();
00424 CutsX[i].E.DeleteElems();
00425 CutsX[i].V.DeleteElems();
00426 }
00427
00428 return true;
00429 }
00430
00431
00432
00433
00434
00435 void ConvertEdges( graph_edge_list *E,
00436 double orgx, double orgy,
00437 double scalex, double scaley,
00438 int *nLA, Ptr< line2<double> > *LA )
00439 {
00440 graph_edge *e;
00441 double x1,x2,y1,y2;
00442 int i;
00443 Interval ix,iy;
00444 Ptr< line2<double> > L;
00445
00446 *nLA = E->nElems;
00447 L.reserve_pool( E->nElems );
00448 e = E->head;
00449
00450 i = 0;
00451 while( e != NULL )
00452 {
00453 ix = e->v[0]->v.v().m_x.GetBounds();
00454 iy = e->v[0]->v.v().m_y.GetBounds();
00455 x1 = (ix.m_low+ix.m_high)/2.0;
00456 y1 = (iy.m_low+iy.m_high)/2.0;
00457
00458 ix = e->v[1]->v.v().m_x.GetBounds();
00459 iy = e->v[1]->v.v().m_y.GetBounds();
00460 x2 = (ix.m_low+ix.m_high)/2.0;
00461 y2 = (iy.m_low+iy.m_high)/2.0;
00462
00463 x1 = cnv2coord(x1)*scalex + orgx;
00464 x2 = cnv2coord(x2)*scalex + orgx;
00465 y1 = cnv2coord(y1)*scaley + orgy;
00466 y2 = cnv2coord(y2)*scaley + orgy;
00467
00468 L[i].P1.x = x1; L[i].P1.y = y1;
00469 L[i].P2.x = x2; L[i].P2.y = y2;
00470 i++;
00471
00472 e = e->next;
00473 }
00474 *LA = L;
00475 }
00476
00477
00478
00479
00480 void ConvertTriangles( triangle_list *TL,
00481 double orgx, double orgy,
00482 double scalex, double scaley,
00483 int *nTA, Ptr< triangle2<double> > *TA )
00484 {
00485 Interval ix,iy;
00486 double x1,x2,x3,y1,y2,y3;
00487 triangle *t;
00488 int i;
00489 Ptr< triangle2<double> > T;
00490
00491 T.reserve_pool(TL->nElems);
00492
00493 t = TL->head;
00494 i = 0;
00495 while( t != NULL )
00496 {
00497 ix = t->v[0].v().m_x.GetBounds();
00498 iy = t->v[0].v().m_y.GetBounds();
00499 x1 = (ix.m_low+ix.m_high)/2.0;
00500 y1 = (iy.m_low+iy.m_high)/2.0;
00501
00502 ix = t->v[1].v().m_x.GetBounds();
00503 iy = t->v[1].v().m_y.GetBounds();
00504 x2 = (ix.m_low+ix.m_high)/2.0;
00505 y2 = (iy.m_low+iy.m_high)/2.0;
00506
00507 ix = t->v[2].v().m_x.GetBounds();
00508 iy = t->v[2].v().m_y.GetBounds();
00509 x3 = (ix.m_low+ix.m_high)/2.0;
00510 y3 = (iy.m_low+iy.m_high)/2.0;
00511
00512 x1 = cnv2coord(x1)*scalex + orgx;
00513 x2 = cnv2coord(x2)*scalex + orgx;
00514 x3 = cnv2coord(x3)*scalex + orgx;
00515
00516 y1 = cnv2coord(y1)*scaley + orgy;
00517 y2 = cnv2coord(y2)*scaley + orgy;
00518 y3 = cnv2coord(y3)*scaley + orgy;
00519
00520 T[i].P1.x = x1; T[i].P1.y = y1;
00521 T[i].P2.x = x2; T[i].P2.y = y2;
00522 T[i].P3.x = x3; T[i].P3.y = y3;
00523 i++;
00524 t = t->next;
00525
00526
00527
00528
00529
00530
00531
00532
00533 }
00534 *TA = T;
00535 *nTA = i;
00536
00537 }
00538
00539
00540
00541
00542
00543 float Dump<float>::orgx;
00544 float Dump<float>::orgy;
00545 float Dump<float>::scalex;
00546 float Dump<float>::scaley;
00547
00548 double Dump<double>::orgx;
00549 double Dump<double>::orgy;
00550 double Dump<double>::scalex;
00551 double Dump<double>::scaley;
00552
00553 double orgx,orgy,scalex,scaley;
00554
00555 GULAPI
00556 void (*DrawMarkFunc) ( point2<double> P1, point2<double> P2,
00557 point2<double> P3 );
00558 GULAPI
00559 void (*DrawLineFunc) ( point2<double> P1, point2<double> P2 );
00560
00561 void SetDumpTransformation( double aorgx, double aorgy,
00562 double ascalex, double ascaley )
00563 {
00564 orgx = aorgx;
00565 orgy = aorgy;
00566 scalex = ascalex;
00567 scaley = ascaley;
00568 }
00569
00570 void DumpVertices( graph_vertex *V )
00571 {
00572 graph_vertex *v;
00573 double x1,y1;
00574
00575 v = V;
00576
00577 printf( "VERTICES\n" );
00578
00579 while( v != NULL )
00580 {
00581 v->v.v().m_x.Dump(x1);
00582 v->v.v().m_y.Dump(y1);
00583
00584 x1 = cnv2coord(x1)*scalex + orgx;
00585 y1 = cnv2coord(y1)*scaley + orgy;
00586 printf( "%p: (%0.8f, %0.8f), %p]\n", v, x1, y1, v->e );
00587
00588 v = v->next;
00589 }
00590
00591 fflush(stdout);
00592 }
00593
00594 void DumpEdges( graph_edge *E )
00595 {
00596 graph_edge *e;
00597 double x1,x2,y1,y2;
00598 int i = 1;
00599
00600 e = E;
00601
00602 printf( "EDGES\n" );
00603
00604 while( e != NULL )
00605 {
00606 e->v[0]->v.v().m_x.Dump(x1);
00607 e->v[0]->v.v().m_y.Dump(y1);
00608 e->v[1]->v.v().m_x.Dump(x2);
00609 e->v[1]->v.v().m_y.Dump(y2);
00610
00611 x1 = cnv2coord(x1)*scalex + orgx;
00612 x2 = cnv2coord(x2)*scalex + orgx;
00613 y1 = cnv2coord(y1)*scaley + orgy;
00614 y2 = cnv2coord(y2)*scaley + orgy;
00615
00616 printf( "%p: [%d,%d] [%p=(%0.8f, %0.8f), %p] [%p=(%0.8f, %0.8f), %p]\n", e,
00617 e->f[0], e->f[1], e->v[0], x1, y1, e->e[0],
00618 e->v[1], x2, y2, e->e[1] );
00619
00620 i++;
00621 e = e->next;
00622 }
00623
00624 fflush(stdout);
00625 }
00626
00627 void DrawEdges( graph_edge *E )
00628 {
00629 graph_edge *e;
00630 double x1,x2,y1,y2;
00631 double u = (scalex+scaley)/80.0, r;
00632 point2<double> m,n,d,beg,end;
00633 if( DrawLineFunc == 0 ) return;
00634 if( DrawMarkFunc == 0 ) return;
00635
00636 e = E;
00637
00638 while( e != NULL )
00639 {
00640 e->v[0]->v.v().m_x.Dump(x1);
00641 e->v[0]->v.v().m_y.Dump(y1);
00642 e->v[1]->v.v().m_x.Dump(x2);
00643 e->v[1]->v.v().m_y.Dump(y2);
00644
00645 x1 = cnv2coord(x1)*scalex + orgx;
00646 x2 = cnv2coord(x2)*scalex + orgx;
00647 y1 = cnv2coord(y1)*scaley + orgy;
00648 y2 = cnv2coord(y2)*scaley + orgy;
00649
00650 beg.x = x1;
00651 beg.y = y1;
00652 end.x = x2;
00653 end.y = y2;
00654
00655 DrawLineFunc( beg, end );
00656
00657 m.x = (x1+x2)/2.0;
00658 m.y = (y1+y2)/2.0;
00659 d.x = (x2-x1)/2.0;
00660 d.y = (y2-y1)/2.0;
00661 n.x = -d.y;
00662 n.y = d.x;
00663 r = 1.0 / sqrt( d.x*d.x + d.y*d.y );
00664 d = r*d;
00665 n = r*n;
00666
00667 if( e->f[0] > 0 )
00668 DrawMarkFunc( m-u*d, m+u*d, m+u*n );
00669
00670 if( e->f[1] > 0 )
00671 DrawMarkFunc( m-u*d, m+u*d, m-u*n );
00672
00673 e = e->next;
00674 }
00675 }
00676
00677
00678
00679 void DrawTriangles( FILE *out, triangle_list *T, double orgx, double orgy,
00680 double scalex, double scaley )
00681 {
00682 Interval ix,iy;
00683 double x1,x2,x3,y1,y2,y3;
00684 triangle *t;
00685
00686 fprintf( out, "LINE_LIST\n" );
00687 fprintf( out, "%d\n", T->nElems*3 );
00688
00689 t = T->head;
00690 while( t != NULL )
00691 {
00692 ix = t->v[0].v().m_x.GetBounds();
00693 iy = t->v[0].v().m_y.GetBounds();
00694 x1 = (ix.m_low+ix.m_high)/2.0;
00695 y1 = (iy.m_low+iy.m_high)/2.0;
00696
00697 ix = t->v[1].v().m_x.GetBounds();
00698 iy = t->v[1].v().m_y.GetBounds();
00699 x2 = (ix.m_low+ix.m_high)/2.0;
00700 y2 = (iy.m_low+iy.m_high)/2.0;
00701
00702 ix = t->v[2].v().m_x.GetBounds();
00703 iy = t->v[2].v().m_y.GetBounds();
00704 x3 = (ix.m_low+ix.m_high)/2.0;
00705 y3 = (iy.m_low+iy.m_high)/2.0;
00706
00707 x1 = cnv2coord(x1)*scalex + orgx;
00708 x2 = cnv2coord(x2)*scalex + orgx;
00709 x3 = cnv2coord(x3)*scalex + orgx;
00710
00711 y1 = cnv2coord(y1)*scaley + orgy;
00712 y2 = cnv2coord(y2)*scaley + orgy;
00713 y3 = cnv2coord(y3)*scaley + orgy;
00714
00715 fprintf( out, "%0.15e %0.15e %0.15e %0.15e %0.15e %0.15e\n",
00716 x1, y1, 0.0, x2, y2, 0.0 );
00717 fprintf( out, "%0.15e %0.15e %0.15e %0.15e %0.15e %0.15e\n",
00718 x2, y2, 0.0, x3, y3, 0.0 );
00719 fprintf( out, "%0.15e %0.15e %0.15e %0.15e %0.15e %0.15e\n",
00720 x3, y3, 0.0, x1, y1, 0.0 );
00721
00722 t = t->next;
00723 }
00724 }
00725 #endif
00726
00727 }
00728