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 {