Files
Renderive/YSGraphic_Core/plottable/Afterglow.cpp
T
2026-07-23 11:39:46 +08:00

114 lines
4.6 KiB
C++

#include "Afterglow_p.h"
#include <cstring>
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();
AfterglowRenderState* sc = reinterpret_cast<AfterglowRenderState*>(pd->state(State_Edit));
SpinLockGuard _guard(&pd->mBufferLock);
RenderEditGuard _editGuard(pd);
sc->frequentPointSize = std::move(t);
sc->bufferSize = sc->frequentPointSize * sc->powerPointSize;
}
void Afterglow::set_powerPointSize(int t) {
AfterglowPrivate* pd = d();
AfterglowRenderState* sc = reinterpret_cast<AfterglowRenderState*>(pd->state(State_Edit));
SpinLockGuard _guard(&pd->mBufferLock);
RenderEditGuard _editGuard(pd);
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<double> &powerRangeData) {
if(!ok()) return;
AfterglowPrivate* pd = d();
SpinLockGuard _guard(&pd->mBufferLock);
AfterglowRenderState* sc = reinterpret_cast<AfterglowRenderState*>(pd->state(State_Edit));
if(powerRangeData.size() != sc->frequentPointSize) {
qDebug() << QString("pushData(const QVector<double> &powerRangeData) error 数组大小不匹配 需要%1, 实际为%2")
.arg(sc->frequentPointSize).arg(powerRangeData.size());
return;
}
auto input = reinterpret_cast<AfterglowInputData*>(pd->inputData(Input_Edit));
input->mDataList.push_back(powerRangeData);
pd->markInputDirty();
}
void AfterglowPrivate::pushData(const QVector<double>& 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) {
mutexPowerData[i] = oldRemain*oldCachePowerData[i] + cacheRemain*cachedPowerData[i];
cachedPowerData[i] = 0;
}
{
SpinLockGuard g(&dataLock);
std::memmove(oldCachePowerData.data(), mutexPowerData.data(), cacheBufferSize * sizeof(double));
OK.storeRelease(true);
}
}
QVector<int> 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++;
}
}