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

117 lines
4.7 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));
AfterglowTempData* td = reinterpret_cast<AfterglowTempData*>(pd->mEditTempData);
SpinLockGuard _guard(&pd->mBufferLock);
RenderEditGuard _editGuard(pd);
sc->frequentPointSize = std::move(t);
sc->update_PointSize(sc->frequentPointSize, sc->powerPointSize);
}
void Afterglow::set_powerPointSize(int t) {
AfterglowPrivate* pd = d();
AfterglowRenderState* sc = reinterpret_cast<AfterglowRenderState*>(pd->state(State_Edit));
AfterglowTempData* td = reinterpret_cast<AfterglowTempData*>(pd->mEditTempData);
SpinLockGuard _guard(&pd->mBufferLock);
RenderEditGuard _editGuard(pd);
sc->powerPointSize = std::move(t);
sc->update_PointSize(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;
INIT_SET(Afterglow)
sc->pushData(powerRangeData);
}
void AfterglowRenderState::pushData(const QVector<double> &powerRangeData) {
if (powerRangeData.size() != frequentPointSize) {
qDebug() << QString("pushData(const QVector<double> &powerRangeData) error 数组大小不匹配 需要%1, 实际为%2")
.arg(frequentPointSize).arg(powerRangeData.size());
return;
}
if (curIndex == initStrongValue) {
curIndex = 0;
double oldRemain = 1.0 - attenuationRate;
double cacheRemain = attenuationRate / (double) initStrongValue; //这一次的概率 [0,1]
for (int i = 0; i < bufferSize; ++i) {
//std::cout << mCachedPowerData[i] << " " ;
mutexPowerData[i] = oldRemain*oldCachePowerData[i] + cacheRemain*cachedPowerData[i];
cachedPowerData[i] = 0;
}
//std::cout << std::endl;
{
auto d = reinterpret_cast<AfterglowPrivate*>(dPtr);
SpinLockGuard g(&d->dataLock);
std::memmove(oldCachePowerData.data(), mutexPowerData.data(), bufferSize * sizeof(double));
d->OK.storeRelease(true);
}
}
QVector<int> indexList(frequentPointSize);
double rate = (double)powerPointSize/powerRange.size();
for (int i = 0; i < frequentPointSize; ++i) {
int lineIndex = (int) ((powerRangeData[i] - powerRange.lower) * rate);
if (lineIndex < 0) lineIndex = 0;
if (lineIndex > powerPointSize - 1) lineIndex = powerPointSize - 1;
indexList[i] = lineIndex;
}
if (!interpolate) { //插值 填入没有的概率地方
for (int i = 0; i < frequentPointSize; ++i) {
int index = indexList[i] * frequentPointSize + i;
cachedPowerData[index]++;
}
} else {
int lastLower = -1, lastUpper = -1;
for (int i = 0; i < frequentPointSize; ++i) {
int y = indexList[i];
cachedPowerData[y * frequentPointSize + i]++;
if (y - lastUpper >= 2) {
for (int curY = lastUpper + 1; curY < y; ++curY) {
cachedPowerData[curY * frequentPointSize + i]++;
}
lastUpper = y;
lastLower = lastLower + 1;
continue;
}
if (lastLower - y >= 2) {
for (int curY = y + 1; curY < lastLower; ++curY) {
cachedPowerData[curY * frequentPointSize + i]++;
}
lastUpper = lastLower - 1;
lastLower = y;
continue;
}
lastUpper = y;
lastLower = y;
}
}
curIndex++;
}
}