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 MakeWater (Matrix& M, float waterlevel = 0.0,
		float scale_x = 80, float scale_y = 120, float scale_z = 0.1)
{
  for (int i = M.Rlo(); i <= M.Rhi(); i++)
    for (int j = M.Clo(); j <= M.Chi(); j++)
      if (M(i,j) < waterlevel) {		   // apply noise to values below
	float x = scale_x * (i-M.Rlo())/M.Rows(),  // the water level to simulate
	      y = scale_y * (j-M.Clo())/M.Cols();	      // waves on the sea
	M(i,j) =  scale_z * Noise(x,y,0);
     }
}
int main (void)
{
  enum { N = 20, L = 10, resolution = 600};

  Matrix M = TestMatrix(N,N);

  Vector level(1,L);
  double mi = Min(M), ma = Max(M);
  for (int i = 1; i <= L; ++i) 
    level[i] = mi + (i-1)*(ma-mi)/(L-1);
  level[4]  = -3; 
  level[5]  = -2.5;
  cerr << mi << " " << ma << endl <<  level << endl;

  ColorMap cmap("spectral-256");
  MpImage image(resolution,resolution);
  Scene scene(image);

  MpContourSurface(scene,M, M.Rlo(),M.Rhi(), M.Clo(),M.Chi(), 
		   level,cmap,Min(M),Max(M));

  scene.LookFrom(Vector3D(100,50,-30));    // define the camera position
  scene.SetColoring(Scene::PerVertex);     // coloring (GLobal/PerVertex/PerFacet)
  scene.SetGlobalShading(Facet::Flat);     // shading (Constant/Flat/Gouraud/Phong)
  scene.SetGlobalEdgeLines(true);	   // edge lines (true/false)

  scene.Show();				   // now start rendering of the surface

  MpFrame display("Contour",resolution+4,resolution+4);
  new MpScrollImageWindow(display,image,resolution+4,resolution+4);
  new MpQuitButton(display,"Quit",80,25,0,0);
  display.EventLoop();
}
void MpViewGraphData::DrawPolesPlot (Scene& scene, const Matrix& Z, 
				     const Trafo& P)
{
  int identical_colors = (Three_Dim_Poles_Color == Three_Dim_Poles_Head_Color);
  int r = Three_Dim_Poles_Head_Radius;

  // set color only once
  if (identical_colors) scene.SetColor(Three_Dim_Poles_Color);

  // set lines style for poles
  scene.LineStyle(Solid,Three_Dim_Poles_Width);

  for (int x = Z.Rlo(); x <= Z.Rhi(); x++)
    for (int y = Z.Clo(); y <= Z.Chi(); y++) {

      // draw line of pole
      if ( ! identical_colors ) scene.SetColor(Three_Dim_Poles_Color);
      if (Three_Dim_Poles_Width)
	scene.Line( P * Vector3D(y,Three_Dim_Poles_Base,x), 
		    P * Vector3D(y,Z[x][y],x) );

      // draw head of pole
      if (Three_Dim_Poles_Head_Radius > 0) {
	if ( ! identical_colors ) scene.SetColor(Three_Dim_Poles_Head_Color);
	scene.Arc( scene.Map(P * Vector3D(y,Z[x][y],x)), 
		   r,r, 0, 360*64, Fill);
      }
    }
}
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 FractalSurface (Matrix& X, int b, double H, long seed)
{
    // The dimension of the matrix is 2^b + 1. Resize if neccessary 
    // (don't do anything if size is ok), then reset to zero.
    int n = 1 << b;

    if (X.Rlo() != 0 || X.Clo() != 0 || X.Rhi() != n || X.Chi() != n) {
      X.Remove();
      X = Matrix(0,n,0,n);
    }

    // clear
    X = 0.0;
    
    // Create normal distributed deviates with zero mean and unit variance
    double mean = 0, sdev = 1;
    Ran002 rnd(seed);
    NormalDistribution N(mean, sdev, &rnd);
         
    // Voss random addition algorithm
    int stride = n/2, off = stride/2;

    // start
    for (int i = 0; i <= n; i += stride)
      for (int j = 0; j <= n; j += stride) X(i,j) = N();

    // subdivide
    for (int g = 1; g < b; g++) {
	int i,j;

	// interpolate
	for (i = off; i <= n-off; i += stride)
	  for (j = off; j <= n-off; j += stride)
	    X(i,j) = 0.25 * ( X(i-off,j-off) + X(i-off,j+off) 
			    + X(i+off,j+off) + X(i+off,j-off));	
	for (i = 0; i <= n; i += stride)
	  for (j = off; j <= n-off; j += stride)
	    X(i,j) = 0.5 * (X(i,j-off) + X(i,j+off));
	for (i = off; i <= n-off; i += stride)
	  for (j = 0; j <= n; j += stride)
	    X(i,j) = 0.5 * (X(i-off,j) + X(i+off,j));

	// add noise with reduced variance
	sdev *= pow(0.5,H);
	N = NormalDistribution(mean, sdev, &rnd);
	for (i = 0; i <= n; i += off) 
	  for (j = 0; j <= n; j += off) X(i,j) += N(); 

	// next subdivision
	stride = off; 
	off /= 2;
    } 
}
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);  
    }
}
Beispiel #8
0
int main (void)
{
  MpImage image(size,size);		     // allocate size x size raster image

  MpImage backimg;			                 // read background image
  if (back_image) {
    if ( ! backimg.ReadAnyFile(back_image) )
      Matpack.Error("Can't read \"%s\"",back_image);
  }

  // read potential matrix
  ifstream pot_stream("pot");
  if ( ! pot_stream) Matpack.Error("Can't open pot data file \"%s\"","pot");
  pot_stream >> pot;
  pot_stream.close();

  for (int i = 0; i <= 175; i += 5) {  			   // loop through frames

    fprintf(stdout,"\rframe %d...",i); fflush(stdout);         // what's going on

    // read complex wave function
    char file_name[200], pipe_name[200], output_name[200];
    sprintf(file_name,"psi%d.gz",i);		           // generate input data file name
    sprintf(pipe_name,"gunzip -c %s > psi.dat",file_name); // decompress data file 
    sprintf(output_name,"psi%03d.jpg",i);                  // generate output file name

    system(pipe_name);
    ifstream data_stream("psi.dat");
    if ( ! data_stream) Matpack.Error("Can't open data file psi.dat");
    data_stream >> psi;
    data_stream.close();
    unlink("psi.dat");

    // consistency checks
    if ( pot.Rlo() != psi.Rlo() || pot.Rhi() != psi.Rhi() || 
	 pot.Clo() != psi.Clo() || pot.Chi() != psi.Chi() )
      Matpack.Error("non-conformant index range of potential and wave function");

    Scene scene;				   // define scene for 3d drawing

    // create surface
    double u0 = psi.Clo(), u1 = psi.Chi(), 
           v0 = psi.Rlo(), v1 = psi.Rhi();
    int    nu = psi.Chi()-psi.Clo(), nv = psi.Rhi()-psi.Rlo(),  
           su = 0, sv = 0,  periodic = 0;
    ParametricSurface(scene, height_fcn, u0,u1,nu,su, v0,v1,nv,sv, 
		      periodic, Identity, color_fcn);

    scene.BoxRatios(1,z_aspect,1);               // scale scene to box with x:y:z

    float dist = 1.6;			                    // distance parameter
    scene.Look(Vector3D( 1.1*dist, 1.5*dist, 1.4*dist), // camera position vector
	       Vector3D(-1.1*dist,-1.65*dist,-1.4*dist), // look direction vector
	       FieldOfView(45), 		 // field of view angle in degree
	       0);		             // "twist your head" angle in degree

    scene.SetGlobalShading(Facet::Gouraud);   
                                       // shading (None, Flat, Gouraud, Phong...)
    scene.SetHiddenSurface(preview ? Scene::DepthSort : Scene::TopoSort);

    // edgeline drawing option (None,...)
    scene.SetGlobalEdgeLines(show_grid ? Facet::Individual : None);

    // Setting per-vertex coloring is the best choice to get smoothly changing
    // colors on the surface. This requires Gouraud or Phong shading to be
    // switched on. If you use per-facet coloring then the facet edges are still
    // slightly visible ("Scene::PerFacet")
    scene.SetColoring(Scene::PerVertex);

    // Define ambient light, RGB color, and specular light and exponent
    // If per-vertex coloring or per-facet coloring is set, then only the ambient
    // light factor and the specular light factor and exponent are in effect, and
    // the diffuse color is ignored (the vertex or facet color is used instead)
    Material material(0.6, ColorF(1.,0.8,0.), 0.3,1.8); 
    scene.SetFacetMaterial(material);		    // set all facets to material

    scene.Open(image);			        // direct drawing to raster image
    if (back_image)
      image.InsertTiled(backimg);
    else
      scene.SetBackground(back_color); 	        // draw background with RGB color
    scene.SetColor(edge_color);		           // define color for edge lines
    scene.Show();			  		    // render the surface
    scene.Close();				       // call always after close

    image.WriteJpegFile(output_name,jpeg_quality,jpeg_smooth);// write JPEG image

    // write GIF image, if you prefer that
    //image.WriteGifFile(output_name);     // write image as GIF

  }

  cout << "\nfinished" << endl;
}
Beispiel #9
0
void ContourLine (Scene& scene, const Matrix& z, 
                  double h, int mode, double hxy, const Trafo& trafo, 
                  char* label, double label_distance)
//
//  Plots a single contour line at a given height 'h' in the
//  data set z. Depending on the mode flag
//  it uses a linear interpolation or Bezier polynomials to draw
//  smooth contour lines.
//
//  Possible values for the mode flag are:
//
//    ContourPlotClass::Lines
//                        to draw a contour line with straight line segments
//
//    ContourPlotClass::BezierSpline
//                        to draw a smooth contour line using cubic 
//                        Bezier polynomials (this is the default)
//
//    ContourPlotClass::CardinalSpline
//                        draw smooth lines using cubic Cardinal Splines
//
//    Project3d           to project the contour line in 3d space onto the 
//                        xy-plane at height hxy. (default is 2d).
//
//  The mode flags can be combined like 'Linear|Project3D'
//
{
    int x,y;

    if (! scene.IsOpen()) 
      Matpack.Error(Mat::UnspecifiedError,"ContourLine: scene is not open");

    // make some parameters global 
    S = &scene;
    P = trafo;
    height = h;
    xyheight = hxy;
    xdim = z.Chi()-z.Clo()+2;
    ydim = z.Rhi()-z.Rlo()+2;
    xoff = z.Clo()-1;
    yoff = z.Rlo()-1;
    lab = label;
    lab_dist = label_distance;

    // straight lines or Bezier polynomials are drawn 
    drawlinear = mode & ContourPlotClass::Lines; 
    drawbspline = mode & ContourPlotClass::CardinalSpline;

    // use 3D or 2D projection
    project3d  = (mode & Project3D);
    
    // set the resolution global variable - must at least be = 3 !!
    resol = scene.curve.resolution + 2; 

    // allocate a cut-array 
    cut = bytematrix(0,xdim,0,ydim);

    // clear cut-array boundaries 
    for (x = 0; x <= xdim; x++)
      cut[x][0] = cut[x][ydim] = lower;
    for (y = 0; y <= ydim; y++)
      cut[0][y] = cut[xdim][y] = lower;

    // determine cut-array 
    for (x = 1; x < xdim; x++)
      for (y = 1; y < ydim; y++)
        cut[x][y] = (z[y+yoff][x+xoff] >= height) ? higher : lower;

#ifdef DEBUG
    printf("\nBEFORE\n");
    for (x = 0; x <= xdim; x++) {
        for (y = 0; y <= ydim; y++) 
          printf("%c",cut[x][y]==0?'.':cut[x][y]==1?'+':'2');
        printf("\n");
    }
    printf("\n");
#endif    
    
    // find contour lines  
    // ------------------

    for (x = 1; x < xdim; x++)
      for (y = 1; y < ydim; y++)
        if (cut[x][y] == higher) 
          if (cut[x][y-1] == lower)      // initial search direction = 0
            search_contour(z,x,y-1,0); 
          else if (cut[x][y+1] == lower) // initial search direction = 2
            search_contour(z,x,y+1,2); 

#ifdef DEBUG
    printf("\nAFTER\n");
    for (x = 0; x <= xdim; x++) {
        for (y = 0; y <= ydim; y++) 
          printf("%c",cut[x][y]==0?'.':cut[x][y]==1?'+':'2');
        printf("\n");
    }
    printf("\n");
#endif    

    // flush graphics buffer 
    scene.Flush();

    // free the cut-array 
    freebytematrix(0,xdim,0,ydim,cut);
}
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;
}
Beispiel #11
0
Matrix operator * (const Matrix& A, const Matrix& B)
{
    if (A.Clo() != B.Rlo() || A.Chi() != B.Rhi()) 
      Matpack.Error("Matrix operator * (const Matrix&, const Matrix&): "
                    "non conformant arguments\n");

    // allocate return matrix
    Matrix C(A.Rlo(),A.Rhi(),B.Clo(),B.Chi());
    
    //------------------------------------------------------------------------//
    // the BLAS version
    //------------------------------------------------------------------------//

#if defined ( _MATPACK_USE_BLAS_ )

    if ( LT(B) ) {                   // full matrix * lower triangle
#ifdef DEBUG
        cout << "GM*LT\n";
#endif
        checksquare(B);

        // copy A to C to protect from overwriting
        copyvec(C.Store(),A.Store(),A.Elements());

        charT   side('L'), uplo('U'), transc('N'), diag('N');
        intT    m(C.Cols()), n(C.Rows()),
                ldb(B.Cols()), ldc(C.Cols());
        doubleT alpha(1.0);
        
        F77NAME(dtrmm)(&side,&uplo,&transc,&diag,&m,&n,
                       &alpha,B.Store(),&ldb, C.Store(),&ldc);


    } else if ( UT(B) ) {             // full matrix * upper triangle
#ifdef DEBUG
        cout << "GM*UT\n";
#endif
        checksquare(B);

        // copy A to C to protect from overwriting
        copyvec(C.Store(),A.Store(),A.Elements());

        charT   side('L'), uplo('L'), transc('N'), diag('N');
        intT    m(C.Cols()), n(C.Rows()),
                ldb(B.Cols()), ldc(C.Cols());
        doubleT alpha(1.0);
        
        F77NAME(dtrmm)(&side,&uplo,&transc,&diag,&m,&n,
                       &alpha,B.Store(),&ldb, C.Store(),&ldc);


    } else if ( LT(A) ) {            // lower triangle * full matrix
#ifdef DEBUG
        cout << "LT*GM\n";
#endif

        checksquare(A);

        // copy B to C to protect from overwriting
        copyvec(C.Store(),B.Store(),B.Elements());

        charT   side('R'), uplo('U'), transc('N'), diag('N');
        intT    m(C.Cols()), n(C.Rows()),
                ldb(A.Cols()), ldc(C.Cols());
        doubleT alpha(1.0);
        
        F77NAME(dtrmm)(&side,&uplo,&transc,&diag,&m,&n,
                       &alpha,A.Store(),&ldb, C.Store(),&ldc);



    } else if ( UT(A) ) {            // upper triangle * full matrix
#ifdef DEBUG
        cout << "UT*GM\n";
#endif
        checksquare(A);

        // copy A to C to protect from overwriting
        copyvec(C.Store(),B.Store(),B.Elements());

        charT   side('R'), uplo('L'), transc('N'), diag('N');
        intT    m(C.Cols()), n(C.Rows()),
                ldb(A.Cols()), ldc(C.Cols());
        doubleT alpha(1.0);
        
        F77NAME(dtrmm)(&side,&uplo,&transc,&diag,&m,&n,
                       &alpha,A.Store(),&ldb, C.Store(),&ldc);

    } else /* GM(A) and GM(B) */ {   // GM*GM: full matrix * full matrix
#ifdef DEBUG
        cout << "GM*GM\n";
#endif

        charT   t('N');
        intT    m(B.Cols()), n(A.Rows()), k(B.Rows()),
                lda(A.Cols()), ldb(B.Cols()), ldc(C.Cols());
        doubleT alpha(1.0), beta(0.0);
        
        F77NAME(dgemm)(&t,&t, &m,&n,&k,
                       &alpha,B.Store(),&ldb, A.Store(),&lda, 
                       &beta,C.Store(),&ldc);
    }

    //------------------------------------------------------------------------//
    // the non-BLAS version
    //------------------------------------------------------------------------//

#else
    int  cl = A.cl,   ch = A.ch,
        arl = A.rl,  arh = A.rh,
        bcl = B.cl,  bch = B.ch;

    // avoid call to index operator that optimizes very badely
    double **a = A.M, **b = B.M, **c = C.M;
    for (int i = arl; i <= arh; i++)  {
        for (int j = bcl; j <= bch; j++) c[i][j] = 0.0;
        for (int l = cl; l <= ch; l++) {
            if ( a[i][l] != 0.0 ) {
                double temp = a[i][l];
                for (int j = bcl; j <= bch; j++)
                    c[i][j] += temp * b[l][j];
            }
        }
    }

#endif

    return C.Value();
}
Beispiel #12
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;
  }
}