Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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);
  }
}
Ejemplo n.º 3
0
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);
    }
  }
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 6
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 &center = 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 &center = 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;
  }
}