APPROXMVBB_EXPORT void samplePointsGrid(Matrix3Dyn & newPoints, const MatrixBase<Derived> & points, const unsigned int nPoints, OOBB & oobb) { if(nPoints >= points.cols() || nPoints < 2) { ApproxMVBB_ERRORMSG("Wrong arguements!") } newPoints.resize(3,nPoints); std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<unsigned int> dis(0, points.cols()-1); //total points = bottomPoints=gridSize^2 + topPoints=gridSize^2 unsigned int gridSize = std::max( static_cast<unsigned int>( std::sqrt( static_cast<double>(nPoints) / 2.0 )) , 1U ); // Set z-Axis to longest dimension //std::cout << oobb.m_minPoint.transpose() << std::endl; oobb.setZAxisLongest(); unsigned int halfSampleSize = gridSize*gridSize; std::vector< std::pair<unsigned int , PREC > > topPoints(halfSampleSize, std::pair<unsigned int,PREC>{} ); // grid of indices of the top points (indexed from 1 ) std::vector< std::pair<unsigned int , PREC > > bottomPoints(halfSampleSize, std::pair<unsigned int,PREC>{} ); // grid of indices of the bottom points (indexed from 1 ) using LongInt = long long int; MyMatrix<LongInt>::Array2 idx; // Normalized P //std::cout << oobb.extent() << std::endl; //std::cout << oobb.m_minPoint.transpose() << std::endl; Array2 dxdyInv = Array2(gridSize,gridSize) / oobb.extent().head<2>(); // in K Frame; Vector3 K_p; Matrix33 A_KI(oobb.m_q_KI.matrix().transpose()); // Register points in grid auto size = points.cols(); for(unsigned int i=0; i<size; ++i) { K_p = A_KI * points.col(i); // get x index in grid idx = ( (K_p - oobb.m_minPoint).head<2>().array() * dxdyInv ).template cast<LongInt>(); // map to grid idx(0) = std::max( std::min( LongInt(gridSize-1), idx(0)), 0LL ); idx(1) = std::max( std::min( LongInt(gridSize-1), idx(1)), 0LL ); //std::cout << idx.transpose() << std::endl; unsigned int pos = idx(0) + idx(1)*gridSize; // Register points in grid // if z axis of p is > topPoints[pos] -> set new top point at pos // if z axis of p is < bottom[pos] -> set new bottom point at pos if( topPoints[pos].first == 0) { topPoints[pos].first = bottomPoints[pos].first = i+1; topPoints[pos].second = bottomPoints[pos].second = K_p(2); } else { if( topPoints[pos].second < K_p(2) ) { topPoints[pos].first = i+1; topPoints[pos].second = K_p(2); } if( bottomPoints[pos].second > K_p(2) ) { bottomPoints[pos].first = i+1; bottomPoints[pos].second = K_p(2); } } } // Copy top and bottom points unsigned int k=0; // k does not overflow -> 2* halfSampleSize = 2*gridSize*gridSize <= nPoints; for(unsigned int i=0; i<halfSampleSize; ++i) { if( topPoints[i].first != 0 ) { // comment in if you want the points top points of the grid // Array3 a(i % gridSize,i/gridSize,oobb.m_maxPoint(2)-oobb.m_minPoint(2)); // a.head<2>()*=dxdyInv.inverse(); newPoints.col(k++) = points.col(topPoints[i].first-1); // A_KI.transpose()*(oobb.m_minPoint + a.matrix()).eval() ; if(topPoints[i].first != bottomPoints[i].first) { // comment in if you want the bottom points of the grid // Array3 a(i % gridSize,i/gridSize,0); // a.head<2>()*=dxdyInv.inverse(); newPoints.col(k++) = points.col(bottomPoints[i].first-1); // A_KI.transpose()*(oobb.m_minPoint + a.matrix()).eval() ; } } } // Add random points! while( k < nPoints) { newPoints.col(k++) = points.col( dis(gen) ); //= Vector3(0,0,0);// } }
void DrawWidget::drawChannelFilled(Channel *ch, QPainter &p, double leftTime, double currentTime, double zoomX, double viewBottom, double zoomY, int viewType) { ZoomLookup *z; if(viewType == DRAW_VIEW_SUMMARY) z = &ch->summaryZoomLookup; else z = &ch->normalZoomLookup; ChannelLocker channelLocker(ch); QColor current = ch->color; QColor invert(255 - current.red(), 255 - current.green(), 255 - current.blue()); p.setPen(current); int viewBottomOffset = toInt(viewBottom / zoomY); viewBottom = double(viewBottomOffset) * zoomY; // baseX is the no. of chunks a pixel must represent. double baseX = zoomX / ch->timePerChunk(); z->setZoomLevel(baseX); double currentChunk = ch->chunkFractionAtTime(currentTime); double leftFrameTime = currentChunk - ((currentTime - leftTime) / ch->timePerChunk()); //double leftFrameTime = leftTime / ch->timePerChunk(); double frameTime = leftFrameTime; //if(frameTime < 0.0) frameTime = 0.0; int n = 0; int baseElement = int(floor(frameTime / baseX)); if(baseElement < 0) { n -= baseElement; baseElement = 0; } int lastBaseElement = int(floor(double(ch->totalChunks()) / baseX)); int firstN = n; int lastN = firstN; //QPointArray pointArray(width()*2); //QPointArray topPoints(width()*2); /* Q3PointArray bottomPoints(width()*2); Q3PointArray evenMidPoints(width()*2); Q3PointArray oddMidPoints(width()*2); Q3PointArray evenMidPoints2(width()*2); Q3PointArray oddMidPoints2(width()*2);*/ QPolygon bottomPoints(width()*2); QPolygon evenMidPoints(width()*2); QPolygon oddMidPoints(width()*2); QPolygon evenMidPoints2(width()*2); QPolygon oddMidPoints2(width()*2); std::vector<QRect> noteRect(width()*2); std::vector<QRect> noteRect2(width()*2); std::vector<bool> isNoteRectEven(width()*2); //int pointIndex = 0; int pointIndex = 0; int evenMidPointIndex = 0; int oddMidPointIndex = 0; int evenMidPointIndex2 = 0; int oddMidPointIndex2 = 0; int rectIndex = 0; int rectIndex2 = 0; if (baseX > 1) { // More samples than pixels int theWidth = width(); //if(baseElement + theWidth > z->size()) z->setSize(baseElement + theWidth); if(lastBaseElement > z->size()) z->setSize(lastBaseElement); for(; n < theWidth && baseElement < lastBaseElement; n++, baseElement++) { myassert(baseElement >= 0); ZoomElement &ze = z->at(baseElement); //if(!z->hasValue(baseElement)) { if(!ze.isValid()) { if(!calcZoomElement(ch, ze, baseElement, baseX)) continue; } /*p.setPen(gdata->shading1Color()); p.moveTo(n, 0); p.lineTo(n, height() - 1 - toInt(ze.high / zoomY) + viewBottomOffset); p.setPen(gdata->shading2Color()); p.lineTo(n, height());*/ int y = height() - 1 - toInt(ze.high() / zoomY) + viewBottomOffset; int y2, y3; //if(ze.noteIndex >= 0) { if(ze.noteIndex() != -1 && ch->dataAtChunk(ze.midChunk())->getNoteIndex() != -1) { myassert(ze.noteIndex() >= 0); myassert(ze.noteIndex() < int(ch->noteData.size())); myassert(ch->isValidChunk(ze.midChunk())); AnalysisData *data = ch->dataAtChunk(ze.midChunk()); //double avgNote = ch->noteData[ze.noteIndex()].avgNote(); //printf("avgFreq = %f, ", ch->noteData[ze.noteIndex].avgFreq()); //printf("numPeriods = %f, ", ch->noteData[ze.noteIndex].numPeriods()); //printf("noteLength = %f\n", ch->noteData[ze.noteIndex].noteLength()); //y2 = height() - 1 - toInt((avgNote+0.5) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((avgNote-0.5) / zoomY) + viewBottomOffset; //y2 = height() - 1 - toInt((data->shortTermMean + data->shortTermDeviation) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((data->shortTermMean - data->shortTermDeviation) / zoomY) + viewBottomOffset; if(gdata->showMeanVarianceBars()) { //longTermMean bars y2 = height() - 1 - toInt((data->getLongTermMean() + data->getLongTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getLongTermMean() - data->getLongTermDeviation()) / zoomY) + viewBottomOffset; if(ze.noteIndex() % 2 == 0) { evenMidPoints.setPoint(evenMidPointIndex++, n, y2); evenMidPoints.setPoint(evenMidPointIndex++, n, y3); } else { oddMidPoints.setPoint(oddMidPointIndex++, n, y2); oddMidPoints.setPoint(oddMidPointIndex++, n, y3); } //shortTermMean bars y2 = height() - 1 - toInt((data->getShortTermMean() + data->getShortTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getShortTermMean() - data->getShortTermDeviation()) / zoomY) + viewBottomOffset; if(ze.noteIndex() % 2 == 0) { evenMidPoints2.setPoint(evenMidPointIndex2++, n, y2); evenMidPoints2.setPoint(evenMidPointIndex2++, n, y3); } else { oddMidPoints2.setPoint(oddMidPointIndex2++, n, y2); oddMidPoints2.setPoint(oddMidPointIndex2++, n, y3); } } //} else { // y2 = y3 = 0; } //topPoints.setPoint(pointIndex, n, 0); //topPoints.setPoint(pointIndex, n, y); bottomPoints.setPoint(pointIndex++, n, y); bottomPoints.setPoint(pointIndex++, n, height()); lastN = n; } //p.setPen(gdata->shading1Color()); //p.drawLineSegments(topPoints, 0, pointIndex/2); p.setPen(Qt::NoPen); p.setBrush(gdata->shading1Color()); p.drawRect(firstN, 0, lastN, height()); p.setPen(gdata->shading2Color()); //p.drawLineSegments(bottomPoints, 0, pointIndex/2); if(pointIndex > 1) p.drawLines(bottomPoints.constData(), pointIndex/2); if(gdata->showMeanVarianceBars()) { //shortTermMean bars p.setPen(Qt::green); //p.drawLineSegments(evenMidPoints2, 0, evenMidPointIndex2/2); if(evenMidPointIndex2 > 1) p.drawLines(evenMidPoints2.constData(), evenMidPointIndex2/2); p.setPen(Qt::yellow); //p.drawLineSegments(oddMidPoints2, 0, oddMidPointIndex2/2); if(oddMidPointIndex2 > 1) p.drawLines(oddMidPoints2.constData(), oddMidPointIndex2/2); //longTermMean bars p.setPen(Qt::yellow); //p.drawLineSegments(evenMidPoints, 0, evenMidPointIndex/2); if(evenMidPointIndex > 1) p.drawLines(evenMidPoints.constData(), evenMidPointIndex/2); p.setPen(Qt::green); //p.drawLineSegments(oddMidPoints, 0, oddMidPointIndex/2); if(oddMidPointIndex > 1) p.drawLines(oddMidPoints.constData(), oddMidPointIndex/2); } } else { // More pixels than samples float err = 0.0; float pitch = 0.0; int intChunk = (int) floor(frameTime); // Integer version of frame time if(intChunk < 0) intChunk = 0; double stepSize = 1.0 / baseX; // So we skip some pixels int x = 0, y, y2, y3; //double start = 0 - stepSize; double start = (double(intChunk) - frameTime) * stepSize; double stop = width() + (2 * stepSize); //int squareSize = (int(sqrt(stepSize)) / 2) * 2 + 1; //make it an odd number //int halfSquareSize = squareSize/2; //QPointArray topPoints(0); //QPointArray bottomPoints(0); //int pointIndex = 0; //topPoints.putPoints(pointIndex, 1, toInt(start), 0); //bottomPoints.putPoints(pointIndex, 1, toInt(start), height()); //pointIndex++; //topPoints.setPoint(pointIndex, toInt(start), 0); bottomPoints.setPoint(pointIndex++, toInt(start), height()); lastN = firstN = toInt(start); for (double n = start; n < stop && intChunk < (int)ch->totalChunks(); n += stepSize, intChunk++) { myassert(intChunk >= 0); //if (intChunk < 0) continue; // So we don't go off the beginning of the array AnalysisData *data = ch->dataAtChunk(intChunk); err = data->getCorrelation(); //if (err >= CERTAIN_THRESHOLD) { //float val = MIN(ch->dataAtChunk(intChunk)->volumeValue, 1.0); if(gdata->pitchContourMode() == 0) //p.setPen(QPen(colorBetween(colorGroup().background(), ch->color, err*2.0-1.0), lineWidth)); //p.setPen(QPen(colorBetween(gdata->backgroundColor(), ch->color, err*sqrt(data->rms)*10.0), lineWidth)); p.setPen(QPen(colorBetween(QColor(255, 255, 255), ch->color, err * dB2ViewVal(data->getLogRms())), lineWidth)); else p.setPen(QPen(ch->color, lineWidth)); x = toInt(n); lastN = x; //note = (data->isValid()) ? data->note : 0.0f; //note = (ch->isVisibleNote(data->noteIndex)) ? data->note : 0.0f; pitch = (ch->isVisibleChunk(data)) ? data->getPitch() : 0.0f; //if(ch->isVisibleChunk(data)) { if(data->getNoteIndex() >= 0) { isNoteRectEven[rectIndex] = (data->getNoteIndex() % 2) == 0; //note = data->note; //double avgNote = ch->noteData[data->noteIndex].avgNote(); //y2 = height() - 1 - toInt((avgNote+0.5) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((avgNote-0.5) / zoomY) + viewBottomOffset; //y2 = height() - 1 - toInt((data->shortTermMean + data->shortTermDeviation) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((data->shortTermMean - data->shortTermDeviation) / zoomY) + viewBottomOffset; if(gdata->showMeanVarianceBars()) { //longTermMean bars y2 = height() - 1 - toInt((data->getLongTermMean() + data->getLongTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getLongTermMean() - data->getLongTermDeviation()) / zoomY) + viewBottomOffset; noteRect[rectIndex].setLeft(x); noteRect[rectIndex].setRight(toInt(n+stepSize)); noteRect[rectIndex].setTop(y2); noteRect[rectIndex++].setBottom(y3); //shortTermMean bars y2 = height() - 1 - toInt((data->getShortTermMean() + data->getShortTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getShortTermMean() - data->getShortTermDeviation()) / zoomY) + viewBottomOffset; noteRect2[rectIndex2].setLeft(x); noteRect2[rectIndex2].setRight(toInt(n+stepSize)); noteRect2[rectIndex2].setTop(y2); noteRect2[rectIndex2++].setBottom(y3); } //} else { // note = 0.0f; } myassert(pitch >= 0.0 && pitch <= gdata->topPitch()); //note = bound(note, 0, gdata->topNote()); y = height() - 1 - toInt(pitch / zoomY) + viewBottomOffset; //y = height() - 1 - int((note / zoomY) - (viewBottom / zoomY)); //topPoints.putPoints(pointIndex, 1, x, y); //bottomPoints.putPoints(pointIndex, 1, x, y); //pointIndex++; //topPoints.setPoint(pointIndex, x, y); bottomPoints.setPoint(pointIndex++, x, y); } //topPoints.putPoints(pointIndex, 1, topPoints.point(pointIndex-1).x(), 0); //bottomPoints.putPoints(pointIndex, 1, bottomPoints.point(pointIndex-1).x(), height()); //pointIndex++; //topPoints.setPoint(pointIndex, topPoints.point(pointIndex-1).x(), 0); bottomPoints.setPoint(pointIndex, bottomPoints.point(pointIndex-1).x(), height()); pointIndex++; //p.setPen(gdata->shading1Color()); //p.setBrush(gdata->shading1Color()); //p.drawPolygon(topPoints); //p.setPen(gdata->shading2Color()); //p.setBrush(gdata->shading2Color()); //p.drawPolygon(bottomPoints); myassert(pointIndex <= width()*2); //p.setPen(gdata->shading1Color()); p.setPen(Qt::NoPen); p.setBrush(gdata->shading1Color()); //p.drawPolygon(topPoints, false, 0, pointIndex); p.drawRect(firstN, 0, lastN, height()); //p.setPen(gdata->shading2Color()); p.setBrush(gdata->shading2Color()); //p.drawPolygon(bottomPoints, false, 0, pointIndex); p.drawPolygon(bottomPoints.constData(), pointIndex, Qt::OddEvenFill); if(gdata->showMeanVarianceBars()) { //shortTermMean bars for(int j=0; j<rectIndex2; j++) { if(isNoteRectEven[j]) p.setBrush(Qt::green); else p.setBrush(Qt::yellow); p.drawRect(noteRect2[j]); } //longTermMean bars QColor seeThroughYellow = Qt::yellow; seeThroughYellow.setAlpha(255); QColor seeThroughGreen = Qt::green; seeThroughGreen.setAlpha(255); for(int j=0; j<rectIndex; j++) { //if(isNoteRectEven[j]) p.setBrush(QBrush(Qt::yellow, Qt::Dense3Pattern)); //else p.setBrush(QBrush(Qt::green, Qt::Dense3Pattern)); if(isNoteRectEven[j]) p.setBrush(seeThroughYellow); else p.setBrush(seeThroughGreen); p.drawRect(noteRect[j]); } } } }