Changeset 40926
- Timestamp:
- Oct 8, 2019, 9:11:38 PM (7 years ago)
- Location:
- branches/eam_branches/ohana.20190329/src/libkapa
- Files:
-
- 3 edited
-
include/kapa.h (modified) (2 diffs)
-
src/KapaStyles.c (modified) (1 diff)
-
src/bDrawFuncs.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ohana.20190329/src/libkapa/include/kapa.h
r40783 r40926 45 45 KAPA_PLOT_BARS_OUTLINE = 4, 46 46 KAPA_PLOT_BARS_OUTFILL = 5, 47 KAPA_PLOT_INVALID_MAX = 6, 47 KAPA_PLOT_POLYGON = 6, 48 KAPA_PLOT_POLYFILL = 7, 49 KAPA_PLOT_INVALID_MAX = 8, 48 50 } KapaPlotStyle; 49 51 … … 320 322 void bDrawTriOpen (bDrawBuffer *buffer, double x1, double y1, double x2, double y2, double x3, double y3); 321 323 void bDrawTriFill (bDrawBuffer *buffer, double x1, double y1, double dx, double dy); 324 void bDrawPolyFill (bDrawBuffer *buffer, double *x, double *y, int Npoints); 322 325 323 326 void bDrawSmooth (bDrawBuffer *buffer, float sigma); -
branches/eam_branches/ohana.20190329/src/libkapa/src/KapaStyles.c
r40106 r40926 54 54 if (!strcasecmp (string, "outline")) return KAPA_PLOT_BARS_OUTLINE; 55 55 if (!strcasecmp (string, "outfill")) return KAPA_PLOT_BARS_OUTFILL; 56 57 if (!strcasecmp (string, "polygon")) return KAPA_PLOT_POLYGON; 58 if (!strcasecmp (string, "polyfill")) return KAPA_PLOT_POLYFILL; 56 59 57 60 if (strlen(string) > 2) { -
branches/eam_branches/ohana.20190329/src/libkapa/src/bDrawFuncs.c
r40730 r40926 173 173 void bDrawRectOpen (bDrawBuffer *buffer, double x1, double y1, double x2, double y2) { 174 174 175 int X1, Y1, X2, Y2;176 177 175 if (x1 > x2) SWAP (x1, x2); 178 176 if (y1 > y2) SWAP (y1, y2); 179 177 178 int X1 = MIN (MAX (ROUND (x1), 0), buffer[0].Nx - 1); 179 int X2 = MIN (MAX (ROUND (x2), 1), buffer[0].Nx - 1); 180 181 int Y1 = MIN (MAX (ROUND (y1), 0), buffer[0].Ny - 1); 182 int Y2 = MIN (MAX (ROUND (y2), 1), buffer[0].Ny - 1); 183 184 int dNs = -0.5*(buffer->bWeight - 1); 185 /* 0, 0, 0, -1, -1, -2, -2 */ 186 187 int dNe = +0.5*buffer->bWeight + 1; 188 /* 1, 1, 2, 2, 2, 3, 3 */ 189 190 for (int dN = dNs; dN < dNe; dN ++) { 191 // line on the bottom needs to run longer for the negative dN values 192 bDrawLineHorizontal (buffer, X1 + dN, X2 + 1 - dN, Y1 + dN); 193 194 // line on the top needs to run longer for the positive dN values 195 bDrawLineHorizontal (buffer, X1 + dN, X2 + 1 - dN, Y2 - dN); 196 197 // line on the left needs to run longer for the negative dN values 198 bDrawLineVertical (buffer, X1 + dN, Y1 + dN, Y2 - dN); 199 200 // line on the right needs to run longer for the positive dN values 201 bDrawLineVertical (buffer, X2 - dN, Y1 + dN, Y2 - dN); 202 } 203 return; 204 } 205 206 void bDrawRectFill (bDrawBuffer *buffer, double x1, double y1, double x2, double y2) { 207 208 int i; 209 int X1, Y1, X2, Y2; 210 211 if (x1 > x2) SWAP (x1, x2); 212 if (y1 > y2) SWAP (y1, y2); 213 180 214 X1 = MIN (MAX (ROUND (x1), 0), buffer[0].Nx - 1); 181 215 X2 = MIN (MAX (ROUND (x2), 1), buffer[0].Nx - 1); 182 216 183 217 Y1 = MIN (MAX (ROUND (y1), 0), buffer[0].Ny - 1); 184 Y2 = MIN (MAX (ROUND (y2), 1), buffer[0].Ny - 1);185 186 bDrawLineHorizontal (buffer, X1, X2 + 1, Y1);187 bDrawLineHorizontal (buffer, X1, X2 + 1, Y2);188 bDrawLineVertical (buffer, X1, Y1, Y2);189 bDrawLineVertical (buffer, X2, Y1, Y2);190 return;191 }192 193 void bDrawRectFill (bDrawBuffer *buffer, double x1, double y1, double x2, double y2) {194 195 int i;196 int X1, Y1, X2, Y2;197 198 if (x1 > x2) SWAP (x1, x2);199 if (y1 > y2) SWAP (y1, y2);200 201 X1 = MIN (MAX (ROUND (x1), 0), buffer[0].Nx - 1);202 X2 = MIN (MAX (ROUND (x2), 1), buffer[0].Nx - 1);203 204 Y1 = MIN (MAX (ROUND (y1), 0), buffer[0].Ny - 1);205 218 Y2 = MIN (MAX (ROUND (y2), 0), buffer[0].Ny - 1); 206 219 207 220 for (i = Y1; i < Y2; i++) { 221 // this should must be a line or width 1 or we duplicate pixels 208 222 bDrawLineHorizontal (buffer, X1, X2, i); 209 223 } … … 258 272 // use the Bresenham line drawing technique 259 273 // integer-only Bresenham line-draw version which is fast 274 // bresenham assumes x1 < x2 and (y2 - y1) < (x2 - x1) 260 275 void bDrawLineBresen (bDrawBuffer *buffer, int X1, int Y1, int X2, int Y2, int swapcoords) { 261 276 … … 405 420 } 406 421 422 # define BOT_LEFT 0 423 # define BOT_RGHT 1 424 # define TOP_LEFT 2 425 # define TOP_RGHT 3 426 427 // I should probably look up an appropriate recipe for this 428 // source code for XDrawPolyFill? 429 430 int GetNextSeqNumber (int seq, int Npoint, int Clockwise, int LeftSide); 431 int bDrawFillBetweenSegments (bDrawBuffer *buffer, int *x, int *y, int ystart); 432 433 void bDrawPolyFill (bDrawBuffer *buffer, double *x, double *y, int Npoints) { 434 435 // The coord list which is passed in (x,y) must be in order around the contour 436 for (int i = 0; i < Npoints; i++) { 437 fprintf (stderr, "%d : %f,%f\n", i, x[i], y[i]); 438 } 439 440 // First, find the lowest point and start at that sequence number 441 int iMin = 0; 442 double yMin = y[iMin]; 443 for (int i = 1; i < Npoints; i++) { 444 if (y[i] < yMin) { iMin = i; yMin = y[iMin]; } 445 } 446 447 // we generate two line segments and will fill between them 448 int xval[4]; 449 int yval[4]; 450 451 // the starting point is a vertex 452 xval[BOT_LEFT] = x[iMin]; yval[BOT_LEFT] = y[iMin]; 453 xval[BOT_RGHT] = x[iMin]; yval[BOT_RGHT] = y[iMin]; 454 455 // get iNext, iPrev assuming ClockWise, then test 456 int isCW = TRUE; 457 int iNextLeft = GetNextSeqNumber (iMin, Npoints, isCW, TRUE); // TRUE => left-side 458 int iNextRght = GetNextSeqNumber (iMin, Npoints, isCW, FALSE); 459 460 // if this is true, the points are not clockwise 461 if (x[iNextLeft] > x[iNextRght]) { 462 isCW = FALSE; 463 int tmp = iNextLeft; 464 iNextLeft = iNextRght; 465 iNextRght = tmp; 466 } 467 468 int iTL = iNextLeft; // sequence number of the top,left point 469 int iTR = iNextRght; // sequence number of the top,right point 470 xval[TOP_LEFT] = x[iTL]; yval[TOP_LEFT] = y[iTL]; 471 xval[TOP_RGHT] = x[iTR]; yval[TOP_RGHT] = y[iTR]; 472 473 // we need to track the starting row, start at the bottom 474 int ystart = yval[BOT_LEFT]; 475 476 while (TRUE) { 477 int isLeft = bDrawFillBetweenSegments (buffer, xval, yval, ystart); 478 479 // the last pair of segments in the sequence end at the same top point: 480 if (iTL == iTR) break; 481 482 // after one pass, if isLeft is true, then cycle the points on the left 483 // segment, otherwise cycle the right segment: 484 485 if (isLeft) { 486 iTL = GetNextSeqNumber (iTL, Npoints, isCW, TRUE); 487 xval[BOT_LEFT] = xval[TOP_LEFT]; yval[BOT_LEFT] = yval[TOP_LEFT]; 488 xval[TOP_LEFT] = x[iTL]; yval[TOP_LEFT] = y[iTL]; 489 ystart = yval[BOT_LEFT]; 490 } else { 491 iTR = GetNextSeqNumber (iTR, Npoints, isCW, FALSE); 492 xval[BOT_RGHT] = xval[TOP_RGHT]; yval[BOT_RGHT] = yval[TOP_RGHT]; 493 xval[TOP_RGHT] = x[iTR]; yval[TOP_RGHT] = y[iTR]; 494 ystart = yval[BOT_RGHT]; 495 } 496 } 497 return; 498 } 499 500 // we have two line segments defined by x[],y[]. 501 502 // [0],[1] is the left-side segment 503 // [2],[3] is the right-side segment 504 505 // Fill the region between the two segments until 506 // the lower of the two y coordinates y[1], y[3] 507 508 // return which of y[1] or y[3] was the ending row 509 510 int bDrawFillBetweenSegments_BresenBroken (bDrawBuffer *buffer, int *x, int *y, int ystart) { 511 512 fprintf (stderr, "%d, %d - %d, %d : %d, %d - %d, %d @ %d\n", 513 x[BOT_LEFT], y[BOT_LEFT], x[TOP_LEFT], y[TOP_LEFT], 514 x[BOT_RGHT], y[BOT_RGHT], x[TOP_RGHT], y[TOP_RGHT], ystart); 515 516 int dY_L = y[TOP_LEFT] - y[BOT_LEFT]; 517 int dX_L = x[TOP_LEFT] - x[BOT_LEFT]; 518 519 int dY_R = y[TOP_RGHT] - y[BOT_RGHT]; 520 int dX_R = x[TOP_RGHT] - x[BOT_RGHT]; 521 522 // I need to calculate x_L & x_R from the two line segements given ystart. 523 524 // I cannot assume X_L,X_R correspond to x[BOT_LEFT],x[BOT_RGHT]? 525 526 int X_L = (dY_L == 0) ? x[BOT_LEFT] : (ystart - y[BOT_LEFT]) * dX_L / dY_L + x[BOT_LEFT]; 527 int X_R = (dY_R == 0) ? x[BOT_RGHT] : (ystart - y[BOT_RGHT]) * dX_R / dY_R + x[BOT_RGHT]; 528 int e_L = 0; 529 int e_R = 0; 530 531 fprintf (stderr, "start: %d - %d @ %d\n", X_L, X_R, ystart); 532 533 // stop at whichever comes first 534 // XXX not sure if I need to use < or <= here: 535 // with <=, the value of Y after the loop will be one too high. 536 int Y; 537 for (Y = ystart; (Y < y[TOP_LEFT]) && (Y < y[TOP_RGHT]); Y++) { 538 539 // draw horizontal line from X_L to X_R at Y 540 bDrawLineHorizontal (buffer, X_L, X_R, Y); 541 542 e_L += dX_L; 543 int e_L2 = 2*e_L; 544 if (e_L2 > dY_L) { 545 X_L ++; 546 e_L -= dY_L; 547 } 548 if (e_L2 < -dY_L) { 549 X_L --; 550 e_L += dY_L; 551 } 552 553 e_R += dX_R; 554 int e_R2 = 2*e_R; 555 if (e_R2 > dY_R) { 556 X_R ++; 557 e_R -= dY_R; 558 } 559 if (e_R2 < -dY_R) { 560 X_R --; 561 e_R += dY_R; 562 } 563 } 564 565 fprintf (stderr, "end: %d - %d @ %d\n", X_L, X_R, Y); 566 567 if (Y == y[TOP_LEFT]) { 568 return TRUE; // TRUE is LEFT SIDE 569 } else { 570 return FALSE; 571 } 572 } 573 574 int bDrawFillBetweenSegments (bDrawBuffer *buffer, int *x, int *y, int ystart) { 575 576 int dY_L = y[TOP_LEFT] - y[BOT_LEFT]; 577 int dX_L = x[TOP_LEFT] - x[BOT_LEFT]; 578 579 int dY_R = y[TOP_RGHT] - y[BOT_RGHT]; 580 int dX_R = x[TOP_RGHT] - x[BOT_RGHT]; 581 582 double Slope_L = (dY_L == 0) ? NAN : dX_L / (double) dY_L; 583 double Slope_R = (dY_R == 0) ? NAN : dX_R / (double) dY_R; 584 585 // stop at whichever comes first 586 // XXX not sure if I need to use < or <= here: 587 // with <=, the value of Y after the loop will be one too high. 588 int Y; 589 for (Y = ystart; (Y < y[TOP_LEFT]) && (Y < y[TOP_RGHT]); Y++) { 590 591 // calculating X_L, X_R based on the slope and current y point 592 int X_L = (dY_L == 0) ? x[BOT_LEFT] : (Y - y[BOT_LEFT]) * Slope_L + x[BOT_LEFT]; 593 int X_R = (dY_R == 0) ? x[BOT_RGHT] : (Y - y[BOT_RGHT]) * Slope_R + x[BOT_RGHT]; 594 595 // draw horizontal line from X_L to X_R at Y 596 bDrawLineHorizontal (buffer, X_L, X_R, Y); 597 } 598 599 if (Y == y[TOP_LEFT]) { 600 return TRUE; // TRUE is LEFT SIDE 601 } else { 602 return FALSE; 603 } 604 } 605 606 int GetNextSeqNumber (int seq, int Npoints, int Clockwise, int LeftSide) { 607 608 int iNext; 609 610 if (Clockwise) { 611 if (LeftSide) { 612 // next point is next in sequence 613 iNext = (seq < Npoints - 1) ? seq + 1 : 0; 614 } else { 615 // next point is prev in sequence 616 iNext = (seq > 0) ? seq - 1 : Npoints - 1; 617 } 618 } else { 619 if (LeftSide) { 620 // next point is prev in sequence 621 iNext = (seq > 0) ? seq - 1 : Npoints - 1; 622 } else { 623 // next point is next in sequence 624 iNext = (seq < Npoints - 1) ? seq + 1 : 0; 625 } 626 } 627 return iNext; 628 } 629 407 630 void bDrawArc (bDrawBuffer *buffer, double Xc, double Yc, double Xr, double Yr, double Ts, double Te) { 408 631 … … 604 827 if (x == 0) { 605 828 if (decrementY) { 829 // this should must be a line or width 1 or we duplicate pixels 606 830 bDrawLineHorizontal (buffer, Xc , Xc + 1, Yc + y); 607 831 bDrawLineHorizontal (buffer, Xc , Xc + 1, Yc - y); … … 609 833 610 834 // center line 835 // this should must be a line or width 1 or we duplicate pixels 611 836 bDrawLineHorizontal (buffer, Xc - y, Xc + y + 1, Yc ); 612 837 return; … … 614 839 615 840 if (x == y) { 841 // this should must be a line or width 1 or we duplicate pixels 616 842 bDrawLineHorizontal (buffer, Xc - x, Xc + x + 1, Yc + y); 617 843 bDrawLineHorizontal (buffer, Xc - x, Xc + x + 1, Yc - y); … … 621 847 // only draw these two lines if we decrement y 622 848 if (decrementY) { 849 // this must be a line or width 1 or we duplicate pixels 623 850 bDrawLineHorizontal (buffer, Xc - x, Xc + x + 1, Yc + y); 624 851 bDrawLineHorizontal (buffer, Xc - x, Xc + x + 1, Yc - y); … … 626 853 627 854 // always draw these two lines: 855 // this must be a line or width 1 or we duplicate pixels 628 856 bDrawLineHorizontal (buffer, Xc - y, Xc + y + 1, Yc + x); 629 857 bDrawLineHorizontal (buffer, Xc - y, Xc + y + 1, Yc - x);
Note:
See TracChangeset
for help on using the changeset viewer.
