/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% o88°°88o o88°°88o o88°°88o 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 °°° 888 888 °°° 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 888 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 8888888° o8888888 °888888o 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 888 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 ooo 888 888 ooo 888 °8888888 %%%%%%%%%%%% %%%%%%%%%%%% °88oo88° °8888°88 °88oo88° 888 %%%%%%%%%%%% %%%%%%%%%%%% ooo 888 %%%%%%%%%%%% %%%%%%%%%%%% °888888° %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 %%%%%%%%%%%% %%%%%%%%%%%% 8888888o888o o88°°88o o88°°88o 888°°88o %%%%%%%%%%%% %%%%%%%%%%%% 888 888 88o 888 888 888 °°° 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 888 888 888 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 8888888° °888888o 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 888 888 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 888 ooo ooo 888 888 888 %%%%%%%%%%%% %%%%%%%%%%%% 888 888 888 °88oo88° °88oo88° 888 888 %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% Author: Bojan NICENO %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% address@hidden %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #define GRAPHICS OFF #include #include #include #include #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifndef PI #define PI 3.14159265359 #endif #define SMALL 1e-30 #define GREAT 1e+30 #define ON 0 #define OFF -1 /* element is switched off */ #define WAIT -2 /* node is waiting (it is a corner node) */ #define A 3 #define D 4 #define W 5 #define MAX_NODES 3000 /*-----------------------------+ | definitions for the chains | +-----------------------------*/ #define CLOSED 0 #define OPEN 1 #define INSIDE 2 struct ele { int i, j, k; int ei, ej, ek; int si, sj, sk; int mark; /* is it off (ON or OFF) */ int state; /* is it (D)one, (A)ctive or (W)aiting */ int material; double xv, yv, xin, yin, R, r, Det; int new_numb; /* used for renumeration */ } elem[MAX_NODES*2]; struct sid { int ea, eb; /* left and right element */ int a, b, c, d; /* left, right, start and end point */ int mark; /* is it off, is on the boundary */ double s; int new_numb; /* used for renumeration */ } side[MAX_NODES*3]; struct nod { double x, y, F; double sumx, sumy; int Nne; int mark; /* is it off */ int next; /* next node in the boundary chain */ int chain; /* on which chains is the node */ int inserted; int new_numb; /* used for renumeration */ } node[MAX_NODES], point[MAX_NODES/2]; struct seg {int n0, n1; int N; int chain; int bound; int mark;} *segment; struct chai {int s0, s1, type;} *chain; int Ne, Nn, Ns, Nc; /* number of: elements, nodes, sides */ int ugly; /* mora li biti globalna ??? */ /*=========================================================================*/ double area(struct nod *na, struct nod *nb, struct nod *nc) { return 0.5 * ( ((*nb).x-(*na).x)*((*nc).y-(*na).y) - ((*nb).y-(*na).y)*((*nc).x-(*na).x)); } /*-------------------------------------------------------------------------*/ /*=========================================================================*/ double dist(struct nod *na, struct nod *nb) { return sqrt( ((*nb).x-(*na).x)*((*nb).x-(*na).x) + ((*nb).y-(*na).y)*((*nb).y-(*na).y) ); } /*-------------------------------------------------------------------------*/ /*=========================================================================*/ in_elem(struct nod *n) { int e; for(e=0; e= 0.0 && area(n, &node[elem[e].j], &node[elem[e].k]) >= 0.0 && area(n, &node[elem[e].k], &node[elem[e].i]) >= 0.0 ) break; } return e; } /*-in_elem-----------------------------------------------------------------*/ /*=========================================================================*/ bowyer(int n, int spac) { int e, i, s, swap; struct nod vor; do { swap=0; for(s=0; s1 && node[side[s].d].bound==OFF && side[s].s<(node[side[s].c].F+node[side[s].d].F) ) || (node[side[s].d].inserted>1 && node[side[s].c].bound==OFF && side[s].s<(node[side[s].c].F+node[side[s].d].F) ) ) ) */ { if(side[s].a==n) {e=side[s].eb; if(e!=OFF) {vor.x=elem[e].xv; vor.y=elem[e].yv; if( dist(&vor, &node[n]) < elem[e].R ) {swap_side(s); swap=1;}}} else if(side[s].b==n) {e=side[s].ea; if(e!=OFF) {vor.x=elem[e].xv; vor.y=elem[e].yv; if( dist(&vor, &node[n]) < elem[e].R ) {swap_side(s); swap=1;}}} } } while(swap==1); } /*-bowyer------------------------------------------------------------------*/ /*=========================================================================*/ circles(int e) /*---------------------------------------------------+ | This function calculates radii of inscribed and | | circumscribed circle for a given element (int e) | +---------------------------------------------------*/ { double x, y, xi, yi, xj, yj, xk, yk, xij, yij, xjk, yjk, num, den; double si, sj, sk, O; xi=node[elem[e].i].x; yi=node[elem[e].i].y; xj=node[elem[e].j].x; yj=node[elem[e].j].y; xk=node[elem[e].k].x; yk=node[elem[e].k].y; xij=0.5*(xi+xj); yij=0.5*(yi+yj); xjk=0.5*(xj+xk); yjk=0.5*(yj+yk); num = (xij-xjk)*(xj-xi) + (yij-yjk)*(yj-yi); den = (xj -xi) *(yk-yj) - (xk -xj) *(yj-yi); if(den>0) { elem[e].xv = x = xjk + num/den*(yk-yj); elem[e].yv = y = yjk - num/den*(xk-xj); elem[e].R = sqrt( (xi-x)*(xi-x) + (yi-y)*(yi-y) ); } si=side[elem[e].si].s; sj=side[elem[e].sj].s; sk=side[elem[e].sk].s; O =si+sj+sk; elem[e].Det = xi*(yj-yk) - xj*(yi-yk) + xk*(yi-yj); elem[e].xin = ( xi*si + xj*sj + xk*sk ) / O; elem[e].yin = ( yi*si + yj*sj + yk*sk ) / O; elem[e].r = elem[e].Det / O; } /*-circles-----------------------------------------------------------------*/ /*=========================================================================*/ spacing(int e, int n) /*----------------------------------------------------------------+ | This function calculates the value of the spacing function in | | a new node 'n' which is inserted in element 'e' by a linear | | approximation from the values of the spacing function in the | | elements nodes. | +----------------------------------------------------------------*/ { double dxji, dxki, dyji, dyki, dx_i, dy_i, det, a, b; dxji = node[elem[e].j].x - node[elem[e].i].x; dyji = node[elem[e].j].y - node[elem[e].i].y; dxki = node[elem[e].k].x - node[elem[e].i].x; dyki = node[elem[e].k].y - node[elem[e].i].y; dx_i = node[n].x - node[elem[e].i].x; dy_i = node[n].y - node[elem[e].i].y; det = dxji*dyki - dxki*dyji; a = (+ dyki*dx_i - dxki*dy_i)/det; b = (- dyji*dx_i + dxji*dy_i)/det; node[n].F = node[elem[e].i].F + a*(node[elem[e].j].F - node[elem[e].i].F) + b*(node[elem[e].k].F - node[elem[e].i].F); } /*-spacing-----------------------------------------------------------------*/ /*=========================================================================*/ insert_node(double x, double y, int spac, int prev_n, int prev_s_mark, int mark, int next_s_mark, int next_n) { int i,j,k,en, n, e,ei,ej,ek, s,si,sj,sk; double sx, sy; Nn++; /* one new node */ node[Nn-1].x = x; node[Nn-1].y = y; node[Nn-1].mark = mark; /* find the element which contains new node */ e = in_elem(&node[Nn-1]); /* calculate the spacing function in the new node */ if(spac==ON) spacing(e, Nn-1); i =elem[e].i; j =elem[e].j; k =elem[e].k; ei=elem[e].ei; ej=elem[e].ej; ek=elem[e].ek; si=elem[e].si; sj=elem[e].sj; sk=elem[e].sk; Ne+=2; Ns+=3; /*---------------+ | new elements | +---------------*/ elem[Ne-2].i=Nn-1; elem[Ne-2].j=k; elem[Ne-2].k=i; elem[Ne-1].i=Nn-1; elem[Ne-1].j=i; elem[Ne-1].k=j; elem[Ne-2].ei=ej; elem[Ne-2].ej=Ne-1; elem[Ne-2].ek=e; elem[Ne-1].ei=ek; elem[Ne-1].ej=e; elem[Ne-1].ek=Ne-2; elem[Ne-2].si=sj; elem[Ne-2].sj=Ns-2; elem[Ne-2].sk=Ns-3; elem[Ne-1].si=sk; elem[Ne-1].sj=Ns-1; elem[Ne-1].sk=Ns-2; /*------------+ | new sides | +------------*/ side[Ns-3].c =k; side[Ns-3].d =Nn-1; /* c-d */ side[Ns-3].a =j; side[Ns-3].b =i; /* a-b */ side[Ns-3].ea=e; side[Ns-3].eb=Ne-2; side[Ns-2].c =i; side[Ns-2].d =Nn-1; /* c-d */ side[Ns-2].a =k; side[Ns-2].b =j; /* a-b */ side[Ns-2].ea=Ne-2; side[Ns-2].eb=Ne-1; side[Ns-1].c =j; side[Ns-1].d =Nn-1; /* c-d */ side[Ns-1].a =i; side[Ns-1].b =k; /* a-b */ side[Ns-1].ea=Ne-1; side[Ns-1].eb=e; for(s=1; s<=3; s++) {sx = node[side[Ns-s].c].x - node[side[Ns-s].d].x; sy = node[side[Ns-s].c].y - node[side[Ns-s].d].y; side[Ns-s].s = sqrt(sx*sx+sy*sy);} elem[e].i = Nn-1; elem[e].ej = Ne-2; elem[e].ek = Ne-1; elem[e].sj = Ns-3; elem[e].sk = Ns-1; if(side[si].a==i) {side[si].a=Nn-1; side[si].ea=e;} if(side[si].b==i) {side[si].b=Nn-1; side[si].eb=e;} if(side[sj].a==j) {side[sj].a=Nn-1; side[sj].ea=Ne-2;} if(side[sj].b==j) {side[sj].b=Nn-1; side[sj].eb=Ne-2;} if(side[sk].a==k) {side[sk].a=Nn-1; side[sk].ea=Ne-1;} if(side[sk].b==k) {side[sk].b=Nn-1; side[sk].eb=Ne-1;} if(ej!=-1) {if(elem[ej].ei==e) {elem[ej].ei=Ne-2;} if(elem[ej].ej==e) {elem[ej].ej=Ne-2;} if(elem[ej].ek==e) {elem[ej].ek=Ne-2;}} if(ek!=-1) {if(elem[ek].ei==e) {elem[ek].ei=Ne-1;} if(elem[ek].ej==e) {elem[ek].ej=Ne-1;} if(elem[ek].ek==e) {elem[ek].ek=Ne-1;}} /* Find circumenters for two new elements, and for the one who's segment has changed */ circles(e); circles(Ne-2); circles(Ne-1); bowyer(Nn-1, spac); /*-------------------------------------------------+ | NEW ! Insert boundary conditions for the sides | +-------------------------------------------------*/ for(s=3; s ratio) {ratio=max(ratio, elem[e].R/elem[e].r); ugly=e;} } /*-------------------------------------------------+ | Second part of the trick: | | if non-acceptable element on the boundary is | | found, ignore the elements inside the domain | +-------------------------------------------------*/ if(ugly==OFF) for(e=0; e ratio) {ratio=max(ratio, elem[e].R/elem[e].r); ugly=e;} } } } /*-classify----------------------------------------------------------------*/ /*=========================================================================*/ new_node() /*---------------------------------------------------+ | This function is very important. | | It determines the position of the inserted node. | +---------------------------------------------------*/ { int s=OFF, n, e; double xM, yM, xCa, yCa, p, px, py, q, qx, qy, rhoM, rho_M, d; struct nod Ca; /*-------------------------------------------------------------------------+ | It's obvious that elements which are near the boundary, will come into | | play first. | | | | However, some attention has to be payed for the case when two accepted | | elements surround the ugly one | | | | What if new points falls outside the domain | +-------------------------------------------------------------------------*/ if(elem[elem[ugly].ei].state==D) {s=elem[ugly].si; n=elem[ugly].i;} if(elem[elem[ugly].ej].state==D) {s=elem[ugly].sj; n=elem[ugly].j;} if(elem[elem[ugly].ek].state==D) {s=elem[ugly].sk; n=elem[ugly].k;} if(side[elem[ugly].si].mark > 0) {s=elem[ugly].si; n=elem[ugly].i;} if(side[elem[ugly].sj].mark > 0) {s=elem[ugly].sj; n=elem[ugly].j;} if(side[elem[ugly].sk].mark > 0) {s=elem[ugly].sk; n=elem[ugly].k;} if(s==OFF) return 0; xM = 0.5*(node[side[s].c].x + node[side[s].d].x); yM = 0.5*(node[side[s].c].y + node[side[s].d].y); Ca.x = elem[ugly].xv; Ca.y = elem[ugly].yv; p = 0.5*side[s].s; /* not checked */ qx = Ca.x-xM; qy = Ca.y-yM; q = sqrt(qx*qx+qy*qy); rhoM = 0.577 * 0.5*(node[side[s].c].F + node[side[s].d].F); rho_M = min( max( rhoM, p), 0.5*(p*p+q*q)/q ); if(rho_M < p) d=rho_M; else d=rho_M+sqrt(rho_M*rho_M-p*p); /*---------------------------------------------------------------------+ | The following line check can the new point fall outside the domain. | | However, I can't remember how it works, but I believe that it is | | still a weak point of the code, particulary when there are lines | | inside the domain | +---------------------------------------------------------------------*/ if( area(&node[side[s].c], &node[side[s].d], &Ca) * area(&node[side[s].c], &node[side[s].d], &node[n]) > 0.0 ) insert_node(xM + d*qx/q, yM + d*qy/q, ON, OFF, 0, 0, 0, OFF); /* else { node[n].x = xM - d*qx/q; node[n].y = yM - d*qy/q; node[n].mark=6; for(e=0; e=3; T--) for(s=0; s1 && dummy[strlen(dummy)-1]=='#') {} else if(dummy[0]=='#') {do{fscanf(in,"%c", &dum);} while(dum!='#');} else {*numb=atoi(dummy); break;} } } load_d(FILE *in, double *numb) { char dum, dummy[128]; for(;;) {fscanf(in,"%s", dummy); if(dummy[0]=='#' && strlen(dummy)>1 && dummy[strlen(dummy)-1]=='#') {} else if(dummy[0]=='#') {do{fscanf(in,"%c", &dum);} while(dum!='#');} else {*numb=atof(dummy); break;} } } load_s(FILE *in, char *string) { char dum, dummy[128]; for(;;) {fscanf(in,"%s", dummy); if(dummy[0]=='#' && strlen(dummy)>1 && dummy[strlen(dummy)-1]=='#') {} else if(dummy[0]=='#') {do{fscanf(in,"%c", &dum);} while(dum!='#');} else {strcpy(string, dummy); break;} } } /*-------------------------------------------------------------------------*/ /*=========================================================================*/ load() { int c, n, s, Fl, M, N0, chains, bound; char dummy[80]; double xmax=-GREAT, xmin=+GREAT, ymax=-GREAT, ymin=+GREAT, xt, yt, gab; FILE *in; int m; double xO, yO, xN, yN, xC, yC, L, Lx, Ly, dLm, ddL, L_tot; int *inserted; /*----------+ | | | Loading | | | +----------*/ if((in=fopen(name, "r"))==NULL) {fprintf(stderr, "Cannot load file %s !\n", name); return 1;} load_i(in, &Nc); inserted=(int *) calloc(Nc, sizeof(int)); for(n=0; n L ) && (segment[s].n0 != segment[s].n1) ) {point[segment[s].n0].F = min(point[segment[s].n0].F,L); point[segment[s].n1].F = min(point[segment[s].n1].F,L);} } /*-------------------------------------+ counting the nodes on each segment +-------------------------------------*/ for(s=0; s point[segment[s].n1].F) {M=-segment[s].N/2; ddL=(point[segment[s].n1].F-dLm)/M;} else {M=+segment[s].N/2; ddL=(dLm-point[segment[s].n0].F)/M;} } /*================= * middle points * =================*/ L_tot=0; if(point[segment[s].n0].F + point[segment[s].n1].F <= L) for(m=1; m point[segment[s].n1].F) {M++; if(M==0 && segment[s].N%2==0) M++;} else {M--; if(M==0 && segment[s].N%2==0) M--;} if(s==chain[c].s1 && m==(abs(segment[s].N)-1)) {insert_node(xO+Lx/L*L_tot, yO+Ly/L*L_tot, OFF, Nn-1, segment[s].mark, segment[s].mark, segment[s].mark, point[segment[s].n1].new_numb); node[Nn-1].next = Nn;} else if(m==1) {insert_node(xO+Lx/L*L_tot, yO+Ly/L*L_tot, OFF, point[segment[s].n0].new_numb, segment[s].mark, segment[s].mark, OFF, OFF); node[Nn-1].next = Nn;} else {insert_node(xO+Lx/L*L_tot, yO+Ly/L*L_tot, OFF, Nn-1, segment[s].mark, segment[s].mark, OFF, OFF); node[Nn-1].next = Nn;} node[Nn-1].chain = segment[s].chain; node[Nn-1].F = 0.5*(node[Nn-2].F + (dLm-M*ddL)); } /*============== * last point * -> just for the inside chains ==============*/ if( (point[segment[s].n1].new_numb == OFF) && (s==chain[c].s1) ) { insert_node(xN, yN, OFF, Nn-1, segment[s].mark, point[segment[s].n1].mark, OFF, OFF); node[Nn-1].next = OFF; node[Nn-1].chain = segment[s].chain; node[Nn-1].F = point[segment[s].n1].F; } if( chain[c].type==CLOSED && s==chain[c].s1) node[Nn-1].next = point[segment[chain[c].s0].n0].new_numb; if( chain[c].type==OPEN && s==chain[c].s1) node[Nn-1].next = OFF; } } free(segment); free(inserted); return 0; } /*-load--------------------------------------------------------------------*/ /*=========================================================================*/ save() { int e, s, n, r_Nn=0, r_Ns=0, r_Ne=0; struct nod *r_node; struct ele *r_elem; struct sid *r_side; FILE *out; r_node=(struct nod *) calloc(Nn, sizeof(struct nod)); r_elem=(struct ele *) calloc(Ne, sizeof(struct ele)); r_side=(struct sid *) calloc(Ns, sizeof(struct sid)); if(r_side==NULL) {fprintf(stderr, "Sorry, cannot allocate enough memory !\n"); return 1;} for(n=0; n0) /* It means, side is on the boundary */ { xc=node[side[s].c].x; yc=node[side[s].c].y; xd=node[side[s].d].x; yd=node[side[s].d].y; line_dxf(xc, yc, 0, xd, yd, 0, "boundary"); } /*----------------+ | Draw Delaunay | +----------------*/ for(s=0; s0) /* It means, side is on the boundary */ { xc=node[side[s].c].x; yc=node[side[s].c].y; xd=node[side[s].d].x; yd=node[side[s].d].y; line_fig ( 450+(int)floor(scl*xc), 450+(int)floor(scl*yc), 450+(int)floor(scl*xd), 450+(int)floor(scl*yd), 0, 3, 0, 0.000); } /*----------------+ | Draw Delaunay | +----------------*/ for(s=0; s #define B_CIRCLE(x1, y1, x2, y2) _ellipse(_GBORDER, x1, y1, x2, y2) #define I_CIRCLE(x1, y1, x2, y2) _ellipse(_GFILLINTERIOR, x1, y1, x2, y2) #define CLEARSCREEN _clearscreen(_GCLEARSCREEN) #define CLOSEGRAPH _setvideomode(_DEFAULTMODE) #define COLOR(b) _setcolor(b) #define FILL(x1, y1, color) _floodfill(x1, y1, color) #define GRTEXT(x1, y1, string) _moveto(x1, y1); _outgtext(string) #define LINE(x1, y1, x2, y2) _moveto(x1, y1); _lineto(x2,y2) #define OPEN_SVGA _setvideomode(_SVRES256COLOR) #define OPEN_VGA _setvideomode(_VRES16COLOR) #define RECTANGLE(x1, y1, x2, y2) _rectangle(_GBORDER, x1, y1, x2, y2) /*------------------------------------------------------------------------*/ /*=========================================================================*/ draw(int mesh, int voronoi, int marks, int fill) { int e, n, s, X0, Y0, ei, ej, ek, ea, eb; double scl, x, y, xc, yc, xd, yd, x1, y1, x2, y2, xmax=-GREAT, xmin=+GREAT, ymax=-GREAT, ymin=+GREAT; char numb[80]; for(n=0; n0) /* It means, side is on the boundary */ { if(marks==ON) COLOR(16-side[s].mark); else COLOR(15); xc=node[side[s].c].x; yc=node[side[s].c].y; xd=node[side[s].d].x; yd=node[side[s].d].y; LINE(xc*scl + X0, -yc*scl + Y0, xd*scl + X0, -yd*scl + Y0); } if(marks==ON) for(n=0; n0) /* node is on the boundary */ { COLOR(16-node[n].mark); x=node[n].x; y=node[n].y; I_CIRCLE(x*scl+X0+2, -y*scl+Y0+2, x*scl+X0-2, -y*scl+Y0-2); } } if(voronoi!=OFF) { if(voronoi==ON) COLOR(7); else COLOR(voronoi); for(s=0; s []"); printf("\n\n***************"); printf("\n*** OPTIONS ***"); printf("\n***************"); printf("\n\nValid options are:"); printf("\n -d don't triangulate domain"); printf("\n -g without graphic output"); printf("\n -m without messages"); printf("\n -r without relaxation"); printf("\n -s without Laplacian smoothing"); printf("\n +dxf create drawing in DXF format"); printf("\n +fig create drawing in fig format"); printf("\n +example create example input file"); printf("\n\n*************"); printf("\n*** INPUT ***"); printf("\n*************"); printf("\n\nInput file (NAME.d) has the following format"); printf("\n first line: "); printf("\n following Nbp lines: "); printf("\n one line: "); printf("\n following Nbs lines: "); printf("\n\n where:"); printf("\n Nbn is the number of points defining the boundary"); printf("\n Nbp is the number of sides defining the boundary"); printf("\n marker is the boundary condition marker"); printf("\n\nNote: Input file has to end with the extension: .d !"); printf("\n\n**************"); printf("\n*** OUTPUT ***"); printf("\n**************"); printf("\n\nEasyMesh produces the following three output files:"); printf("\n NAME.n"); printf("\n NAME.e"); printf("\n NAME.s"); printf("\n\nNode file (NAME.n) has the following format:"); printf("\n first line: "); printf("\n following Nn lines: "); printf("\n last two lines: comments inserted by the program "); printf("\n\n where:"); printf("\n Nn is the number of nodes"); printf("\n x, y are the node coordinates"); printf("\n marker is the node boundary marker"); printf("\n\nElement file (NAME.e) has the following format:"); printf("\n first line "); printf("\n following Ne lines: "); printf("\n last two lines: comments inserted by the program "); printf("\n\n where:"); printf("\n Ne is the number of elements"); printf("\n i, j, k are the nodes belonging to the element, "); printf("\n ei, ej, ek are the neighbouring elements,"); printf("\n si, sj, sk are the element sides. "); printf("\n xV, yV are the coordinates of the element circumcenter"); printf("\n marker is the side boundary marker"); printf("\n\nSide file (NAME.s) has the following format:"); printf("\n first line: "); printf("\n following Ns lines: "); printf("\n last two lines: comments inserted by the program "); printf("\n\n where:"); printf("\n Ns is the number of sides"); printf("\n c, d are the starting and ending node of the side,"); printf("\n ea, eb are the elements on the left and on the right of the side."); printf("\n\nNote: If eb equals to -1, it means that the right element does not exists,"); printf("\n i.e. the side is on the boundary !"); printf("\n\n"); return 0;} else {if(strcmp(argv[1], "+example")==0) exa=ON; strcpy(name, argv[1]); len=strlen(name); if(name[len-2]=='.') if(name[len-1]=='d' || name[len-1]=='D' ) name[len-2]='\0'; strcpy(dxf_name, name); strcat(dxf_name, ".dxf"); strcpy(fig_name, name); strcat(fig_name, ".fig");} /*-----------------------+ | command line options | +-----------------------*/ for(arg=2; arg EasyMesh example +fig"); fprintf(out, "\n "); fprintf(out, "\n if you want to see the results with xfig,"); fprintf(out, "\n or with"); fprintf(out, "\n"); fprintf(out, "\n > EasyMesh example +dxf"); fprintf(out, "\n"); fprintf(out, "\n if you want to see the results with some tool that"); fprintf(out, "\n suports Autodesk DXF format"); fprintf(out, "\n"); fprintf(out, "\n*******************************************************#"); fprintf(out, "\n"); fprintf(out, "\n#*********"); fprintf(out, "\n POINTS"); fprintf(out, "\n*********#"); fprintf(out, "\n8 # number of points defining the boundary #"); fprintf(out, "\n"); fprintf(out, "\n# rectangular domain #"); fprintf(out, "\n#-------+-----+-----+---------+--------#"); fprintf(out, "\n# point | x | y | spacing | marker #"); fprintf(out, "\n#-------+-----+-----+---------+--------#"); fprintf(out, "\n 0: 0.0 0.0 0.05 1"); fprintf(out, "\n 1: 2.0 0.0 0.25 2"); fprintf(out, "\n 2: 2.0 1.6 0.25 2"); fprintf(out, "\n 3: 0.0 1.6 0.1 1"); fprintf(out, "\n"); fprintf(out, "\n# square hole #"); fprintf(out, "\n#-------+-----+-----+---------+--------#"); fprintf(out, "\n# point | x | y | spacing | marker #"); fprintf(out, "\n#-------+-----+-----+---------+--------#"); fprintf(out, "\n 4: 0.5 0.5 0.05 3"); fprintf(out, "\n 5: 0.5 1.1 0.08 3"); fprintf(out, "\n 6: 1.1 1.1 0.2 3"); fprintf(out, "\n 7: 1.1 0.5 0.2 3"); fprintf(out, "\n"); fprintf(out, "\n#***********"); fprintf(out, "\n SEGMENTS"); fprintf(out, "\n***********#"); fprintf(out, "\n8 # number of segments #"); fprintf(out, "\n"); fprintf(out, "\n# domain #"); fprintf(out, "\n#---------+-----+-----+--------#"); fprintf(out, "\n# segment | 1st | 2nd | marker #"); fprintf(out, "\n#---------+-----+-----+--------#"); fprintf(out, "\n 0: 0 1 1"); fprintf(out, "\n 1: 1 2 2"); fprintf(out, "\n 2: 2 3 1"); fprintf(out, "\n 3: 3 0 1"); fprintf(out, "\n"); fprintf(out, "\n# hole #"); fprintf(out, "\n#---------+-----+-----+--------#"); fprintf(out, "\n# segment | 1st | 2nd | marker #"); fprintf(out, "\n#---------+-----+-----+--------#"); fprintf(out, "\n 4: 4 5 3"); fprintf(out, "\n 5: 5 6 3"); fprintf(out, "\n 6: 6 7 3"); fprintf(out, "\n 7: 7 4 3\n"); printf("\nThe file 'example.d' created !\n"); fclose(out); return 0; } } strcat(name, ".d"); len=strlen(name); if(load()!=0) return 1; erase(); classify(); if(m==ON) printf("Working. Please wait !\n"); fflush(stdout); if(d==ON) do { Nn0=Nn; new_node(); classify(); printf("%d\n", ugly); //test line added by wyan if(Nn==MAX_NODES-1) break; if(Nn==Nn0) break; } while(ugly!=OFF); neighbours(); if(r==ON || s==ON) if(m==ON) printf("Improving the grid quality. Please wait !\n"); fflush(stdout); if(r==ON) relax(); if(r==ON || s==ON) smooth(); if(m==ON) printf("Renumerating nodes, elements and sides. Please wait !\n"); fflush(stdout); renum(); if(m==ON) printf("Processing material marks. Please wait !\n"); fflush(stdout); materials(); #if GRAPHICS == ON if(g==ON) { do { printf("\n****************************"); printf("\n** Enter your choice: **"); printf("\n****************************\n\n"); printf("0. Exit\n"); printf("1. Delaunay\n"); printf("2. Voronoi\n"); printf("3. Delaunay and Voronoi\n"); printf("4. Materials\n"); printf("5. Boundary condition marks only\n"); printf("6. Boundary condition marks with Delaunay\n"); printf("7. Boundary condition marks with Voronoi\n\n"); printf("-> "); scanf("%d", &ans); switch(ans) { case 1: OPEN_SVGA; draw(11, OFF, OFF, OFF); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; case 2: OPEN_SVGA; draw(OFF, 12, OFF, OFF); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; case 3: OPEN_SVGA; draw(11, 12, OFF, OFF); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; case 4: OPEN_SVGA; draw(ON, OFF, OFF, ON ); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; case 5: OPEN_SVGA; draw(OFF, OFF, ON, OFF); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; case 6: OPEN_SVGA; draw(ON, OFF, ON, OFF); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; case 7: OPEN_SVGA; draw(OFF, ON, ON, OFF); printf("Press any key to continue !"); fflush(stdout); getch(); CLOSEGRAPH; break; } } while(ans!=0); } #endif save(); if(dxf==ON) {start_dxf(); draw_dxf(); end_dxf();} if(fig==ON) {start_fig(); draw_fig(); end_fig();} return 1; }