⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wzdelaunay.cxx

📁 Delaunay三角形的网格剖分程序
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#include <float.h>#include <math.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "ibg2.hxx"void wzCellTypeInit(); ibgDelaunayMarker::ibgDelaunayMarker()  :dsl((1+IBG2CSMAX)*sizeof(int))  ,dsc(dsl.base)  ,nsl(3*sizeof(int))  ,nsc(nsl.base)  ,nsco(nsc,1)  ,nscs(nsc,2){  for(int i=0;i<IBG2CSMAX;i++){    dscl[i].reinitialize(dsc,1+i);  }}void wzDelaunayGenerator::Delaunay(wzpoints plist, cogeometry cog){  wzCellTypeInit();  initializeDelaunayBox(plist->min,plist->max);  include(plist);  try{    defineRegions(cog);    createFaces(cog);  }catch(...){;}}void wzDelaunayGenerator::Delaunay(wzpoints plist){  wzCellTypeInit();  initializeDelaunayBox(plist->min,plist->max);  include(plist);}void wzDelaunayGenerator::include(wzpoints plist){  switch(gdim()){  case 0: Delaunay0(plist); break;  case 1: Delaunay1(plist); break;  case 2: Delaunay2(plist); break;  case 3: Delaunay3(plist); break;  }}#define ibg2pX(point)		((point).X)#define ibg2pF(point)		((point).X+wzPointDim)#define ibg2pI(point)		((point).I)#define ibg2pSegment(point)	((point).S.index())#define ibg2pType(point)	((point).S.codim())#define ibg2pSetSegment(point,tt,uu)	((point).S = wzSegment((wzIndex)(uu),(wzDimension)(tt)))const wzFloat	ibgDelaunayBig  = 10000.0;const wzFloat	ibgDelaunayEps  = 2.e-6;static wzFloat	ibgDelaunayEps2;static wzFloat	ibgDelaunayEps3;static int hcn3[16] = {1,3,2,5, 1,5,2,4, 1,4,2,6, 1,6,2,3};static int hcs3[16] = {0,2,0,4, 0,3,0,1, 0,4,0,2, 0,1,0,3};static int hcn2[ 6] = {1,3,2,  1,2,4};static int hcs2[ 6] = {0,2,0,  0,0,1};static int hcn1[ 2] = {1,2};static int hcs1[ 2] = {0,0};static int hcnum[4] = {0,1,2,4};static int* hcn[ 4] = {0,hcn1,hcn2,hcn3};static int* hcs[ 4] = {0,hcs1,hcs2,hcs3};static wzCellType hctyp[4] = {wzCellType0Node,wzCellType1Line,wzCellType2Triangle,wzCellType3Tetrahedron};void wzDelaunayGenerator::initializeDelaunayBox(wzFloat* min, wzFloat* max){  int i,j,c,*n,*s,*hn,*hs;  wzFloat m[wzPointDim],d0,dd;  ibgSphere cvert;  for(i=0;i<xdim();i++){    Grid.mincoord[i+1] = min[i];     Grid.maxcoord[i+1] = max[i];  }  if(gdim()==0) return;  Grid.points.create(2*gdim());  for(i=1;i<=hcnum[gdim()];i++){    j = createCell(hctyp[gdim()]);  }  d0 = 0;  for(i=0;i<xdim();i++){    m[i] = (min[i]+max[i])/2; dd = max[i]-min[i]; if(dd>d0) d0=dd;  }  //  ibgDelaunayEps1 = d0*ibgDelaunayEps;  ibgDelaunayEps2 = d0*ibgDelaunayEps*(max[0]-min[0])*ibgDelaunayEps;  ibgDelaunayEps3 =     (max[0]-min[0])*ibgDelaunayEps*    (max[1]-min[1])*ibgDelaunayEps*    (max[2]-min[2])*ibgDelaunayEps;  d0 *= ibgDelaunayBig;  for(i=0;i<gdim();i++){    for(j=0;j<xdim();j++){      Grid.Point[2*i+1][j] = Grid.Point[2*i+2][j] = cvert.x1[j] = cvert.x2[j] = m[j];    }    Grid.Point[2*i+1][i] -= d0;    Grid.Point[2*i+2][i] += d0;    cnc(2*i+1) = cnc(2*i+2) = 1;    cns(2*i+1,wzIsRegion,0);    cns(2*i+2,wzIsRegion,0);  }  cvert.x1[0] -= d0;  cvert.x2[0] += d0;  hn = hcn[gdim()]; hs = hcs[gdim()];  wzRangeLoop(Grid.cells,c){    ccv(c)=cvert;    n = ccn(c); s = ccs(c);    for(i=0;i<wzCellTypepoints[hctyp[gdim()]];i++){*n++ = *hn++;}    for(i=0;i<wzCellTypesides [hctyp[gdim()]];i++){*s++ = *hs++;}  }}static int LastUsedCell;int wzDelaunayGenerator::g1find(wzFloat *xx, int c0){  int *cn0;  if(ccu(c0)<0){    c0 = 1;    while (ccu(c0)<0) c0++;  }beg:  wzAssert(ccu(c0)>=0);  cn0=ccn(c0);  if(xx[0]<cnx(cn0[0])[0]) {c0=ccs(c0)[0]; goto beg;}   if(xx[0]>cnx(cn0[1])[0]) {c0=ccs(c0)[1]; goto beg;}   return LastUsedCell = c0;}int wzDelaunayGenerator::g2find(wzFloat *xx, int c0){  int nl,*cn0;  wzCellType t;  int i;  wzFloat vv,x1,x2,y1,y2;  wzFloat* ff[IBG2CSMAX];  register wzFloat *fj;  if(ccund(c0)) c0 = LastUsedCell;  if(ccund(c0)){    wzRangeLoop(Grid.cells,c0){      if(ccund(c0)) continue;      break;    }  }beg:  wzAssert(!ccund(c0));  wzAssert(ccu(c0)>=0);  nl=wzCellTypePoints(t=cct(c0)); cn0=ccn(c0);  for(i=0;i<nl;i++) ff[i]=cnx(cn0[i]);  for(i=0;i<nl;i++){    fj = ff[wzCellTypeSPoint1(t,i,0)];    x1 = fj[0]-xx[0]; y1=fj[1]-xx[1];    fj = ff[wzCellTypeSPoint1(t,i,1)];    x2 = fj[0]-xx[0]; y2=fj[1]-xx[1];    vv = x1 * y2 - x2 * y1;    if(vv<-ibgDelaunayEps2) {c0=ccs(c0)[i]; goto beg;}  }  return LastUsedCell = c0;}int wzDelaunayGenerator::g3find(wzFloat *xx, int c0){  register int nl,*cn0;  int i,sl;  wzCellType t;  long double vv,x1,x2,x3,y1,y2,y3,z1,z2,z3,xx0=xx[0],xx1=xx[1],xx2=xx[2];  wzFloat* ff[IBG2CNMAX];  register wzFloat *fj;  if(ccund(c0)) c0 = LastUsedCell;  if(ccund(c0)){    wzRangeLoop(Grid.cells,c0){      if(ccund(c0)) continue;      break;    }  }beg:  wzAssert(!ccund(c0));  wzAssert(ccu(c0)>=0);  nl=wzCellTypePoints(t=cct(c0)); cn0=ccn(c0);  for(i=0;i<nl;i++) ff[i]=cnx(cn0[i]);  sl=wzCellTypeSides(t);  for(i=0;i<sl;i++){    fj = ff[wzCellTypeSPoint1(t,i,0)];    x1 = ((long double)fj[0])-xx0;y1=((long double)fj[1])-xx1;z1=((long double)fj[2])-xx2;    fj = ff[wzCellTypeSPoint1(t,i,1)];    x2 = ((long double)fj[0])-xx0;y2=((long double)fj[1])-xx1;z2=((long double)fj[2])-xx2;    fj = ff[wzCellTypeSPoint1(t,i,2)];    x3 = ((long double)fj[0])-xx0;y3=((long double)fj[1])-xx1;z3=((long double)fj[2])-xx2;    vv = x1 * (y2*z3-y3*z2) + x2 * (y3*z1-y1*z3) + x3 * (y1*z2-y2*z1);    if(vv>ibgDelaunayEps3) {c0=ccs(c0)[i]; goto beg;}  }  return LastUsedCell = c0;}int   wzDelaunayGenerator::Delaunay0(wzpoints list){  if(int l = list->last()){    int c = createCell(wzCellType0Node);    int n = Grid.points.append();    ccn(c)[0]=n; cnc(n) = c;    wzPoint& p = Grid.Point[ccn(c)[0]];    p = list->Point[list->first()];  }  return wzSuccess;}int   wzDelaunayGenerator::Delaunay1(wzpoints list){  int n,n0,c0,c1,cs,no,nb,nshift;  n0 = nb = Grid.points.append(list->length());  nshift = nb - list->first(); n0--;  wzRangeLoop(*list,n){    n0++;    Grid.Point[n0]=list->Point[n];    // Suche nach einer Zelle, die n0 enth"alt:     no = list->Near[n] + nshift;    if(no<nb) no = n0-1;    c0=g1find(cnx(n0),cnc(no));    c1 = createCell(wzCellType1Line);    ccs(c1)[1] = cs = ccs(c0)[1];    ccs(c0)[1] = ccs(cs)[0] = c1;    ccs(c1)[0] = c0;      ccn(c1)[1] = ccn(c0)[1];    ccn(c1)[0] = ccn(c0)[1] = n0;    cnc(n0)    = c1;    ccu(c1)    = ccu(c0)    = 0;  }  return wzSuccess;}int   wzDelaunayGenerator::Delaunay2(wzpoints list){  int n,s,s0,sh,ms,i,i0,ih,j,del;  int n0,no,nb,nt,nshift,nh,c0,c1,cc,ct,ch,co,cl;  int *cs0,*cs1,*csi,*csj,*csh,*cn0,*cni,*cnj,*cnh,*ss,*se;  wzFloat *cx1,*cx2;  wzFloat x,y,x1,x2,y1,y2;  wzFloat l1,l2,det,mx,my;  wzCellType t,t0,t1,th,tt;  wzPoint nd;  ibgSphere v;  int dsi,ds0,dsh,nsi;  LastUsedCell=0;  n0 = nb = Grid.points.append(list->length());  nshift = nb - list->first(); n0--;  wzRangeLoop(*list,n){    n0++;    Grid.Point[n0]=list->Point[n];    // Suche nach einer Zelle, die n0 enth"alt:     no = list->Near[n] + nshift;    if(no<nb) no = n0-1;    c0=g2find(cnx(n0),cnc(no));    x=cnx(n0)[0]; y=cnx(n0)[1];    nsl=0; dsl=0; dsi=1; dsc[++dsl]=c0; ccu(c0)= -dsl;    while(dsi<=dsl){      c0  = dsc[dsi];      cs0 = ccs(c0); ms=wzCellTypeSides((t0=cct(c0)));      cn0 = ccn(c0);      for(s=0;s<ms;s++){	cc= cs0[s];	if(cc<=0) {del=0; goto deltest;}	if(ccu(cc)<0) {(dscl[s])[dsi]= -1; continue;}	v = ccv(cc); t = cct(cc);	if((    (v.x1[0]-x)*(v.x2[0]-x)		+   (v.x1[1]-y)*(v.x2[1]-y)) < ibgDelaunayEps2)	del=1;	else							del=0;      deltest:	if(del){	  dsc[++dsl] = cc; ccu(cc) = -dsl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -