static void MakeColorMap (ColorMap& cmap) { cmap.Load("copper-256"); // load a default colormap if (! cmap) Matpack.Error("Can't load colormap"); cmap.Reverse(); // reverse ordering int i, n = cmap.Size(); // change colormap now for (i = 0; i < 20; i++) cmap[i] = ColorB(0,100+2*i,160+2*i); // water for (i = 20; i < 80; i++) cmap[i] = ColorB(2*i+20,2*i+20,i/2+10); // mangrove for (i = 1; i < 60; i++) cmap[n-i] = ColorB(255-i,250-i,250-2*i); // snow }
void MpSurfacePrism (Scene &S, const Matrix &Z, int nsegments, double wx, double wy, const ColorMap &cmap,double cmin, double cmax) { // nothing that can be drawn if ( Z.Empty() ) return; // 4-segments faster special case if (nsegments == 4) { MpSurfacePrism4(S,Z,wx,wy,cmap,cmin,cmax); return; } // find the extrema double zmin = Min(Z); // check for valid nsegments values MpForceRange(nsegments, 3, MaxVertices); // check if a colormap should be used double dz,cscale = 0; bool usecolormap; int ncmap = cmap.Size()-1; if (cmap) { usecolormap = true; dz = cmax - cmin; cscale = (dz == 0.0) ? 0 : ncmap/dz; } else usecolormap = false; // add prism for (int x = Z.Rlo(); x <= Z.Rhi(); x++) for (int y = Z.Clo(); y <= Z.Chi(); y++) { double z = Z(x,y), height = 0.5 * (z - zmin); Trafo T = trans(y,height+zmin,x) * scale(wy,height,wx) * rot(Trafo::XAxis,M_PI/2); // coloring const ColorB *color; if (usecolormap) { int c = int((z-cmin)*cscale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; color = &cmap[c]; } else color = (ColorB*)NULL; cylinder(S,nsegments,T,color); } }
void MpDensityPlot::Draw (Scene& scene, const Matrix& z, const ColorMap &cmap, double cmin, double cmax, int mode) { if (! scene.IsOpen()) Matpack.Error("MpDensityPlot: scene is not open"); int outlined = (mode & MpDensityPlot::Outlined) ? (Fill | Outline) : Fill; ColorB BlendFrom(0,0,0), BlendTo(255,255,255); // black to white // scale factor for color mapping int ncmap; double cscale = 0, dz = cmax - cmin; if (cmap) { ncmap = cmap.Size()-1; cscale = (dz == 0.0) ? 0.0 : ncmap/dz; } else ncmap = 0; // plot all density cells for (int x = z.Clo(); x <= z.Chi(); ++x) { double dx1 = (x != z.Clo()) ? 0.5 : 0, dx2 = (x != z.Chi()) ? 0.5 : 0; for (int y = z.Rlo(); y <= z.Rhi(); ++y) { // calculate color long color; if (ncmap) { int c = int((z[y][x]-cmin)*cscale); MpForceRange(c,0,ncmap); color = scene.NewColor(cmap[c]); } else { // linear map to color range black - white double intens = (dz == 0.0) ? 0.0 : (z[y][x] - cmin)/dz; MpForceRange(intens,0.0,1.0); color = scene.NewColor(((1.0-intens)*BlendFrom.red+intens*BlendTo.red)/255.0, ((1.0-intens)*BlendFrom.green+intens*BlendTo.green)/255.0, ((1.0-intens)*BlendFrom.blue+intens*BlendTo.blue)/255.0, RGB); } // draw squares double dy1 = (y != z.Rlo()) ? 0.5 : 0, dy2 = (y != z.Rhi()) ? 0.5 : 0; double px[4] = {y-dy1,y+dy2,y+dy2,y-dy1}, py[4] = {x-dx1,x-dx1,x+dx2,x+dx2}; scene.Polygon(4,px,py,color,outlined); } } }
static void MpSurfacePrism4 (Scene &S, const Matrix &Z, double wx, double wy, const ColorMap &cmap, double cmin, double cmax) { // nothing that can be drawn if ( Z.Empty() ) return; // find the minimum double zmin = Min(Z); // check if a colormap should be used double dz,cscale = 0; bool usecolormap; int ncmap = cmap.Size()-1; if (cmap) { usecolormap = true; dz = cmax - cmin; cscale = (dz == 0.0) ? 0.0 : ncmap/dz; } else usecolormap = false; // add square prisms for (int x = Z.Rlo(); x <= Z.Rhi(); x++) for (int y = Z.Clo(); y <= Z.Chi(); y++) { double z = Z(x,y), height = 0.5 * (z - zmin); Trafo T = trans(y,height+zmin,x) * scale(wy,height,wx); // coloring const ColorB *color; if (usecolormap) { int c = int((z-cmin)*cscale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; color = &cmap[c]; } else color = (ColorB*)NULL; MpCube(S,T,color); } }
int MpWarpMatrixToSphere (Scene& S, Matrix& H, Vector& Pol, Vector& Azm, double r, const Trafo& T, int facet_culling, bool periodic, bool south_pole_cap, double h_south, bool north_pole_cap, double h_north, const ColorMap& cmap, double cmin, double cmax, int PolStride, int AzmStride) { int a,p,ncmap = 0; double x,y,z,pol,hr,sp,cp; double dz,scale = 0.0; bool usecolormap; int p1 = H.Rlo(), p2 = H.Rhi(), a1 = H.Clo(), a2 = H.Chi(); // check matrix and vector dimensions if (p1 != Pol.Lo() || p2 != Pol.Hi() || a1 != Azm.Lo() || a2 != Azm.Hi()) return 1; // check edge line stride values if (PolStride <= 0 || AzmStride <= 0) return 4; // evaluate facet culling flag int addFront = (facet_culling == Scene::Front) || (facet_culling == false), addBack = (facet_culling == Scene::Back) || (facet_culling == false); // number of facets in polar and azimuthal direction int np = p2-p1+1, na = a2-a1+1; // nothing that can be drawn if (np < 2 || na < 2) return 3; // pointer to vertices in two consecutive slices Vertex **top,**bot=0,**act; // allocate auxilliary storage if ( !(top = new Vertex*[na]) || !(bot = new Vertex*[na]) ) Matpack.Error("WarpMatrixToSphere: vector allocation failure"); // check if a colormap should be used if (cmap) { usecolormap = true; dz = cmax-cmin; ncmap = cmap.Size()-1; scale = (dz == 0.0) ? 0 : ncmap/dz; } else usecolormap = false; // Precompute sines and cosines of the azimuthal angles for the // sake of high performance Vector s,c; s = Sin(Azm); c = Cos(Azm); // loop through latitudes (polar angle) for ( p = p1, act = top; p <= p2; p++ ) { pol = Pol(p); sp = sin(pol); cp = cos(pol); // loop through longitudes (azimuthal angle) for ( a = a1; a <= a2; a++ ) { // warp transformation to sphere hr = H(p,a) + r; x = hr * cp * s(a); y = -hr * cp * c(a); z = hr * sp; // add vertices to scene storing a pointer to it // (and apply the global transformation) act[a-a1] = &S.AddVertex( T * Vertex((float)x,(float)z,(float)y) ); // set the vertex color if (usecolormap) { int cen = int((H(p,a)-cmin)*scale); MpForceRange(cen,0,ncmap); act[a-a1]->SetColor(cmap[cen]); } } // first slice or last slice - add triangles to create pole caps if ( (south_pole_cap && p == p1) || (north_pole_cap && p == p2) ) { int addF = false, addB = false; double h = 0.0; if (p == p1 && south_pole_cap) { addF = addBack; addB = addFront; h = -(r + h_south); } else if (p == p2 && north_pole_cap) { addF = addFront; addB = addBack; h = r + h_north; } // add vertices to scene storing a pointer to it // (and apply the global transformation) Vertex* v = &S.AddVertex(T * Vertex((float)0,(float)h,(float)0) ); // set the vertex color if (usecolormap) { int cen = int((h-cmin)*scale); MpForceRange(cen,0,ncmap); v->SetColor(cmap[cen]); } for (a = 0; a < na-1; a++) { // add with reverse orientation if (addB) { Facet &f = S.AddFacet(3); f(0) = v; f(1) = act[a]; f(2) = act[a+1]; SetEdgeLineVisibility(f,a,AzmStride,p-p1,PolStride,true); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a+a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } // add with normal orientation if (addF) { Facet &f = S.AddFacet(3); f(2) = act[a]; f(1) = act[a+1]; f(0) = v; SetEdgeLineVisibility(f,a,AzmStride,p-p1,PolStride); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a+a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } } // close sphere periodically in azimuthal direction if (periodic) { // add with opposite orientation if (addB) { Facet &f = S.AddFacet(3); f(0) = v; f(1) = act[na-1]; f(2) = act[0]; SetEdgeLineVisibility(f,a,AzmStride,p-p1,PolStride,true); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } // add with normal orientation if (addF) { Facet &f = S.AddFacet(3); f(2) = act[na-1]; f(1) = act[0]; f(0) = v; SetEdgeLineVisibility(f,a,AzmStride,p-p1,PolStride); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } } } // if ((south_pole_cap && p == p1) || (north_pole_cap && p == p2)) // // normal case: add quadrilaterals with top and bottom slices if (p != p1) { for (a = 0; a < na-1; a++) { // add with reverse orientation if (addBack) { Facet &f = S.AddFacet(4); f(0) = top[a]; f(1) = bot[a]; f(2) = bot[a+1]; f(3) = top[a+1]; SetEdgeLineVisibility(f,a,AzmStride,p-p1,PolStride,true); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a+a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } // add with normal orientation if (addFront) { Facet &f = S.AddFacet(4); f(3) = top[a]; f(2) = bot[a]; f(1) = bot[a+1]; f(0) = top[a+1]; SetEdgeLineVisibility(f,a,AzmStride,p-p1,PolStride); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a+a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } } // close sphere periodically in azimuthal direction if (periodic) { // add with reverse orientation if (addBack) { Facet &f = S.AddFacet(4); f(0) = top[na-1]; f(1) = bot[na-1]; f(2) = bot[0]; f(3) = top[0]; SetEdgeLineVisibility(f,na-1,AzmStride,p-p1,PolStride,true); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } // add with normal orientation if (addFront) { Facet &f = S.AddFacet(4); f(3) = top[na-1]; f(2) = bot[na-1]; f(1) = bot[0]; f(0) = top[0]; SetEdgeLineVisibility(f,na-1,AzmStride,p-p1,PolStride); // set color of facet according to colormap if (usecolormap) { int cen = int((H(p,a1)-cmin)*scale); MpForceRange(cen,0,ncmap); f.SetFrontColor(cmap[cen]); f.SetBackColor(cmap[cen]); } } } } // if (p == p1) // // swap top with bot pointers act = bot; bot = top; top = act; } // for ( p = p1, ... ) // // remove auxilliary storage delete bot; delete top; // no problems occured return 0; }
void MpSurfaceBands (Scene& S, const Matrix& z, int direction, double width, const ColorMap& cmap, double cmin, double cmax) { Vertex *v0,*v1,*v2,*v3; double scale = 0.0; bool usecolormap; // the width of the bands MpForceRange(width,1e-3,1.0); // 0.5 is half the mesh unit width /= 2; int ncmap = 0, nx = z.Rows(), ny = z.Cols(); // check arguments if ( nx < 0 || ny < 0 ) return; // nothing to draw // check if a colormap should be used if (cmap) { usecolormap = true; ncmap = cmap.Size()-1; double dz = cmax - cmin; scale = (dz == 0.0) ? 0.0 : ncmap/dz; } else usecolormap = false; switch (direction) { case RowBandsGrid: case RowBands: { for ( int y = z.Clo(); y <= z.Chi(); y++ ) { int x = z.Rlo(); v0 = &S.AddVertex(y+width,z[x][y],x); v1 = &S.AddVertex(y-width,z[x][y],x); if (usecolormap) { int c = int((z[x][y]-cmin)*scale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; const ColorB &col = cmap[c]; v0->SetColor(col); v1->SetColor(col); } for ( ; x < z.Rhi(); x++) { // create facet Facet &f = S.AddFacet(4); v2 = &S.AddVertex(y-width,z[x+1][y],x+1); v3 = &S.AddVertex(y+width,z[x+1][y],x+1); f(0) = v0; f(1) = v1; f(2) = v2; f(3) = v3; v0 = v3; v1 = v2; // set edge line mask if (direction == RowBands) if (x == z.Rlo()) f.SetEdgeLineVisibility(Facet::Individual,0xb); // (1011=0xb) else if (x == z.Rhi()-1) f.SetEdgeLineVisibility(Facet::Individual,0xe); // (1110=0xe) else f.SetEdgeLineVisibility(Facet::Individual,0xa); // (1010=0xa) // set color of facet according to colormap if (usecolormap) { float cx,cy,cz; f.Center(cy,cz,cx); int c = int((cz-cmin)*scale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; const ColorB ¢er = cmap[c]; f.SetColor(center); c = int((z[x+1][y]-cmin)*scale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; const ColorB &col = cmap[c]; v2->SetColor(col); v3->SetColor(col); } } } break; } case ColumnBandsGrid: case ColumnBands: { for ( int x = z.Rlo(); x <= z.Rhi(); x++ ) { int y = z.Clo(); v1 = &S.AddVertex(y,z[x][y],x-width); v2 = &S.AddVertex(y,z[x][y],x+width); if (usecolormap) { int c = int((z[x][y]-cmin)*scale); const ColorB &col = cmap[c]; if (c > ncmap) c = ncmap; else if (c < 0) c = 0; v1->SetColor(col); v2->SetColor(col); } for ( ; y < z.Chi(); y++) { // create facet Facet &f = S.AddFacet(4); v0 = &S.AddVertex(y+1,z[x][y+1],x-width); v3 = &S.AddVertex(y+1,z[x][y+1],x+width); f(0) = v0; f(1) = v1; f(2) = v2; f(3) = v3; v1 = v0; v2 = v3; // set edge line mask if (direction == ColumnBands) if (y == z.Clo()) f.SetEdgeLineVisibility(Facet::Individual,0x7); // (0111=0x7) else if (y == z.Chi()-1) f.SetEdgeLineVisibility(Facet::Individual,0xd); // (1101=0xd) else f.SetEdgeLineVisibility(Facet::Individual,0x5); // (0101=0x5) // set color of facet according to colormap if (usecolormap) { float cx,cy,cz; f.Center(cy,cz,cx); int c = int((cz-cmin)*scale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; const ColorB ¢er = cmap[c]; f.SetColor(center); c = int((z[x][y+1]-cmin)*scale); if (c > ncmap) c = ncmap; else if (c < 0) c = 0; const ColorB &col = cmap[c]; v0->SetColor(col); v3->SetColor(col); } } } break; } default: Matpack.Error("MpSurfaceBands: Illegal value for direction argument"); break; } }