#pragma once #include "Afterglow.h" #include "../Axis/FrequentAxis.h" #include "../Axis/FrequentAxis_p.h" #include "../base/PerformanceShower_p.h" #include "../base/Plot_p.h" #include "../base/Global.h" namespace YSG { struct AfterglowRenderState : RenderState, Afterglow_Prop { int curIndex = 0; QVector cachedPowerData; QVector oldCachePowerData; QVector mutexPowerData; // 等比数列求和公式 a1*(1-q^n)/(1-q) n->inf 时为 a1/(1-q) [[nodiscard]] int strengthValue() const { return (int) ((double) initStrongValue / (1.0 - attenuationRate)); } void update_PointSize(int frequentPointSize, int powerPointSize) { this->frequentPointSize = frequentPointSize; this->powerPointSize = powerPointSize; bufferSize = frequentPointSize * powerPointSize; cachedPowerData.resize(bufferSize); cachedPowerData.fill(0); oldCachePowerData.resize(bufferSize); oldCachePowerData.fill(0); mutexPowerData.resize(bufferSize); mutexPowerData.fill(0); curIndex = 0; } void pushData(const QVector &powerRangeData); }; struct AfterglowTempData : TempData {}; struct AfterglowPrivate : RenderData { D_Ptr(Afterglow) QImage image; SpinLock dataLock; QAtomicInteger OK = false; void draw(QPainter* painter) override { AfterglowRenderState* s = renderState(); PerformanceShower *shower = q()->mPlot->d->mShower; if(shower) { shower->mInfoMap["colCount, rowCount"] = PerformanceLine(QString("colCount:%1, rowCount:%2") .arg(s->frequentPointSize).arg( s->powerPointSize)); } AbsAxis *hAxis = s->frequentAxis, *vAxis = s->powerAxis, *valueAxis = s->powerAxis; Range &hRange = s->frequentRange, &vRange = s->powerRange; int colCount = s->frequentPointSize, rowCount = s->powerPointSize; if(image.width() != colCount || image.height() != rowCount) { image = QImage(colCount, rowCount, QImage::Format_ARGB32_Premultiplied); image.fill(0); } { if(OK.loadAcquire() == true) { QVector& mColorMap = Global::instance()->mColorMap; Cacl c("Afterglow setTime:%1 avg %2", q()->mPlot->d->mShower); //double rate = 1.0/s->strengthValue() * 256.0; for (int row = 0; row < rowCount; ++row) { QRgb* scanLine = reinterpret_cast(image.scanLine(row)); double* list = s->oldCachePowerData.data() + row*colCount; for (int col = 0; col < colCount; ++col) { int colorOffset = (int)(list[col] * 255); if (colorOffset < 0 || colorOffset > 255) { qDebug() << "colorOffset:" << colorOffset << " value: " << list[col] << " startCoord:" << valueAxis->startCoord() << " endCoord:" << valueAxis->endCoord(); } //std::cout << " " << list[col]; scanLine[col] = mColorMap.at(colorOffset); } //std::cout << std::endl; } OK.storeRelease(false); } } double x = hAxis->coordToPixel(hRange.lower, SRC::Render); double y = vAxis->coordToPixel(vRange.lower, SRC::Render); double w = hAxis->coordToPixel(hRange.upper, SRC::Render) - x; double h = vAxis->coordToPixel(vRange.upper, SRC::Render) - y; Range &&hAxisRange = hAxis->coordRange(), &&vAxisRange = vAxis->coordRange(); double hr = ((hAxisRange.lower < hAxisRange.upper) ^ (hRange.lower < hRange.upper)) ? -1 : 1; double vr = ((vAxisRange.lower < vAxisRange.upper) ^ (vRange.lower < vRange.upper)) ? -1 : 1; painter->save(); painter->scale(hr, vr); painter->drawImage(QRectF(hr * x, vr * y, hr * w, vr * h), image); painter->restore(); } void prepareData() override { SpinLockGuard guard(&mBufferLock); syncStatePipeline(); } }; template void Afterglow::BuilderT::init(FrequentAxis* frequentAxis, Axis* powerAxis) { ASSERT(frequentAxis->mPlot != nullptr, "Afterglow build error! frequentAxis->mPlot == nullptr"); ASSERT(frequentAxis->mPlot == powerAxis->mPlot, "Afterglow build error! frequentAxis->mPlot != powerAxis->mPlot"); plot = frequentAxis->mPlot; static_cast(this)->frequentAxis = frequentAxis; static_cast(this)->powerAxis = powerAxis; } template void Afterglow::BuilderT::set(Afterglow* ret) { ret->init(plot, layerName); AfterglowPrivate* pd = ret->d(); AfterglowRenderState* sc = reinterpret_cast(pd->state(State_Edit)); PROP_RT(FrequentAxis*, frequentAxis) PROP_RT(Axis*, powerAxis) PROP_RT(Range, frequentRange) PROP_RT(Range, powerRange) PROP_RT(int, frequentPointSize) PROP_RT(int, powerPointSize) PROP_RT(int, bufferSize) PROP_RT(bool, interpolate) PROP_RT(double, attenuationRate) PROP_RT(int, initStrongValue) } }