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

125 lines
5.5 KiB
C++

#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<double> cachedPowerData;
QVector<double> oldCachePowerData;
QVector<double> 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<double> &powerRangeData);
};
struct AfterglowTempData : TempData {};
struct AfterglowPrivate : RenderData {
D_Ptr(Afterglow)
QImage image;
SpinLock dataLock;
QAtomicInteger<bool> 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<QRgb>& 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<QRgb*>(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 <typename That>
void Afterglow::BuilderT<That>::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<That*>(this)->frequentAxis = frequentAxis;
static_cast<That*>(this)->powerAxis = powerAxis;
}
template <typename That>
void Afterglow::BuilderT<That>::set(Afterglow* ret) {
ret->init(plot, layerName);
AfterglowPrivate* pd = ret->d();
AfterglowRenderState* sc = reinterpret_cast<AfterglowRenderState*>(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)
}
}