Esempio n. 1
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);
}
Esempio n. 2
0
void ProgressMeter (Scene& scene, int min, int max, int cnt, void*)
//
// The progress meter hook is called during some long operations to
// give the user some indication that the program will ever finish.
// It draws a temperature gauge like progress indicator.
// Calling with cnt >= max removes the gauge. A gauge is only drawn,
// if the operation is expected to take more than few seconds.
//
{
    // position (x,y) and size (w x h) of horizontal gauge
    const int x = 20, y = 20, w = 150, h = 31;
 
    const ColorF GaugeColor(0.0,0.0,0.0), // black
	         BackColor(1.0,1.0,1.0),  // white
	         FrameColor(0.0,0.0,0.0); // black

    // draw gauge only if after 'wait_time' seconds less 
    // than 'wait_percentage' of the job is done.
    const int   wait_time = 2;
    const float wait_percentage = 0.5;

    static int waiting = false;
    static time_t last = 0;
    time_t now;

    if (min >= max) return;
    if (cnt >= max && last == 0) return;

    float percent_done = ((float)(cnt-min))/((float)(max-min));
    
    time(&now);

    if (last == 0) {        // calling gauge first time 
	last = now;
	waiting = true;
    } else if (waiting) {   // gauge is not yet drawn
	if ((now - last >= wait_time) 
	      && percent_done < wait_percentage) waiting = false;
    }

    if (! waiting) {
	if (now == last && cnt < max) return;  // maximally one draw per second
	last = now;

	// store old settings
	long old_line_color     = scene.GetInfo(LineColor); // doesn't work
	int  old_line_pattern   = scene.GetInfo(LinePattern),
	     old_line_thickness = scene.GetInfo(LineThickness);

	// draw the gauge
	scene.LineStyle(Solid,h);
	scene.SetColor(FrameColor);
	scene.Line(Pixel2D(x,y),Pixel2D(x+w,y));
	
	scene.LineStyle(Solid,h-4);
	scene.SetColor(BackColor);
	scene.Line(Pixel2D(x+1,y),Pixel2D(x+w-1,y));
	
	scene.LineStyle(Solid,h-8);
	scene.SetColor(GaugeColor);
	scene.Line(Pixel2D(x+2,y),
			  Pixel2D(x+(int)((float)(w-4)*percent_done),y));
	
	if (cnt >= max) { // remove gauge
	    last = 0;
	    scene.LineStyle(Solid,h);
	    scene.SetColor(GaugeColor);
	    scene.Line(Pixel2D(x,y),Pixel2D(x+w,y));
	}

	// restore old settings
	scene.LineStyle(old_line_pattern,old_line_thickness);
	scene.SetColor(old_line_color);
	scene.Flush();
    }
}