//----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_ri(HADT d, HCDT re, HCDT im) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); d->Create(nx,ny,nz); #pragma omp parallel for for(long i=0;i<nx*ny*nz;i++) d->a[i] = dual(re->vthr(i),im->vthr(i)); }
HADT MGL_EXPORT mgl_datac_sum(HCDT dat, const char *dir) { if(!dir || *dir==0) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; dual *b = new dual[nx*ny*nz]; dual *c = new dual[nx*ny*nz]; const mglDataC *d=dynamic_cast<const mglDataC *>(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(dual)); else #pragma omp parallel for for(long i=0;i<nx*ny*nz;i++) c[i]=dat->vthr(i); if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_sumc_z,0,nx*ny,b,c,0,p); memcpy(c,b,nx*ny*sizeof(mreal)); p[2] = 1; } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_sumc_y,0,nx*p[2],b,c,0,p); memcpy(c,b,nx*p[2]*sizeof(mreal)); p[1] = p[2]; p[2] = 1; } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_sumc_x,0,p[1]*p[2],b,c,0,p); p[0] = p[1]; p[1] = p[2]; p[2] = 1; } mglDataC *r=new mglDataC(p[0],p[1],p[2]); memcpy(r->a,b,p[0]*p[1]*p[2]*sizeof(dual)); delete []b; delete []c; return r; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq) { const mglData *dd=dynamic_cast<const mglData *>(dat); std::vector<mglDataA*> list; if(dd && dd->id.length()>0) for(size_t i=0;i<dd->id.length();i++) { mglDataT *col = new mglDataT(*dat); col->SetInd(i,dd->id[i]); list.push_back(col); } const mglDataC *dc=dynamic_cast<const mglDataC *>(dat); if(dc && dc->id.length()>0) for(size_t i=0;i<dc->id.length();i++) { mglDataT *col = new mglDataT(*dat); col->SetInd(i,dc->id[i]); list.push_back(col); } if(list.size()==0) return 0; // no named columns mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz()); t->s=L"#$mgl"; list.push_back(t); mglDataC *r = new mglDataC; r->Set(mglFormulaCalcC(eq,list)); for(size_t i=0;i<list.size();i++) delete list[i]; return r; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_grid_xy(HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, mreal x1, mreal x2, mreal y1, mreal y2) { // NOTE: only for mglData const mglData *x = dynamic_cast<const mglData *>(xdat); const mglData *y = dynamic_cast<const mglData *>(ydat); long n=xdat->GetNN(); if((n<3) || (ydat->GetNN()!=n) || (zdat->GetNN()!=n)) return; mglData *nums = mgl_triangulation_2d(xdat,ydat); if(nums->nx<3) { delete nums; return; } long nn = nums->ny, par[3]={d->nx,d->ny,d->nz}; mreal xx[4]={x1,(d->nx-1.)/(x2-x1), y1,(d->ny-1.)/(y2-y1)}; mreal *xc=new mreal[n], *yc=new mreal[n]; if(x && y) #pragma omp parallel for for(long i=0;i<n;i++) { xc[i]=xx[1]*(x->a[i]-xx[0]); yc[i]=xx[3]*(y->a[i]-xx[2]); } else #pragma omp parallel for for(long i=0;i<n;i++) { xc[i]=xx[1]*(xdat->vthr(i)-xx[0]); yc[i]=xx[3]*(ydat->vthr(i)-xx[2]); } long tmp = d->nx*d->ny*d->nz; #pragma omp parallel for for(long i=0;i<tmp;i++) d->a[i] = NAN; mglStartThread(mgl_grid_t,0,nn,d->a,xc,yc,par,zdat,nums->a); delete nums; delete []xc; delete []yc; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContZ"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgZ('z'); if(sv<gr->Min.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"ContZ"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContZ",cgid++); mglDataV xx,yy,zz; mglData aa; int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; long ss=gr->AddTexture(sch); gr->SetPenPal(sch); a = fill_slice_z(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;i<v->GetNx();i++) { mreal v0 = v->v(i); mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0); } gr->EndGroup(); }
//----------------------------------------------------------------------------- // // Crust series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_crust(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt) { if(y->GetNx()!=x->GetNx() || z->GetNx()!=x->GetNx()) { gr->SetWarn(mglWarnDim,"Crust"); return; } HMDT nums = mgl_triangulation_3d(x, y, z); mgl_triplot_xyzc(gr,nums,x,y,z,z,sch,opt); mgl_delete_data(nums); }
//----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_arg(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast<const mglDataC*>(d); if(dd) #pragma omp parallel for for(long i=0;i<nx*ny*nz;i++) r->a[i] = arg(dd->a[i]); return r; }
//----------------------------------------------------------------------------- // // TriContV series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mglDataV zz(x->GetNx(),x->GetNy()); if(!z) z = &zz; if(mgl_check_trig(gr,nums,x,y,z,a,"TriContV")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TriContV",cgid++); bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); for(long k=0;k<v->GetNx();k++) { mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0); mreal dv = (gr->Max.c-gr->Min.c)/8, c = gr->GetC(s,v0); if(k>0) dv = v->v(k-1)-v->v(k); else if(k<v->GetNx()-1) dv = v->v(k)-v->v(k+1); if(fixed) dv=-dv; const std::vector<mglSegment> curvs = mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z)); for(size_t i=0;i<curvs.size();i++) { const std::list<mglPoint> &pp=curvs[i].pp; long f2=-1,g2=-1; for(std::list<mglPoint>::const_iterator it=pp.begin(); it != pp.end(); ++it) { mglPoint p=*it,q(p.y,-p.x); long f1 = f2; f2 = gr->AddPnt(p,c,q); p.z+=dv; long g1 = g2; g2 = gr->AddPnt(p,c,q); gr->quad_plot(f1,g1,f2,g2); } } } }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set_ap(HADT d, HCDT a, HCDT p) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); d->Create(nx,ny,nz); #pragma omp parallel for for(long i=0;i<nx*ny*nz;i++) { register mreal aa=a->vthr(i), pp=p->vthr(i); d->a[i] = dual(aa*cos(pp), aa*sin(pp)); } }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_dens_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensZ"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgZ('z'); if(sv<gr->Min.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"DensZ"); gr->LoadState(); return; } mglDataV xx,yy,zz; mglData aa; a = fill_slice_z(gr,sv,a,xx,yy,zz,aa); mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch); }
//----------------------------------------------------------------------------- // // IFS series // //----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_ifs_2d_point(HCDT A, mreal& x, mreal& y, mreal amax) { long i, n=A->GetNy(); mreal r = amax*mgl_rnd(), sum_prob = 0, x1; for(i=0;i<n;i++) { sum_prob += A->v(6,i); if(r<sum_prob) break; } x1= A->v(0,i)*x + A->v(1,i)*y + A->v(4,i); y = A->v(2,i)*x + A->v(3,i)*y + A->v(5,i); x = x1; }
//----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_ifs_3d_point(HCDT A, mreal& x, mreal& y, mreal& z, mreal amax) { int i, n=A->GetNy(); mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1; for (i=0; i<n; i++) { sum_prob += A->v(12,i); if(r < sum_prob) break; } x1= A->v(0,i)*x + A->v(1,i)*y + A->v(2,i)*z + A->v(9,i); y1= A->v(3,i)*x + A->v(4,i)*y + A->v(5,i)*z + A->v(10,i); z = A->v(6,i)*x + A->v(7,i)*y + A->v(8,i)*z + A->v(11,i); x = x1; y = y1; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set(HADT d, HCDT a) { if(!a) return; const mglDataC *dd = dynamic_cast<const mglDataC *>(a); // faster for mglData mgl_datac_create(d, a->GetNx(), a->GetNy(), a->GetNz()); if(dd) // this one should be much faster memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(dual)); else // very inefficient!!! { register long i,j,k; for(k=0;k<d->nz;k++) for(j=0;j<d->ny;j++) for(i=0;i<d->nx;i++) d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k); } }
void MGL_EXPORT mgl_datac_modify_vw(HADT d, const char *eq,HCDT vdat,HCDT wdat) { const mglDataC *v = dynamic_cast<const mglDataC *>(vdat); const mglDataC *w = dynamic_cast<const mglDataC *>(wdat); long nn = d->nx*d->ny*d->nz, par[3]={d->nx,d->ny,d->nz}; if(vdat && vdat->GetNN()!=nn) return; if(wdat && wdat->GetNN()!=nn) return; mglFormulaC f(eq); if(v && w) mglStartThreadC(mgl_cmodify,0,nn,d->a,v->a,w->a,par,&f); else if(vdat && wdat) mglStartThreadV(mgl_cmodify_gen,nn,d->a,vdat,wdat,par,&f); else if(v) mglStartThreadC(mgl_cmodify,0,nn,d->a,v->a,0,par,&f); else if(vdat) mglStartThreadV(mgl_cmodify_gen,nn,d->a,vdat,0,par,&f); else mglStartThreadC(mgl_cmodify,0,nn,d->a,0,0,par,&f); }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt) { gr->SaveState(opt); mglData z(x->GetNx()); mreal zm = gr->AdjustZMin(); z.Fill(zm,zm); mgl_triplot_xyzc(gr,nums,x,y,&z,&z,sch,0); }
HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip) { if(!A || A->GetNx()<13 || n<1) return 0; // incompatible dimensions mreal amax = 0; for(int i=0; i<A->GetNy(); i++) amax += A->v(12,i); if(amax <= 0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0, z = 0; for(long i=0; i<skip; i++) mgl_ifs_3d_point(A, x, y, z, amax); for(long i=0; i<n; i++) { mgl_ifs_3d_point(A, x, y, z, amax); f->a[3*i] = x; f->a[3*i+1] = y; f->a[3*i+2] = z; } return f; }
//----------------------------------------------------------------------------- // // DataGrid // //----------------------------------------------------------------------------- MGL_NO_EXPORT void *mgl_grid_t(void *par) { mglThreadD *t=(mglThreadD *)par; long nx=t->p[0],ny=t->p[1]; mreal *b=t->a; const mreal *x=t->b, *y=t->c, *d=t->d; HCDT zdat = (HCDT) t->v; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0<t->n;i0+=mglNumThr) { register long k1 = long(d[3*i0]+0.5), k2 = long(d[3*i0+1]+0.5), k3 = long(d[3*i0+2]+0.5); mreal dxu,dxv,dyu,dyv; mreal z1=zdat->vthr(k1), z2=zdat->vthr(k2), z3=zdat->vthr(k3); mglPoint d1=mglPoint(x[k2]-x[k1],y[k2]-y[k1],z2-z1), d2=mglPoint(x[k3]-x[k1],y[k3]-y[k1],z3-z1), p; dxu = d2.x*d1.y - d1.x*d2.y; if(fabs(dxu)<1e-5) continue; // points lies on the same line dyv =-d1.x/dxu; dxv = d1.y/dxu; dyu = d2.x/dxu; dxu =-d2.y/dxu; long x1,y1,x2,y2; x1 = long(mgl_min(mgl_min(x[k1],x[k2]),x[k3])); // bounding box y1 = long(mgl_min(mgl_min(y[k1],y[k2]),y[k3])); x2 = long(mgl_max(mgl_max(x[k1],x[k2]),x[k3])); y2 = long(mgl_max(mgl_max(y[k1],y[k2]),y[k3])); x1 = x1>0 ? x1:0; x2 = x2<nx ? x2:nx-1; y1 = y1>0 ? y1:0; y2 = y2<ny ? y2:ny-1; if((x1>x2) | (y1>y2)) continue; register mreal u,v,xx,yy, x0 = x[k1], y0 = y[k1]; register long i,j; for(i=x1;i<=x2;i++) for(j=y1;j<=y2;j++) { xx = (i-x0); yy = (j-y0); u = dxu*xx+dyu*yy; v = dxv*xx+dyv*yy; if((u<0) | (v<0) | (u+v>1)) continue; b[i+nx*j] = z1 + d1.z*u + d2.z*v; } } return 0; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFY"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgY('y'); if(sv<gr->Min.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"ContFY"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContFY",cgid++); mglDataV xx,yy,zz; mglData aa; long ss=gr->AddTexture(sch); a = fill_slice_y(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;i<v->GetNx()-1;i++) { mreal v0 = v->v(i); mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0); } gr->EndGroup(); }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt) { if(vdat && vdat->GetNN()!=d->GetNN()) return; // incompatible dimensions if(wdat && wdat->GetNN()!=d->GetNN()) return; gr->SaveState(opt); std::wstring s = d->Name(); d->Name(L"u"); mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.Name(L"x"); mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.Name(L"y"); mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.Name(L"z"); mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i"); mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j"); mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k"); mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl"); mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w"); std::vector<mglDataA*> list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&r); list.push_back(d); list.push_back(&v); list.push_back(&w); list.push_back(&i); list.push_back(&j); list.push_back(&k); d->Move(mglFormulaCalc(eq,list)); d->Name(s.c_str()); gr->LoadState(); }
//----------------------------------------------------------------------------- HCDT static fill_slice_z(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); if(l>1) { aa.Create(n,m); mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z); long k = long(d); d = d - k; if(k>l-2) { k=l-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;j<m;j++) for(long i=0;i<n;i++) aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1); a = &aa; } zz.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'y'); xx.Fill(gr->Min.x, gr->Max.x,'x'); return a; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mglDataV zz(x->GetNx(),x->GetNy()); if(!z) z = &zz; if(mgl_check_trig(gr,nums,x,y,z,a,"TriCont")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TriCont",cgid++); int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); for(long k=0;k<v->GetNx();k++) { mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0); mgl_draw_curvs(gr,v0,gr->GetC(s,v0),text,mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z))); } }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_trace(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); const mglDataC *dc = dynamic_cast<const mglDataC *>(d); mglDataC *r=new mglDataC(nx); if(dc) { if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = dc->a[i+nx*(i+ny*i)]; else if(ny>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = dc->a[i+nx*i]; else #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = dc->a[i]; } else if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = d->v(i,i,i); else if(ny>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = d->v(i,i); else #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = d->v(i); return r; }
//----------------------------------------------------------------------------- HCDT static fill_slice_x(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); if(l>1) { aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l); mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x); long k = long(d); d = d - k; if(k>n-2) { k=n-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;j<l;j++) for(long i=0;i<m;i++) aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j); a = &aa; } else { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); } xx.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'x'); zz.Fill(gr->Min.z, gr->Max.z,'y'); return a; }
//----------------------------------------------------------------------------- long MGL_NO_EXPORT mgl_flame_2d_point(HCDT A, HCDT F, mreal& x, mreal& y, mreal amax) { long i, n=A->GetNy(), m=F->GetNy(), last_func=0, l=F->GetNx(); l = l>6?6:l; mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1; for(i=0;i<n;i++) { sum_prob += A->v(6,i); if(r<sum_prob) break; } x1 = A->v(0,i)*x + A->v(1,i)*y + A->v(4,i); y1 = A->v(2,i)*x + A->v(3,i)*y + A->v(5,i); x = y = 0; for(long j=0;j<m;j++) { int v=int(F->v(0,j,i)+0.5); mreal par[5] = {F->v(1,j,i),0,0,0,0}; for(int k=2;k<l;k++) par[k-1]=F->v(k,j,i); if(v<0 || v>=mglFlameLAST) { v=0; par[0]=1; } ffunc[v](x,y,x1,y1,par); last_func=v; } return last_func; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata(HCDT d, long xx,long yy,long zz) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1; int dx=0,dy=0,dz=0; if(xx<0) { xx=0; dx=1; n=nx; } if(yy<0) { yy=0; dy=1; m=ny; } if(zz<0) { zz=0; dz=1; l=nz; } const mglDataC *dd = dynamic_cast<const mglDataC *>(d); mglDataC *r=new mglDataC(n,m,l); if(xx>=nx || yy>=ny || zz>=nz) #pragma omp parallel for for(long i=0;i<n*m*l;i++) r->a[i] = NAN; else if(dd) #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) r->a[i+n*(j+m*k)] = dd->a[xx+dx*i + nx*(yy+dy*j + ny*(zz+dz*k))]; else #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) r->a[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k); if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; }
HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z) { mglData *nums=0; long n = x->GetNx(), m; if(y->GetNx()!=n || z->GetNx()!=n) return nums; mglPoint *pp = new mglPoint[n]; long *nn=0; for(long i=0;i<n;i++) pp[i] = mglPoint(x->v(i), y->v(i), z->v(i)); m = mgl_crust(n,pp,&nn,0); if(m>0) { nums=new mglData(3,m); for(long i=0;i<3*m;i++) nums->a[i]=nn[i]; } delete []pp; free(nn); return nums; }
HMDT MGL_EXPORT mgl_data_flame_2d(HCDT A, HCDT F, long n, long skip) { if(!A || A->GetNx()<7 || n<1) return 0; // incompatible dimensions if(!F || F->GetNx()<2 || F->GetNz()!=A->GetNy()) return 0; // incompatible dimensions mreal amax=0; for(long i=0; i<A->GetNy(); i++) amax += A->v(6,i); if(amax<=0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0; for(long i=0; i<skip; i++) mgl_flame_2d_point(A, F, x, y,amax); for(long i=0; i<n; i++) { f->a[3*i+2] = mgl_flame_2d_point(A, F, x, y, amax); // TODO color information ?!! f->a[3*i] = x; f->a[3*i+1] = y; } return f; }
HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y) { mglData *nums=0; long n = x->GetNN(); if(y->GetNN()!=n) return nums; // use s-hull here std::vector<Shx> pts; std::vector<long> out; Shx pt; double mx = 0, my = 0; for(long i=0;i<n;i++) { register double t; t = fabs(x->vthr(i)); if(t>mx) mx=t; t = fabs(y->vthr(i)); if(t>my) my=t; } mx *= 1e-15; my *= 1e-15; for(long i=0;i<n;i++) { pt.r = x->vthr(i); pt.c = y->vthr(i); if(mgl_isbad(pt.r) || mgl_isbad(pt.c)) continue; if(fabs(pt.r)<mx) pt.r=0; if(fabs(pt.c)<my) pt.c=0; pt.id = i; pts.push_back(pt); } std::vector<Triad> triads; if(de_duplicate(pts, out)) mgl_set_global_warn("There are duplicated points for triangulation."); s_hull_pro(pts, triads); long m = triads.size(); nums=new mglData(3,m); for(long i=0;i<m;i++) { nums->a[3*i] = triads[i].a; nums->a[3*i+1] = triads[i].b; nums->a[3*i+2] = triads[i].c; } return nums; }
//----------------------------------------------------------------------------- // // Dots series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_ca(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt) { long n = x->GetNN(), d, k=1; if(x->GetNz()>1) k=3; else if(x->GetNy()>1) k=2; if(y->GetNN()!=n || z->GetNN()!=n || c->GetNN()!=n || (a && a->GetNN()!=n)) { gr->SetWarn(mglWarnDim,"Dots"); return; } gr->SaveState(opt); d = gr->MeshNum>0 ? mgl_ipow(gr->MeshNum+1,k) : n; d = n>d ? n/d:1; static int cgid=1; gr->StartGroup("Dots",cgid++); char mk=gr->SetPenPal(sch); long ss=gr->AddTexture(sch); if(mk==0) mk='.'; gr->Reserve(n); for(long i=0;i<n;i+=d) { mglPoint p = mglPoint(x->vthr(i),y->vthr(i),z->vthr(i)); long pp = gr->AddPnt(p,gr->GetC(ss,c->vthr(i)),mglPoint(NAN),a?gr->GetA(a->vthr(i)):-1); gr->mark_plot(pp, mk); } gr->EndGroup(); }
//----------------------------------------------------------------------------- // // TriPlot series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { long n = x->GetNx(), m = nums->GetNy(); if(mgl_check_trig(gr,nums,x,y,z,a,"TriPlot")) return; long ss=gr->AddTexture(sch); gr->SaveState(opt); gr->SetPenPal("-"); static int cgid=1; gr->StartGroup("TriPlot",cgid++); bool wire = mglchr(sch,'#'); long nc = a->GetNx(); if(nc!=n && nc>=m) // colors per triangle { mglPoint p1,p2,p3,q; gr->Reserve(m*3); for(long i=0;i<m;i++) { register long k1 = long(nums->v(0,i)+0.5); p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1)); register long k2 = long(nums->v(1,i)+0.5); p2 = mglPoint(x->v(k2), y->v(k2), z->v(k2)); register long k3 = long(nums->v(2,i)+0.5); p3 = mglPoint(x->v(k3), y->v(k3), z->v(k3)); q = wire ? mglPoint(NAN,NAN) : (p2-p1) ^ (p3-p1); k1 = gr->AddPnt(p1,gr->GetC(ss,a->v(k1)),q); k2 = gr->AddPnt(p2,gr->GetC(ss,a->v(k2)),q); k3 = gr->AddPnt(p3,gr->GetC(ss,a->v(k3)),q); gr->trig_plot(k1,k2,k3); } } else if(nc>=n) // colors per point { gr->Reserve(n); long *kk = new long[n]; mglPoint *pp = new mglPoint[n]; for(long i=0;i<m;i++) // add averaged normales { register long k1 = long(nums->v(0,i)+0.5); register long k2 = long(nums->v(1,i)+0.5); register long k3 = long(nums->v(2,i)+0.5); if(!wire) { mglPoint q = mglPoint(x->v(k2)-x->v(k1), y->v(k2)-y->v(k1), z->v(k2)-z->v(k1)) ^ mglPoint(x->v(k3)-x->v(k1), y->v(k3)-y->v(k1), z->v(k3)-z->v(k1)); q.Normalize(); // try be sure that in the same direction ... if(q.z<0) q *= -1; pp[k1] += q; pp[k2] += q; pp[k3] += q; } else pp[k1]=pp[k2]=pp[k3]=mglPoint(NAN,NAN); } for(long i=0;i<n;i++) // add points kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)), gr->GetC(ss,a->v(i)), pp[i]); for(long i=0;i<m;i++) // draw triangles { register long k1 = long(nums->v(0,i)+0.5); register long k2 = long(nums->v(1,i)+0.5); register long k3 = long(nums->v(2,i)+0.5); if(wire) { gr->line_plot(kk[k1],kk[k2]); gr->line_plot(kk[k1],kk[k3]); gr->line_plot(kk[k3],kk[k2]); } else gr->trig_plot(kk[k1],kk[k2],kk[k3]); } delete []kk; delete []pp; } gr->EndGroup(); }