wzdelaunay.cxx

来自「有限元学习研究用源代码(老外的),供科研人员参考」· CXX 代码 · 共 548 行 · 第 1/2 页

CXX
548
字号
	  dscl[s][dsi] = -1;
	}else{
	  wzAssert(wzCellTypeSSize(t0,s)==2);
	  c1 = createCell(wzCellType2Triangle);
	  cni=ccn(c1); csi=ccs(c1);
	  cn0 = ccn(c0);
	  cs0 = ccs(c0);
	  cni[0]=n0; cnc(n0)=c1; cni++; cnj=cni;
	  csi[0]=cc; csi++;
	  for(i=0;i<2;i++){
	    cni[i]  = nt = cn0[wzCellTypeSPoint1(t0,s,i)];
	    cnc(nt) = c1; csi[i] = -1;
	  }
	  cx1=cnx(*cnj++); cx2=cnx(*cnj++);
	  x1=cx1[0]-x; y1=cx1[1]-y;
	  x2=cx2[0]-x; y2=cx2[1]-y;
	  l1=x1*x1 + y1*y1;
	  l2=x2*x2 + y2*y2;
	  det=x1*y2 - x2*y1;
	  if((det<ibgDelaunayEps2)){
	    destroyCell(c1);
	    // cc has to be deleted, but it's neighbours don't know this if they are
	    // deleted before (v-test is ok for cc). test deleted neighbours for this effect
	    if(cc>=0){
	      csh=ccs(cc);
	      for(sh=0;sh<wzCellTypeSides(t);sh++){
		if(!(dsh= -ccu(ch=csh[sh]))) continue;
		if(ch==c0) continue;
		if(dsh>dsi) continue;
		for(ih=0;ih<wzCellTypeSides(cct(ch));ih++){
		  if(ccs(ch)[ih]==cc){
		    cl=(dscl[ih])[dsh];
		    wzAssert(cl>0);
		    destroyCell(cl);
		    //		 for(nsi=0;nsi<nsl;nsi++){
		    //		   if(nsc[nsi]==cl) nsco[nsi]=0;
		    //		 }
		    (dscl[ih])[dsh] = -1;
		  }
		}
	      }
	      del=1; goto deltest;
	    }else{
	      wzAssert(0);	// do the same stuff for 3D too!!!
	      continue;
	    }
	  }
	  mx=(l1*y2 - l2*y1)/det;
	  my=(l2*x1 - l1*x2)/det;
	  ccv(c1).x1[0]=x;
	  ccv(c1).x1[1]=y;
	  ccv(c1).x2[0]=x+mx;
	  ccv(c1).x2[1]=y+my;
	  //	 cvert = ccv(c1);
	  // Eintragen von c1 in die nsc- und dsc-Listen:
	  nsi = nsl; nsl++;
	  nsc[nsi]=c1; nscs[nsi]=s; nsco[nsi]=c0;
	  ccu(c1)=0; (dscl[s])[dsi]=c1;
	}
      }
      dsi++;
    }
    // Herstellung der Verbindungen der neuen Zellen untereinander: 
    for(nsi=0;nsi<nsl;nsi++){
      c1 = nsc[nsi]; cs1= ccs(c1);	//* neue Zelle 
      c0 =nsco[nsi]; s0 = nscs[nsi];	//* alte Zelle 
      ds0= -ccu(c0);
      if((dscl[s0])[ds0]!=c1) continue;
      t0 =cct(c0); t1=cct(c1); cn0=ccn(c0); cs0=ccs(c0);
      // Eintragen des Zeigers von cc auf c1: 
      if((cc=cs1[0])>0){
	se=(ss=ccs(cc))+wzCellTypeSides(t);
	for(;ss<se;ss++) if(ss[0]==c0)
	  {ss[0]=c1; break;}
      }
      for(i0=0;i0<wzCellTypeSSize(t0,s0);i0++){
	if(cs1[wzCellTypeSSide(t1,0,i0)]>0) continue;
	nh=cn0[wzCellTypeSPoint1(t0,s0,i0)];
	ct=(dscl[wzCellTypeSSide(t0,s0,i0)])[ds0];
	if(ct<=0){
	  /* "Ubergang zur Nachbarzelle */
	  ch=c0;th=t0;sh=s0;ih=i0;csh=cs0;
	  do{
	    co =ch;
	    ch =csh[wzCellTypeSSide(th,sh,ih)];
	    dsh= -ccu(ch);	wzAssert(dsh>0);
	    th =cct(ch);
	    cnh=ccn(ch);
	    csh=ccs(ch);
	    for(sh=0;;sh++)	{
	      if(csh[sh]==co) break;
	      wzAssert(sh<4);}
	    for(ih=0;;ih++) {
	      if(cnh[wzCellTypeSPoint1(th,sh,ih)]==nh)
		break;
	      wzAssert(ih<2);}
	    ct=dscl[wzCellTypeSSide(th,sh,ih)][dsh];
	  }while(ct<=0);
	}
	cs1[wzCellTypeSSide(t1,0,i0)]=ct;
	cnj = ccn(ct); csj = ccs(ct); tt=cct(ct);
	for(j=0;j<4;j++) if(cnj[wzCellTypeSPoint1(tt,0,j)]==nh){
	  csj[wzCellTypeSSide(tt,0,j)]= c1; break;
	}
      }
    }
    /* Eintragen der zerst"orten Zellen in die free-Listen */
    for(dsi=1;dsi<=dsl;dsi++){
      cc=dsc[dsi]; destroyCell(cc);
    }
  }
  return wzSuccess;
}

int   wzDelaunayGenerator::Delaunay3(wzpoints list)
{
  int n,s,s0,sh,ms,i,i0,ih,j,del;
  int n0,nb,no,nold,nshift,nt,nh,c0,c1,cc,ct,ch,cl,co;
  int *cs0,*cs1,*csi,*csj,*csh,*cn0,*cni,*cnj,*cnh,*ss,*se;
  wzFloat *cx1,*cx2,*cx3;
  wzFloat x,y,z,x1,x2,x3,y1,y2,y3,z1,z2,z3;
  wzFloat l1,l2,l3,det,a1,a2,a3,mx,my,mz;
  ibg2CellType t,t0,t1,th,tt;
  wzPoint nd;
  ibgSphere v;
  int dsi,ds0,dsh,nsi;
  n0 = nb = Grid.points.append(list->length());
  nshift = nb - list->first(); n0--;
  nold = list->first()-1;
  wzRangeLoop(*list,n){
    wzAssert(n==nold+1);
    nold = n;
    n0++;
    Grid.Point[n0]=list->Point[n];
    // Suche nach einer Zelle, die n0 enth"alt: 
    no = list->Near[n] + nshift;
    wzAssert(list->Near[n]<n);
    if(no<nb) no = n0-1;
    c0=g3find(cnx(n0),cnc(no));
    // old code:
    x=cnx(n0)[0]; y=cnx(n0)[1]; z=cnx(n0)[2];
    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)
		 +    (v.x1[2]-z)*(v.x2[2]-z)) < ibgDelaunayEps2)	del=1;
	else							del=0;
      deltest:
	if(del){
	  dsc[++dsl] = cc; ccu(cc) = -dsl;
	  (dscl[s])[dsi] = -1;
	}else{
	  wzAssert(wzCellTypeSSize(t0,s)==3);
	  c1 = createCell(wzCellType3Tetrahedron);
	  cni=ccn(c1); csi=ccs(c1);
	  cn0 = ccn(c0);
	  cs0 = ccs(c0);
	  cni[0]=n0; cnc(n0)=c1; cni++; cnj=cni;
	  csi[0]=cc; csi++;
	  for(i=0;i<3;i++){
	    //	erfordert i+1 == wzCellTypeSPoint1(wzCellType3Tetrahedron,0,i)  
	    cni[i]  = nt = cn0[wzCellTypeSPoint1(t0,s,i)];
	    cnc(nt) = c1; csi[i] = -1;
	  }
	  // Berechnen und Eintragen der Daten der Umkugel: 
	  cx1=cnx(*cnj++); cx2=cnx(*cnj++); cx3=cnx(*cnj++);
	  x1=cx1[0]-x; y1=cx1[1]-y; z1=cx1[2]-z;
	  x2=cx2[0]-x; y2=cx2[1]-y; z2=cx2[2]-z;
	  x3=cx3[0]-x; y3=cx3[1]-y; z3=cx3[2]-z;
	  l1=x1*x1 + y1*y1 + z1*z1;
	  l2=x2*x2 + y2*y2 + z2*z2;
	  l3=x3*x3 + y3*y3 + z3*z3;
	  a1=y2*z3 - y3*z2;
	  a2=y3*z1 - y1*z3;
	  a3=y1*z2 - y2*z1;
	  det=x1*a1 + x2*a2 + x3*a3;
	  if((det>-ibgDelaunayEps3)){
	    destroyCell(c1);
	    // cc has to be deleted, but it's neighbours don't know this if they are
	    // deleted before (v-test is ok for cc). test deleted neighbours for this effect
	    csh=ccs(cc);
	    for(sh=0;sh<wzCellTypeSides(t);sh++){
	      if((ch=csh[sh])==0) continue;
	      if(!(dsh= -ccu(ch))) continue;
	      if(ch==c0) continue;
	      if(dsh>dsi) continue;
	      for(ih=0;ih<wzCellTypeSides(cct(ch));ih++){
		if(ccs(ch)[ih]==cc){
		  cl=(dscl[ih])[dsh];
		  wzAssert(cl>0);
		  destroyCell(cl);
		  (dscl[ih])[dsh] = -1;
		}
	      }
	    }
	    del=1;
	    goto deltest;
	  }
	  mx=(l1*a1+l2*a2+l3*a3)/det;
	  my=(l1*(z2*x3-z3*x2)+l2*(z3*x1-z1*x3)+l3*(z1*x2-z2*x1))/det;
	  mz=(l1*(x2*y3-x3*y2)+l2*(x3*y1-x1*y3)+l3*(x1*y2-x2*y1))/det;
	  ccv(c1).x1[0]=x;
	  ccv(c1).x1[1]=y;
	  ccv(c1).x1[2]=z;
	  ccv(c1).x2[0]=x+mx;
	  ccv(c1).x2[1]=y+my;
	  ccv(c1).x2[2]=z+mz;
	  // Eintragen von c1 in die nsc- und dsc-Listen: 
	  nsi = nsl; nsl++;
	  nsc[nsi]=c1; nscs[nsi]=s; nsco[nsi]=c0;
	  ccu(c1)=0; (dscl[s])[dsi]=c1;
	}
      }
      dsi++;
    }
    // Herstellung der Verbindungen der neuen Zellen untereinander: 
    for(nsi=0;nsi<nsl;nsi++){
      c1 = nsc[nsi]; cs1= ccs(c1);	/* neue Zelle */
      c0 =nsco[nsi]; s0 = nscs[nsi];	/* alte Zelle */
      ds0= -ccu(c0);
      if((dscl[s0])[ds0]!=c1) continue;
      t0 =cct(c0); t1=cct(c1); cn0=ccn(c0); cs0=ccs(c0);
      // Eintragen des Zeigers von cc auf c1: 
      if((cc=cs1[0])>0){
	se=(ss=ccs(cc))+wzCellTypeSides(t);
	for(;ss<se;ss++) if(ss[0]==c0)
	  {ss[0]=c1; break;}
      }
      for(i0=0;i0<wzCellTypeSSize(t0,s0);i0++){
	if(cs1[wzCellTypeSSide(t1,0,i0)]>0) continue;
	nh=cn0[wzCellTypeSPoint1(t0,s0,i0+1)];
	ct=(dscl[wzCellTypeSSide(t0,s0,i0)])[ds0];
	if(ct<=0){
	  /* "Ubergang zur Nachbarzelle */
	  ch=c0;th=t0;sh=s0;ih=i0;csh=cs0;
	  do{ co = ch;
	  ch = csh[wzCellTypeSSide(th,sh,ih)];
	  dsh= -ccu(ch);	wzAssert(dsh>0);
	  th = cct(ch);
	  cnh= ccn(ch);
	  csh= ccs(ch);
	  for(sh=0;;sh++)	{
	    if(csh[sh]==co) break;
	    wzAssert(sh<9);}
	  for(ih=0;;ih++) {
	    if(cnh[wzCellTypeSPoint1(th,sh,ih+1)]==nh)
	      break;
	    wzAssert(ih<5);}
	  ct=(dscl[wzCellTypeSSide(th,sh,ih)])[dsh];
	  }while(ct<=0);
	}
	cs1[wzCellTypeSSide(t1,0,i0)]=ct;
	cnj = ccn(ct); csj = ccs(ct); tt=cct(ct);
	for(j=0;j<4;j++) if(cnj[wzCellTypeSPoint1(tt,0,j)]==nh){
	  csj[wzCellTypeSSide(tt,0,j)]= c1; break;
	}
      }
    }
    for(dsi=1;dsi<=dsl;dsi++){
      cc=dsc[dsi]; destroyCell(cc);
    }
  }
  return wzSuccess;
}

⌨️ 快捷键说明

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