Changeset 40125

Show
Ignore:
Timestamp:
08/22/17 14:52:07 (4 months ago)
Author:
eugene
Message:

add PS and PNG bar graph support

Location:
branches/eam_branches/ohana.20170822/src/kapa2/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ohana.20170822/src/kapa2/src/DrawObjects.c

    r40123 r40125  
    11# include "Ximage.h" 
    22 
     3/* DrawRectangle & FillRectangle : take rectangle lower-left corner and widths  
     4   DrawCircle & FillCircle : take circle center and radius 
     5*/ 
     6 
    37# define DrawLine(X1,Y1,X2,Y2) (XDrawLine (graphic->display, graphic->window, graphic->gc, (int)(X1), (int)(Y1), (int)(X2), (int)(Y2))) 
    4 # define DrawRectangle(X1,Y1,X2,Y2) (XDrawRectangle (graphic->display, graphic->window, graphic->gc, (int)(X1), (int)(Y1), (int)(X2), (int)(Y2))) 
    5 # define FillRectangle(X1,Y1,X2,Y2) (XFillRectangle (graphic->display, graphic->window, graphic->gc, (int)(X1), (int)(Y1), (int)(X2), (int)(Y2))) 
     8# define DrawRectangle(X,Y,dX,dY) (XDrawRectangle (graphic->display, graphic->window, graphic->gc, (int)(X), (int)(Y), (int)(dX), (int)(dY))) 
     9# define FillRectangle(X,Y,dX,dY) (XFillRectangle (graphic->display, graphic->window, graphic->gc, (int)(X), (int)(Y), (int)(dX), (int)(dY))) 
    610# define DrawCircle(X,Y,R) (XDrawArc (graphic->display, graphic->window, graphic->gc, (int)(X-R), (int)(Y-R), abs(2*R), abs(2*R), 0, 23040)) 
    711# define FillCircle(X,Y,R) (XFillArc (graphic->display, graphic->window, graphic->gc, (int)(X-R), (int)(Y-R), abs(2*R), abs(2*R), 0, 23040)) 
  • branches/eam_branches/ohana.20170822/src/kapa2/src/PSObjects.c

    r39926 r40125  
    11# include "Ximage.h" 
    22 
     3void PSBars (KapaGraphWidget *graph, Gobjects *object, FILE *f, int mode); 
     4 
     5/* DrawRectangle & FillRectangle : take rectangle lower-left corner and widths  
     6   DrawCircle & FillCircle : take circle center and radius 
     7*/ 
     8 
    39# define DrawLine(X1,Y1,X2,Y2) (fprintf (f, " %6.2f %6.2f %6.2f %6.2f L\n", X1, graphic->dy - Y1, X2, graphic->dy - Y2)) 
    4 # define DrawRectangle(X,Y,dX,dY) (fprintf (f, " %6.2f %6.2f %6.2f %6.2f B\n", (dX), (dY), (X-0.5*dX), (graphic->dy-Y-0.5*dY))) 
    5 # define FillRectangle(X,Y,dX,dY) (fprintf (f, " %6.2f %6.2f %6.2f %6.2f F\n", (dX), (dY), (X-0.5*dX), (graphic->dy-Y-0.5*dY))) 
     10# define DrawRectangle(X,Y,dX,dY) (fprintf (f, " %6.2f %6.2f %6.2f %6.2f B\n", (dX), (dY), (X), (graphic->dy-Y))) 
     11# define FillRectangle(X,Y,dX,dY) (fprintf (f, " %6.2f %6.2f %6.2f %6.2f F\n", (dX), (dY), (X), (graphic->dy-Y))) 
    612# define DrawCircle(X1,Y1,R) (fprintf (f, " %6.2f %6.2f %6.2f C\n", (X1), (graphic->dy - Y1), (R))) 
    713# define FillCircle(X1,Y1,R) (fprintf (f, " %6.2f %6.2f %6.2f FC\n", (X1), (graphic->dy - Y1), (R))) 
     
    3238} 
    3339 
    34 int PSObjectsN (KapaGraphWidget *graph, Gobjects *object, FILE *f) { 
    35    
     40void PSLineStyle (KapaGraphWidget *graph, Gobjects *object, FILE *f) { 
     41 
    3642  static char short_dash[] = "4 4"; 
    3743  static char long_dash[] = "8 8"; 
     
    6470    fprintf (f, "%s setrgbcolor\n", KapaColorRGBString(object->color)); 
    6571  } 
     72} 
     73 
     74int PSObjectsN (KapaGraphWidget *graph, Gobjects *object, FILE *f) { 
     75   
     76  PSLineStyle (graph, object, f); 
    6677 
    6778  switch (object->style) { 
     
    7182    case KAPA_PLOT_HISTOGRAM:  
    7283      PSHistogram (graph, object, f); 
     84      break; 
     85    case KAPA_PLOT_BARS_SOLID: 
     86      PSBars (graph, object, f, KAPA_PLOT_BARS_SOLID); 
     87      break; 
     88    case KAPA_PLOT_BARS_OUTLINE: 
     89      PSBars (graph, object, f, KAPA_PLOT_BARS_OUTLINE); 
     90      break; 
     91    case KAPA_PLOT_BARS_OUTFILL: 
     92      PSBars (graph, object, f, KAPA_PLOT_BARS_OUTFILL); 
    7393      break; 
    7494    case KAPA_PLOT_POINTS:  
     
    265285  DrawLine (sx1, sy1, sxa, sy1); 
    266286  DrawLine (sxa, sy1, sxa, sya); 
    267  
    268 # if (0) 
    269   sx0 = x[i]*mxi + y[i]*mxj + bx; 
    270   sy0 = x[i]*myi + y[i]*myj + by; 
    271   sx0 = MIN (MAX (sx0, X0), X1); 
    272   sy0 = MAX (MIN (sy0, Y0), Y1); 
    273    
    274   /* continue with rest of points */ 
    275   for (i++; i < object[0].Npts; i++) { 
     287} 
     288 
     289// uses object->color 
     290# define HISTOGRAM_SOLID(X_VALUE, Y_VALUE, DX_VAL) {                    \ 
     291  /* histogram bar corners */                                           \ 
     292  double sxmin = (X_VALUE) - 0.5*(DX_VAL);                              \ 
     293  double sxmax = (X_VALUE) + 0.5*(DX_VAL);                              \ 
     294  double symin = Xaxis;                                                 \ 
     295  double symax = (Y_VALUE);                                             \ 
     296  /* saturated values for corner coords: */                             \ 
     297  sxmin = MIN (MAX (sxmin, X0), X1);                                    \ 
     298  sxmax = MIN (MAX (sxmax, X0), X1);                                    \ 
     299  symin = MAX (MIN (symin, Y0), Y1);                                    \ 
     300  symax = MAX (MIN (symax, Y0), Y1);                                    \ 
     301  double dy = fabs(symax - symin);                                      \ 
     302  double ylow = MIN(symin, symax);                                      \ 
     303  FillRectangle (sxmin, ylow, (DX_VAL), dy); } 
     304 
     305// uses object->color 
     306# define HISTOGRAM_OUTLINE(X_VALUE, Y_VALUE, DX_VAL) {                  \ 
     307  /* histogram bar corners */                                           \ 
     308  double sxmin = (X_VALUE) - 0.5*(DX_VAL);                              \ 
     309  double sxmax = (X_VALUE) + 0.5*(DX_VAL);                              \ 
     310  double symin = Xaxis;                                                 \ 
     311  double symax = (Y_VALUE);                                             \ 
     312  /* saturated values for corner coords: */                             \ 
     313  sxmin = MIN (MAX (sxmin, X0), X1);                                    \ 
     314  sxmax = MIN (MAX (sxmax, X0), X1);                                    \ 
     315  symin = MAX (MIN (symin, Y0), Y1);                                    \ 
     316  symax = MAX (MIN (symax, Y0), Y1);                                    \ 
     317  double dy = fabs(symax - symin);                                      \ 
     318  double ylow = MAX(symin, symax);                                      \ 
     319  DrawRectangle (sxmin, ylow, (DX_VAL), dy); } 
     320 
     321# define HISTOGRAM_OUTFILL(X_VALUE, Y_VALUE, DX_VAL) {                  \ 
     322  /* histogram bar corners */                                           \ 
     323  double sxmin = (X_VALUE) - 0.5*(DX_VAL);                              \ 
     324  double sxmax = (X_VALUE) + 0.5*(DX_VAL);                              \ 
     325  double symin = Xaxis;                                                 \ 
     326  double symax = (Y_VALUE);                                             \ 
     327  /* saturated values for corner coords: */                             \ 
     328  sxmin = MIN (MAX (sxmin, X0), X1);                                    \ 
     329  sxmax = MIN (MAX (sxmax, X0), X1);                                    \ 
     330  symin = MIN (MAX (symin, Y0), Y1);                                    \ 
     331  symax = MIN (MAX (symax, Y0), Y1);                                    \ 
     332  double dy = fabs(symax - symin);                                      \ 
     333  double ylow = MIN(symin, symax);                                      \ 
     334  FillRectangle (sxmin, ylow, (DX_VAL), dy);                            \ 
     335  fprintf (f, "0.00 0.00 0.00 setrgbcolor\n");                          \ 
     336  DrawRectangle (sxmin, ylow, (DX_VAL), dy);                            \ 
     337  fprintf (f, "%s setrgbcolor\n", KapaColorRGBString(object->color)); } 
     338 
     339void PSBars (KapaGraphWidget *graph, Gobjects *object, FILE *f, int mode) { 
     340 
     341  double mxi = graph[0].axis[0].dfx / (object[0].x1 - object[0].x0); // slope of the x-axis in x-pixels 
     342  double mxj = graph[0].axis[1].dfx / (object[0].y1 - object[0].y0); // slope of the x-axis in y-pixels (always 0 for now) 
     343  double myi = graph[0].axis[0].dfy / (object[0].x1 - object[0].x0); // slope of the x-axis in x-pixels (always 0 for now) 
     344  double myj = graph[0].axis[1].dfy / (object[0].y1 - object[0].y0); // slope of the x-axis in x-pixels 
     345   
     346  // intercepts of axes 
     347  double bxi  =  graph[0].axis[0].fx - object[0].x0*graph[0].axis[0].dfx/(object[0].x1 - object[0].x0); 
     348  double bxj  =  -object[0].y0*graph[0].axis[1].dfx/(object[0].y1 - object[0].y0); 
     349  double byi  =  -object[0].x0*graph[0].axis[0].dfy/(object[0].x1 - object[0].x0); 
     350  double byj  =  graph[0].axis[1].fy - object[0].y0*graph[0].axis[1].dfy/(object[0].y1 - object[0].y0); 
     351   
     352  double bx = bxi + bxj; 
     353  double by = byi + byj; 
     354   
     355  // corner coords 
     356  double X0 = graph[0].axis[0].fx; 
     357  double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx; 
     358  double Y0 = graph[0].axis[1].fy; 
     359  double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy; 
     360  // NOTE: Y0 > Y1 (dfy is negative) 
     361 
     362  /* find the first valid datapoint */ 
     363  float *x = object[0].x; 
     364  float *y = object[0].y; 
     365   
     366  /* we are drawing bars which are filled rectangles of height y[i] and width 0.5*dx 
     367     one point at a time 
     368 
     369     I need to know the distance to the next and prev points to calculate dx 
     370     for the first point, dx is x[1] - x[0] 
     371     for the last point, dx is x[-1] - x[-2] (x[-1] is the last point) 
     372     for the rest, dx is 0.5*(x[i+1] - x[i-1]) 
     373     
     374     rather than working out complex on-the-fly logic, I want to find the first and last 
     375     valid point in an initial pass, then calculate the above for the remainder. 
     376     TBD: make an index vector of only valid points? 
     377  */ 
     378 
     379  int Ngood = 0; 
     380  ALLOCATE_PTR (goodPoint, int, object[0].Npts); 
     381 
     382  // x = ??, y = 0: this assumes the xaxis is parallel to the plot window (myi = 0) 
     383  // note: Y0 > Y1 : y runs from large on bottom to small on top 
     384  float Xaxis = by; 
     385  Xaxis = MAX (Y1, MIN (Xaxis, Y0)); 
     386 
     387  for (int i = 0; i < object[0].Npts; i++) { 
    276388    if (!(finite(x[i]) && finite(y[i]))) continue; 
    277     sx1 = x[i]*mxi + y[i]*mxj + bx; 
    278     sy1 = x[i]*myi + y[i]*myj + by; 
    279     sx1 = MIN (MAX (sx1, X0), X1); 
    280     sy1 = MAX (MIN (sy1, Y0), Y1); 
    281     sxa = 0.5*(sx0 + sx1); 
    282     DrawLine (sx0, sy0, sxa, sy0); 
    283     DrawLine (sxa, sy0, sxa, sy1); 
    284     DrawLine (sxa, sy1, sx1, sy1); 
    285     sx0 = sx1; sy0 = sy1; 
    286   } 
    287 # endif 
     389 
     390    // coordinate on the screen of the point: 
     391    double sx1r = x[i]*mxi + y[i]*mxj + bx; 
     392 
     393    if (sx1r < X0) { 
     394      // point to the left, skip it 
     395      continue; 
     396    } 
     397    if (sx1r > X1) { 
     398      // point to the right, skip it 
     399      continue; 
     400    } 
     401 
     402    goodPoint[Ngood] = i; 
     403    Ngood ++; 
     404  } 
     405     
     406  if (Ngood == 0) { 
     407    free (goodPoint); 
     408    return; 
     409  } 
     410 
     411  // if we only have 1 point, draw bar half the width of the screen 
     412  // this works fine, but the auto limits for 1 value are somewhat silly 
     413  if (Ngood == 1) { 
     414    // coordinate on the screen of the point: 
     415    int n = goodPoint[0]; 
     416    double sx1r = x[n]*mxi + y[n]*mxj + bx; 
     417    double sy1r = x[n]*myi + y[n]*myj + by; 
     418 
     419    float dx = 0.5*object->size*(X1 - X0); 
     420     
     421    switch (mode) { 
     422      case KAPA_PLOT_BARS_SOLID: 
     423        HISTOGRAM_SOLID(sx1r, sy1r, dx); 
     424        break; 
     425      case KAPA_PLOT_BARS_OUTLINE: 
     426        HISTOGRAM_OUTLINE(sx1r, sy1r, dx); 
     427        break; 
     428      case KAPA_PLOT_BARS_OUTFILL: 
     429        HISTOGRAM_OUTFILL(sx1r, sy1r, dx); 
     430        break; 
     431      default: 
     432        HISTOGRAM_SOLID(sx1r, sy1r, dx); 
     433        break; 
     434    } 
     435 
     436    free (goodPoint); 
     437    return; 
     438  } 
     439 
     440  // first point: 
     441  { 
     442    int n; 
     443    n = goodPoint[1]; 
     444    double sx1r = x[n]*mxi + y[n]*mxj + bx; 
     445 
     446    n = goodPoint[0]; 
     447    double sx0r = x[n]*mxi + y[n]*mxj + bx; 
     448    double sy0r = x[n]*myi + y[n]*myj + by; 
     449 
     450    double dx = 0.5*object->size*(sx1r - sx0r); 
     451     
     452    switch (mode) { 
     453      case KAPA_PLOT_BARS_SOLID: 
     454        HISTOGRAM_SOLID(sx0r, sy0r, dx); 
     455        break; 
     456      case KAPA_PLOT_BARS_OUTLINE: 
     457        HISTOGRAM_OUTLINE(sx0r, sy0r, dx); 
     458        break; 
     459      case KAPA_PLOT_BARS_OUTFILL: 
     460        HISTOGRAM_OUTFILL(sx0r, sy0r, dx); 
     461        break; 
     462      default: 
     463        HISTOGRAM_SOLID(sx0r, sy0r, dx); 
     464        break; 
     465    } 
     466  } 
     467 
     468  for (int i = 1; i < Ngood - 1; i++) { 
     469 
     470    int n; 
     471    n = goodPoint[i + 1]; 
     472    double sx2r = x[n]*mxi + y[n]*mxj + bx; 
     473 
     474    n = goodPoint[i - 1]; 
     475    double sx0r = x[n]*mxi + y[n]*mxj + bx; 
     476 
     477    // below we have 2 factors of 0.5 (we want half of the average spacing) 
     478    double dx = 0.5*0.5*object->size*(sx2r - sx0r); 
     479 
     480    n = goodPoint[i]; 
     481    double sx1r = x[n]*mxi + y[n]*mxj + bx; 
     482    double sy1r = x[n]*myi + y[n]*myj + by; 
     483 
     484    switch (mode) { 
     485      case KAPA_PLOT_BARS_SOLID: 
     486        HISTOGRAM_SOLID(sx1r, sy1r, dx); 
     487        break; 
     488      case KAPA_PLOT_BARS_OUTLINE: 
     489        HISTOGRAM_OUTLINE(sx1r, sy1r, dx); 
     490        break; 
     491      case KAPA_PLOT_BARS_OUTFILL: 
     492        HISTOGRAM_OUTFILL(sx1r, sy1r, dx); 
     493        break; 
     494      default: 
     495        HISTOGRAM_SOLID(sx1r, sy1r, dx); 
     496        break; 
     497    } 
     498  } 
     499   
     500  // last point: 
     501  { 
     502    int n; 
     503    n = goodPoint[Ngood - 1]; 
     504    double sx1r = x[n]*mxi + y[n]*mxj + bx; 
     505    double sy1r = x[n]*myi + y[n]*myj + by; 
     506 
     507    n = goodPoint[Ngood - 2]; 
     508    double sx0r = x[n]*mxi + y[n]*mxj + bx; 
     509 
     510    double dx = 0.5*object->size*(sx1r - sx0r); 
     511 
     512    switch (mode) { 
     513      case KAPA_PLOT_BARS_SOLID: 
     514        HISTOGRAM_SOLID(sx1r, sy1r, dx); 
     515        break; 
     516      case KAPA_PLOT_BARS_OUTLINE: 
     517        HISTOGRAM_OUTLINE(sx1r, sy1r, dx); 
     518        break; 
     519      case KAPA_PLOT_BARS_OUTFILL: 
     520        HISTOGRAM_OUTFILL(sx1r, sy1r, dx); 
     521        break; 
     522      default: 
     523        HISTOGRAM_SOLID(sx1r, sy1r, dx); 
     524        break; 
     525    } 
     526  } 
     527  free (goodPoint); 
     528  return; 
    288529} 
    289530 
     
    310551  by = byi + byj; 
    311552   
    312   Graphic *graphic = GetGraphic(); 
    313  
     553  // scaled colors use the colormap defined for the graphic 
    314554  ALLOCATE (pixel1, float, graphic[0].Npixels); 
    315555  ALLOCATE (pixel2, float, graphic[0].Npixels); 
     
    347587          } 
    348588          D = scaleSize ? dz*z[i] : ds; 
    349           DrawRectangle (sx, sy, 2*D, 2*D); 
     589          DrawRectangle (sx - D, sy - D, 2*D, 2*D); 
    350590        } 
    351591      } 
     
    605845          } 
    606846          D = scaleSize ? dz*z[i] : ds; 
    607           FillRectangle (sx, sy, 2*D, 2*D); 
     847          FillRectangle (sx - D, sy - D, 2*D, 2*D); 
    608848        } 
    609849      } 
  • branches/eam_branches/ohana.20170822/src/kapa2/src/bDrawObjects.c

    r40123 r40125  
    507507   
    508508  // scaled colors use the colormap defined for the graphic 
    509   Graphic *graphic = GetGraphic(); 
    510  
    511509  ALLOCATE (pixel1, unsigned char, graphic[0].Npixels); 
    512510  ALLOCATE (pixel2, unsigned char, graphic[0].Npixels); 
     
    520518  } 
    521519 
    522   /**** points are scaled by object.z ***/ 
     520  /**** point sizes are scaled by object.size, colors by object.color ***/ 
    523521  int scaleSize = (object[0].size < 0); 
    524522  int scaleColor = (object[0].color < 0);