Changeset 40107
- Timestamp:
- Aug 7, 2017, 9:32:12 AM (9 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/kapa2/src/DrawObjects.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/kapa2/src/DrawObjects.c
r40018 r40107 1 1 # include "Ximage.h" 2 3 void DrawBars (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object, int mode); 2 4 3 5 # define DrawLine(X1,Y1,X2,Y2) (XDrawLine (graphic->display, graphic->window, graphic->gc, (int)(X1), (int)(Y1), (int)(X2), (int)(Y2))) … … 36 38 } 37 39 38 /* Draw a specific object in the graph */ 39 int DrawObjectN (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) { 40 40 void DrawLineStyle (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) { 41 41 42 static char dot[2] = {2,3}; 42 43 static char short_dash[2] = {4,4}; … … 85 86 XSetForeground (graphic->display, graphic->gc, graphic->color[object[0].color]); 86 87 } 88 return; 89 } 90 91 /* Draw a specific object in the graph */ 92 int DrawObjectN (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) { 93 94 DrawLineStyle (graphic, graph, object); 87 95 88 96 switch (object[0].style) { … … 92 100 case KAPA_PLOT_HISTOGRAM: 93 101 DrawHistogram (graphic, graph, object); 102 break; 103 case KAPA_PLOT_BARS_SOLID: 104 DrawBars (graphic, graph, object, KAPA_PLOT_BARS_SOLID); 105 break; 106 case KAPA_PLOT_BARS_OUTLINE: 107 DrawBars (graphic, graph, object, KAPA_PLOT_BARS_OUTLINE); 108 break; 109 case KAPA_PLOT_BARS_OUTFILL: 110 DrawBars (graphic, graph, object, KAPA_PLOT_BARS_OUTFILL); 94 111 break; 95 112 case KAPA_PLOT_POINTS: … … 402 419 } 403 420 # endif 421 422 // uses object->color 423 # define HISTOGRAM_SOLID(X_VALUE, Y_VALUE, DX_VAL) { \ 424 /* histogram bar corners */ \ 425 double sxmin = (X_VALUE) - 0.5*(DX_VAL); \ 426 double sxmax = (X_VALUE) + 0.5*(DX_VAL); \ 427 double symin = Xaxis; \ 428 double symax = (Y_VALUE); \ 429 /* saturated values for corner coords: */ \ 430 sxmin = MIN (MAX (sxmin, X0), X1); \ 431 sxmax = MIN (MAX (sxmax, X0), X1); \ 432 symin = MAX (MIN (symin, Y0), Y1); \ 433 symax = MAX (MIN (symax, Y0), Y1); \ 434 double dy = fabs(symax - symin); \ 435 double ylow = MIN(symin, symax); \ 436 FillRectangle (sxmin, ylow, (DX_VAL), dy); } 437 438 // uses object->color 439 # define HISTOGRAM_OUTLINE(X_VALUE, Y_VALUE, DX_VAL) { \ 440 /* histogram bar corners */ \ 441 double sxmin = (X_VALUE) - 0.5*(DX_VAL); \ 442 double sxmax = (X_VALUE) + 0.5*(DX_VAL); \ 443 double symin = Xaxis; \ 444 double symax = (Y_VALUE); \ 445 /* saturated values for corner coords: */ \ 446 sxmin = MIN (MAX (sxmin, X0), X1); \ 447 sxmax = MIN (MAX (sxmax, X0), X1); \ 448 symin = MAX (MIN (symin, Y0), Y1); \ 449 symax = MAX (MIN (symax, Y0), Y1); \ 450 double dy = fabs(symax - symin); \ 451 double ylow = MIN(symin, symax); \ 452 DrawRectangle (sxmin, ylow, (DX_VAL), dy); } 453 454 # define HISTOGRAM_OUTFILL(X_VALUE, Y_VALUE, DX_VAL) { \ 455 /* histogram bar corners */ \ 456 double sxmin = (X_VALUE) - 0.5*(DX_VAL); \ 457 double sxmax = (X_VALUE) + 0.5*(DX_VAL); \ 458 double symin = Xaxis; \ 459 double symax = (Y_VALUE); \ 460 /* saturated values for corner coords: */ \ 461 sxmin = MIN (MAX (sxmin, X0), X1); \ 462 sxmax = MIN (MAX (sxmax, X0), X1); \ 463 symin = MAX (MIN (symin, Y0), Y1); \ 464 symax = MAX (MIN (symax, Y0), Y1); \ 465 double dy = fabs(symax - symin); \ 466 double ylow = MIN(symin, symax); \ 467 FillRectangle (sxmin, ylow, (DX_VAL), dy); \ 468 XSetForeground (graphic->display, graphic->gc, graphic->fore); \ 469 DrawRectangle (sxmin, ylow, (DX_VAL), dy); \ 470 XSetForeground (graphic->display, graphic->gc, graphic->color[object[0].color]); } 471 472 void DrawBars (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object, int mode) { 473 474 double mxi = graph[0].axis[0].dfx / (object[0].x1 - object[0].x0); // slope of the x-axis in x-pixels 475 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) 476 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) 477 double myj = graph[0].axis[1].dfy / (object[0].y1 - object[0].y0); // slope of the x-axis in x-pixels 478 479 // intercepts of axes 480 double bxi = graph[0].axis[0].fx - object[0].x0*graph[0].axis[0].dfx/(object[0].x1 - object[0].x0); 481 double bxj = -object[0].y0*graph[0].axis[1].dfx/(object[0].y1 - object[0].y0); 482 double byi = -object[0].x0*graph[0].axis[0].dfy/(object[0].x1 - object[0].x0); 483 double byj = graph[0].axis[1].fy - object[0].y0*graph[0].axis[1].dfy/(object[0].y1 - object[0].y0); 484 485 double bx = bxi + bxj; 486 double by = byi + byj; 487 488 // corner coords 489 double X0 = graph[0].axis[0].fx; 490 double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx; 491 double Y0 = graph[0].axis[1].fy; 492 double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy; 493 494 /* find the first valid datapoint */ 495 float *x = object[0].x; 496 float *y = object[0].y; 497 498 /* we are drawing bars which are filled rectangles of height y[i] and width 0.5*dx 499 one point at a time 500 */ 501 502 // I need to know the distance to the next and prev points to calculate dx 503 // for the first point, dx is x[1] - x[0] 504 // for the last point, dx is x[-1] - x[-2] (x[-1] is the last point) 505 // for the rest, dx is 0.5*(x[i+1] - x[i-1]) 506 507 // rather than working out complex on-the-fly logic, I want to find the first and last 508 // valid point in an initial pass, the calculate the above for the remainder. 509 // or make an index vector of only valid points? 510 511 int Ngood = 0; 512 ALLOCATE_PTR (goodPoint, int, object[0].Npts); 513 514 // x = ??, y = 0: this assumes the xaxis is parallel to the plot window (myi = 0) 515 // since y runs from large on bottom to small on top, this is slightly backwards 516 float Xaxis = by + YCENTER; 517 Xaxis = MAX (Y1, MIN (Xaxis, Y0)); // MIN & MAX reversed for neg y dir 518 519 for (int i = 0; i < object[0].Npts; i++) { 520 if (!(finite(x[i]) && finite(y[i]))) continue; 521 522 // coordinate on the screen of the point: 523 double sx1r = x[i]*mxi + y[i]*mxj + bx + XCENTER; 524 double sy1r = x[i]*myi + y[i]*myj + by + YCENTER; 525 526 if (sx1r < X0) { 527 // point to the left, skip it 528 continue; 529 } 530 if (sx1r > X1) { 531 // point to the right, skip it 532 continue; 533 } 534 535 goodPoint[Ngood] = i; 536 Ngood ++; 537 } 538 539 if (Ngood == 0) { 540 free (goodPoint); 541 return; 542 } 543 544 // if we only have 1 point, draw bar half the width of the screen 545 // this works fine, but the auto limits for 1 value are somewhat silly 546 if (Ngood == 1) { 547 // coordinate on the screen of the point: 548 int n = goodPoint[0]; 549 double sx1r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 550 double sy1r = x[n]*myi + y[n]*myj + by + YCENTER; 551 552 float dx = 0.5*object->size*(X1 - X0); 553 554 switch (mode) { 555 case KAPA_PLOT_BARS_SOLID: 556 HISTOGRAM_SOLID(sx1r, sy1r, dx); 557 break; 558 case KAPA_PLOT_BARS_OUTLINE: 559 HISTOGRAM_OUTLINE(sx1r, sy1r, dx); 560 break; 561 case KAPA_PLOT_BARS_OUTFILL: 562 HISTOGRAM_OUTFILL(sx1r, sy1r, dx); 563 break; 564 default: 565 HISTOGRAM_SOLID(sx1r, sy1r, dx); 566 break; 567 } 568 569 free (goodPoint); 570 return; 571 } 572 573 // first point: 574 { 575 int n; 576 n = goodPoint[1]; 577 double sx1r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 578 // double sy1r = x[n]*myi + y[n]*myj + by + YCENTER; 579 580 n = goodPoint[0]; 581 double sx0r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 582 double sy0r = x[n]*myi + y[n]*myj + by + YCENTER; 583 584 double dx = 0.5*object->size*(sx1r - sx0r); 585 586 switch (mode) { 587 case KAPA_PLOT_BARS_SOLID: 588 HISTOGRAM_SOLID(sx0r, sy0r, dx); 589 break; 590 case KAPA_PLOT_BARS_OUTLINE: 591 HISTOGRAM_OUTLINE(sx0r, sy0r, dx); 592 break; 593 case KAPA_PLOT_BARS_OUTFILL: 594 HISTOGRAM_OUTFILL(sx0r, sy0r, dx); 595 break; 596 default: 597 HISTOGRAM_SOLID(sx0r, sy0r, dx); 598 break; 599 } 600 } 601 602 for (int i = 1; i < Ngood - 1; i++) { 603 604 int n; 605 n = goodPoint[i + 1]; 606 double sx2r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 607 double sy2r = x[n]*myi + y[n]*myj + by + YCENTER; 608 609 n = goodPoint[i - 1]; 610 double sx0r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 611 double sy0r = x[n]*myi + y[n]*myj + by + YCENTER; 612 613 double dx = 0.5*0.5*object->size*(sx2r - sx0r); // 2 factors of 0.5 (we want half of the average spacing) 614 615 n = goodPoint[i]; 616 double sx1r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 617 double sy1r = x[n]*myi + y[n]*myj + by + YCENTER; 618 619 switch (mode) { 620 case KAPA_PLOT_BARS_SOLID: 621 HISTOGRAM_SOLID(sx1r, sy1r, dx); 622 break; 623 case KAPA_PLOT_BARS_OUTLINE: 624 HISTOGRAM_OUTLINE(sx1r, sy1r, dx); 625 break; 626 case KAPA_PLOT_BARS_OUTFILL: 627 HISTOGRAM_OUTFILL(sx1r, sy1r, dx); 628 break; 629 default: 630 HISTOGRAM_SOLID(sx1r, sy1r, dx); 631 break; 632 } 633 } 634 635 // last point: 636 { 637 int n; 638 n = goodPoint[Ngood - 1]; 639 double sx1r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 640 double sy1r = x[n]*myi + y[n]*myj + by + YCENTER; 641 642 n = goodPoint[Ngood - 2]; 643 double sx0r = x[n]*mxi + y[n]*mxj + bx + XCENTER; 644 // double sy0r = x[n]*myi + y[n]*myj + by + YCENTER; 645 646 double dx = 0.5*object->size*(sx1r - sx0r); 647 648 switch (mode) { 649 case KAPA_PLOT_BARS_SOLID: 650 HISTOGRAM_SOLID(sx1r, sy1r, dx); 651 break; 652 case KAPA_PLOT_BARS_OUTLINE: 653 HISTOGRAM_OUTLINE(sx1r, sy1r, dx); 654 break; 655 case KAPA_PLOT_BARS_OUTFILL: 656 HISTOGRAM_OUTFILL(sx1r, sy1r, dx); 657 break; 658 default: 659 HISTOGRAM_SOLID(sx1r, sy1r, dx); 660 break; 661 } 662 } 663 free (goodPoint); 664 return; 665 } 404 666 405 667 /******/
Note:
See TracChangeset
for help on using the changeset viewer.
