Mercurial > hg > svgui
comparison layer/SliceLayer.cpp @ 1400:decb7741d036
Different approach to x-coord calculation in slice layer - let's acknowledge that we really do have two different types of model, those whose "bins" are actually at a single value (frequency in the case of the spectrum) and those whose bins are just labels.
| author | Chris Cannam | 
|---|---|
| date | Thu, 15 Nov 2018 13:06:38 +0000 | 
| parents | ba1f0234efa7 | 
| children | 28075cc658c9 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 1399:ba1f0234efa7 | 1400:decb7741d036 | 
|---|---|
| 31 #include <QTextStream> | 31 #include <QTextStream> | 
| 32 | 32 | 
| 33 | 33 | 
| 34 SliceLayer::SliceLayer() : | 34 SliceLayer::SliceLayer() : | 
| 35 m_sliceableModel(0), | 35 m_sliceableModel(0), | 
| 36 m_binAlignment(BinsSpanScalePoints), | |
| 36 m_colourMap(int(ColourMapper::Ice)), | 37 m_colourMap(int(ColourMapper::Ice)), | 
| 37 m_colourInverted(false), | 38 m_colourInverted(false), | 
| 38 m_energyScale(dBScale), | 39 m_energyScale(dBScale), | 
| 39 m_samplingMode(SampleMean), | 40 m_samplingMode(SampleMean), | 
| 40 m_plotStyle(PlotLines), | 41 m_plotStyle(PlotLines), | 
| 118 { | 119 { | 
| 119 minbin = 0; | 120 minbin = 0; | 
| 120 maxbin = 0; | 121 maxbin = 0; | 
| 121 if (!m_sliceableModel) return ""; | 122 if (!m_sliceableModel) return ""; | 
| 122 | 123 | 
| 123 minbin = int(getBinForX(v, p.x())); | 124 if (m_binAlignment == BinsSpanScalePoints) { | 
| 124 maxbin = int(getBinForX(v, p.x() + 1)); | 125 minbin = int(getBinForX(v, p.x())); | 
| 126 maxbin = int(getBinForX(v, p.x() + 1)); | |
| 127 } else { | |
| 128 minbin = int(getBinForX(v, p.x()) + 0.5); | |
| 129 maxbin = int(getBinForX(v, p.x() + 1) + 0.5); | |
| 130 } | |
| 125 | 131 | 
| 126 int mh = m_sliceableModel->getHeight(); | 132 int mh = m_sliceableModel->getHeight(); | 
| 127 if (minbin >= mh) minbin = mh - 1; | 133 if (minbin >= mh) minbin = mh - 1; | 
| 128 if (maxbin >= mh) maxbin = mh - 1; | 134 if (maxbin >= mh) maxbin = mh - 1; | 
| 129 if (minbin < 0) minbin = 0; | 135 if (minbin < 0) minbin = 0; | 
| 447 // Must use actual zero-width pen, too slow otherwise | 453 // Must use actual zero-width pen, too slow otherwise | 
| 448 paint.setPen(QPen(getBaseQColor(), 0)); | 454 paint.setPen(QPen(getBaseQColor(), 0)); | 
| 449 } else { | 455 } else { | 
| 450 // Similarly, if there are very many bins here, we use a | 456 // Similarly, if there are very many bins here, we use a | 
| 451 // thinner pen | 457 // thinner pen | 
| 452 QPen pen(getBaseQColor(), 1); | 458 QPen pen; | 
| 453 if (mh < 10000) { | 459 if (mh < 10000) { | 
| 454 pen = PaintAssistant::scalePen(pen); | 460 pen = PaintAssistant::scalePen(QPen(getBaseQColor(), 0.8)); | 
| 461 } else { | |
| 462 pen = QPen(getBaseQColor(), 1); | |
| 455 } | 463 } | 
| 456 paint.setPen(pen); | 464 paint.setPen(pen); | 
| 457 } | 465 } | 
| 458 | 466 | 
| 459 int xorigin = getVerticalScaleWidth(v, true, paint) + 1; | 467 int xorigin = getVerticalScaleWidth(v, true, paint) + 1; | 
| 528 for (int bin = 0; bin < mh; ++bin) { | 536 for (int bin = 0; bin < mh; ++bin) { | 
| 529 m_values[bin] /= max; | 537 m_values[bin] /= max; | 
| 530 } | 538 } | 
| 531 } | 539 } | 
| 532 | 540 | 
| 533 double nx = getXForBin(v, bin0); | |
| 534 | |
| 535 ColourMapper mapper(m_colourMap, m_colourInverted, 0, 1); | 541 ColourMapper mapper(m_colourMap, m_colourInverted, 0, 1); | 
| 536 | 542 | 
| 537 double ytop = 0, ybottom = 0; | 543 double ytop = 0, ybottom = 0; | 
| 538 bool firstBinOfPixel = true; | 544 bool firstBinOfPixel = true; | 
| 539 | 545 | 
| 540 QColor prevColour = v->getBackground(); | 546 QColor prevColour = v->getBackground(); | 
| 541 double prevPx = 0; | |
| 542 double prevYtop = 0; | 547 double prevYtop = 0; | 
| 543 | 548 | 
| 549 double xleft = -1, xmiddle = -1, xright = -1; | |
| 550 double prevXmiddle = 0; | |
| 551 | |
| 544 for (int bin = 0; bin < mh; ++bin) { | 552 for (int bin = 0; bin < mh; ++bin) { | 
| 545 | 553 | 
| 546 double x = nx; | 554 if (m_binAlignment == BinsSpanScalePoints) { | 
| 547 nx = getXForBin(v, bin + bin0 + 1); | 555 if (xright >= 0) xleft = xright; // previous value of | 
| 556 else xleft = getXForBin(v, bin0 + bin); | |
| 557 xmiddle = getXForBin(v, bin0 + bin + 0.5); | |
| 558 xright = getXForBin(v, bin0 + bin + 1); | |
| 559 } else { | |
| 560 if (xright >= 0) xleft = xright; // previous value of | |
| 561 else xleft = getXForBin(v, bin0 + bin - 0.5); | |
| 562 xmiddle = getXForBin(v, bin0 + bin); | |
| 563 xright = getXForBin(v, bin0 + bin + 0.5); | |
| 564 } | |
| 548 | 565 | 
| 549 double value = m_values[bin]; | 566 double value = m_values[bin]; | 
| 550 double norm = 0.0; | 567 double norm = 0.0; | 
| 551 double y = getYForValue(v, value, norm); | 568 double y = getYForValue(v, value, norm); | 
| 552 | 569 | 
| 555 } | 572 } | 
| 556 if (y > ybottom || firstBinOfPixel) { | 573 if (y > ybottom || firstBinOfPixel) { | 
| 557 ybottom = y; | 574 ybottom = y; | 
| 558 } | 575 } | 
| 559 | 576 | 
| 560 if (int(nx) != int(x) || bin+1 == mh) { | 577 if (int(xright) != int(xleft) || bin+1 == mh) { | 
| 561 | 578 | 
| 562 if (m_plotStyle == PlotLines) { | 579 if (m_plotStyle == PlotLines) { | 
| 563 | 580 | 
| 564 double px = (x + nx) / 2; | |
| 565 | |
| 566 if (bin == 0) { | 581 if (bin == 0) { | 
| 567 path.moveTo(px, y); | 582 path.moveTo(xmiddle, y); | 
| 568 } else { | 583 } else { | 
| 569 if (ytop != ybottom) { | 584 if (ytop != ybottom) { | 
| 570 path.lineTo(px, ybottom); | 585 path.lineTo(xmiddle, ybottom); | 
| 571 path.lineTo(px, ytop); | 586 path.lineTo(xmiddle, ytop); | 
| 572 path.moveTo(px, ybottom); | 587 path.moveTo(xmiddle, ybottom); | 
| 573 } else { | 588 } else { | 
| 574 path.lineTo(px, ytop); | 589 path.lineTo(xmiddle, ytop); | 
| 575 } | 590 } | 
| 576 } | 591 } | 
| 577 | 592 | 
| 578 } else if (m_plotStyle == PlotSteps) { | 593 } else if (m_plotStyle == PlotSteps) { | 
| 579 | 594 | 
| 580 if (bin == 0) { | 595 if (bin == 0) { | 
| 581 path.moveTo(x, y); | 596 path.moveTo(xleft, y); | 
| 582 } else { | 597 } else { | 
| 583 path.lineTo(x, ytop); | 598 path.lineTo(xleft, ytop); | 
| 584 } | 599 } | 
| 585 path.lineTo(nx, ytop); | 600 path.lineTo(xright, ytop); | 
| 586 | 601 | 
| 587 } else if (m_plotStyle == PlotBlocks) { | 602 } else if (m_plotStyle == PlotBlocks) { | 
| 588 | 603 | 
| 589 // work in pixel coords here, as we don't want the | 604 // work in pixel coords here, as we don't want the | 
| 590 // vertical edges to be antialiased | 605 // vertical edges to be antialiased | 
| 591 | 606 | 
| 592 path.moveTo(QPoint(int(x), int(yorigin))); | 607 path.moveTo(QPoint(int(xleft), int(yorigin))); | 
| 593 path.lineTo(QPoint(int(x), int(ytop))); | 608 path.lineTo(QPoint(int(xleft), int(ytop))); | 
| 594 path.lineTo(QPoint(int(nx), int(ytop))); | 609 path.lineTo(QPoint(int(xright), int(ytop))); | 
| 595 path.lineTo(QPoint(int(nx), int(yorigin))); | 610 path.lineTo(QPoint(int(xright), int(yorigin))); | 
| 596 path.lineTo(QPoint(int(x), int(yorigin))); | 611 path.lineTo(QPoint(int(xleft), int(yorigin))); | 
| 597 | 612 | 
| 598 } else if (m_plotStyle == PlotFilledBlocks) { | 613 } else if (m_plotStyle == PlotFilledBlocks) { | 
| 599 | 614 | 
| 600 QColor c = mapper.map(norm); | 615 QColor c = mapper.map(norm); | 
| 601 paint.setPen(Qt::NoPen); | 616 paint.setPen(Qt::NoPen); | 
| 602 | 617 | 
| 603 // work in pixel coords here, as we don't want the | 618 // work in pixel coords here, as we don't want the | 
| 604 // vertical edges to be antialiased | 619 // vertical edges to be antialiased | 
| 605 | 620 | 
| 606 if (nx > x + 1) { | 621 if (xright > xleft + 1) { | 
| 607 | 622 | 
| 608 double px = (x + nx) / 2; | |
| 609 | |
| 610 QVector<QPoint> pp; | 623 QVector<QPoint> pp; | 
| 611 | 624 | 
| 612 if (bin > 0) { | 625 if (bin > 0) { | 
| 613 paint.setBrush(prevColour); | 626 paint.setBrush(prevColour); | 
| 614 pp.clear(); | 627 pp.clear(); | 
| 615 pp << QPoint(int(prevPx), int(yorigin)); | 628 pp << QPoint(int(prevXmiddle), int(yorigin)); | 
| 616 pp << QPoint(int(prevPx), int(prevYtop)); | 629 pp << QPoint(int(prevXmiddle), int(prevYtop)); | 
| 617 pp << QPoint(int((px + prevPx) / 2), | 630 pp << QPoint(int((xmiddle + prevXmiddle) / 2), | 
| 618 int((ytop + prevYtop) / 2)); | 631 int((ytop + prevYtop) / 2)); | 
| 619 pp << QPoint(int((px + prevPx) / 2), | 632 pp << QPoint(int((xmiddle + prevXmiddle) / 2), | 
| 620 int(yorigin)); | 633 int(yorigin)); | 
| 621 paint.drawConvexPolygon(QPolygon(pp)); | 634 paint.drawConvexPolygon(QPolygon(pp)); | 
| 622 | 635 | 
| 623 paint.setBrush(c); | 636 paint.setBrush(c); | 
| 624 pp.clear(); | 637 pp.clear(); | 
| 625 pp << QPoint(int((px + prevPx) / 2), | 638 pp << QPoint(int((xmiddle + prevXmiddle) / 2), | 
| 626 int(yorigin)); | 639 int(yorigin)); | 
| 627 pp << QPoint(int((px + prevPx) / 2), | 640 pp << QPoint(int((xmiddle + prevXmiddle) / 2), | 
| 628 int((ytop + prevYtop) / 2)); | 641 int((ytop + prevYtop) / 2)); | 
| 629 pp << QPoint(int(px), int(ytop)); | 642 pp << QPoint(int(xmiddle), int(ytop)); | 
| 630 pp << QPoint(int(px), int(yorigin)); | 643 pp << QPoint(int(xmiddle), int(yorigin)); | 
| 631 paint.drawConvexPolygon(QPolygon(pp)); | 644 paint.drawConvexPolygon(QPolygon(pp)); | 
| 632 } | 645 } | 
| 633 | 646 | 
| 634 prevPx = px; | |
| 635 prevColour = c; | 647 prevColour = c; | 
| 636 prevYtop = ytop; | 648 prevYtop = ytop; | 
| 637 | 649 | 
| 638 } else { | 650 } else { | 
| 639 | 651 | 
| 640 paint.fillRect(QRect(int(x), int(ytop), | 652 paint.fillRect(QRect(int(xleft), int(ytop), | 
| 641 int(nx) - int(x), | 653 int(xright) - int(xleft), | 
| 642 int(yorigin) - int(ytop)), | 654 int(yorigin) - int(ytop)), | 
| 643 c); | 655 c); | 
| 644 } | 656 } | 
| 657 | |
| 658 prevXmiddle = xmiddle; | |
| 645 } | 659 } | 
| 646 | 660 | 
| 647 firstBinOfPixel = true; | 661 firstBinOfPixel = true; | 
| 648 | 662 | 
| 649 } else { | 663 } else { | 
