#include "Afterglow_p.h" #include namespace YSG { Q_Ptr_cpp(Afterglow) PROP_P(Afterglow, FrequentAxis*, frequentAxis) PROP_P(Afterglow, Axis*, powerAxis) PROP_P(Afterglow, Range, frequentRange) PROP_P(Afterglow, Range, powerRange) PROP_G(Afterglow, int, frequentPointSize) PROP_G(Afterglow, int, powerPointSize) PROP_P(Afterglow, int, bufferSize) PROP_P(Afterglow, bool, interpolate) PROP_P(Afterglow, double, attenuationRate) PROP_P(Afterglow, int, initStrongValue) void Afterglow::set_frequentPointSize(int t) { AfterglowPrivate* pd = d(); Triple_Buffer_Lease lease = pd->mStateControl.wait_mark_use_role(State_Edit); AfterglowRenderState* sc = reinterpret_cast(pd->stateByIndex(lease.index)); RenderEditGuard _editGuard(pd, lease); sc->frequentPointSize = std::move(t); sc->bufferSize = sc->frequentPointSize * sc->powerPointSize; } void Afterglow::set_powerPointSize(int t) { AfterglowPrivate* pd = d(); Triple_Buffer_Lease lease = pd->mStateControl.wait_mark_use_role(State_Edit); AfterglowRenderState* sc = reinterpret_cast(pd->stateByIndex(lease.index)); RenderEditGuard _editGuard(pd, lease); sc->powerPointSize = std::move(t); sc->bufferSize = sc->frequentPointSize * sc->powerPointSize; } Afterglow::Builder::Builder(FrequentAxis* frequentAxis, Axis* powerAxis){ init(frequentAxis, powerAxis); } Afterglow* Afterglow::Builder::build() { auto ret = new Afterglow(); set(ret); return ret; } void Afterglow::giveData(const QVector &powerRangeData) { if(!ok()) return; AfterglowPrivate* pd = d(); Triple_Buffer_Lease stateLease = pd->mStateControl.wait_mark_use_role(State_Edit); AfterglowRenderState* sc = reinterpret_cast(pd->stateByIndex(stateLease.index)); int frequentPointSize = sc->frequentPointSize; pd->mStateControl.unmark_use(stateLease); if(powerRangeData.size() != frequentPointSize) { qDebug() << QString("pushData(const QVector &powerRangeData) error 数组大小不匹配 需要%1, 实际为%2") .arg(frequentPointSize).arg(powerRangeData.size()); return; } Triple_Buffer_Lease inputLease = pd->mInputControl.wait_mark_use_role(Input_Edit); RenderInputGuard _inputGuard(pd, inputLease); auto input = reinterpret_cast(pd->inputDataByIndex(inputLease.index)); input->mDataList.push_back(powerRangeData); } void AfterglowPrivate::pushData(const QVector& powerRangeData, const AfterglowRenderState* s) { if(curIndex == s->initStrongValue) { curIndex = 0; double oldRemain = 1.0 - s->attenuationRate; double cacheRemain = s->attenuationRate / (double)s->initStrongValue; for(int i = 0; i < cacheBufferSize; ++i) { mergedPowerData[i] = oldRemain*oldCachePowerData[i] + cacheRemain*cachedPowerData[i]; cachedPowerData[i] = 0; } std::memmove(oldCachePowerData.data(), mergedPowerData.data(), cacheBufferSize * sizeof(double)); cacheImageDirty = true; } QVector indexList(s->frequentPointSize); double rate = (double)s->powerPointSize/s->powerRange.size(); for(int i = 0; i < s->frequentPointSize; ++i) { int lineIndex = (int)((powerRangeData[i] - s->powerRange.lower) * rate); if (lineIndex < 0) lineIndex = 0; if (lineIndex > s->powerPointSize - 1) lineIndex = s->powerPointSize - 1; indexList[i] = lineIndex; } if(!s->interpolate) { for(int i = 0; i < s->frequentPointSize; ++i) { int index = indexList[i] * s->frequentPointSize + i; cachedPowerData[index]++; } } else { int lastLower = -1, lastUpper = -1; for(int i = 0; i < s->frequentPointSize; ++i) { int y = indexList[i]; cachedPowerData[y * s->frequentPointSize + i]++; if (y - lastUpper >= 2) { for (int curY = lastUpper + 1; curY < y; ++curY) { cachedPowerData[curY * s->frequentPointSize + i]++; } lastUpper = y; lastLower = lastLower + 1; continue; } if (lastLower - y >= 2) { for (int curY = y + 1; curY < lastLower; ++curY) { cachedPowerData[curY * s->frequentPointSize + i]++; } lastUpper = lastLower - 1; lastLower = y; continue; } lastUpper = y; lastLower = y; } } curIndex++; } }