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 { |