Files
Renderive/YSGraphic_Core/plottable/Afterglow.cpp
T
2026-07-24 10:54:44 +08:00

165 lines
6.4 KiB
C++

#include <cstring>
#include "Afterglow_p.h"
namespace YSG {
using Afterglow_Binding = Renderable_Binding<Afterglow, Afterglow_Private, Afterglow_Render_State, Afterglow_Input_Data>;
Afterglow::Afterglow() {
Afterglow_Binding::init(this, "Afterglow");
}
Afterglow_Private* Afterglow::d() {
return Afterglow_Binding::d(this);
}
Render_Data* Afterglow::create_render_data() {
return Afterglow_Binding::create_render_data();
}
Render_State* Afterglow::create_render_state() {
return Afterglow_Binding::create_render_state();
}
Input_Data* Afterglow::create_input_data() {
return Afterglow_Binding::create_input_data();
}
Frequent_Axis* Afterglow::frequent_axis(SRC src) {
return d()->state_value(&Afterglow_Render_State::frequent_axis, src);
}
void Afterglow::set_frequent_axis(Frequent_Axis* value) {
d()->set_state_value(&Afterglow_Render_State::frequent_axis, value);
}
Axis* Afterglow::power_axis(SRC src) {
return d()->state_value(&Afterglow_Render_State::power_axis, src);
}
void Afterglow::set_power_axis(Axis* value) {
d()->set_state_value(&Afterglow_Render_State::power_axis, value);
}
Range Afterglow::frequent_range(SRC src) {
return d()->state_value(&Afterglow_Render_State::frequent_range, src);
}
void Afterglow::set_frequent_range(Range value) {
d()->set_state_value(&Afterglow_Render_State::frequent_range, std::move(value));
}
Range Afterglow::power_range(SRC src) {
return d()->state_value(&Afterglow_Render_State::power_range, src);
}
void Afterglow::set_power_range(Range value) {
d()->set_state_value(&Afterglow_Render_State::power_range, std::move(value));
}
int Afterglow::frequent_point_size(SRC src) {
return d()->state_value(&Afterglow_Render_State::frequent_point_size, src);
}
int Afterglow::power_point_size(SRC src) {
return d()->state_value(&Afterglow_Render_State::power_point_size, src);
}
int Afterglow::buffer_size(SRC src) {
return d()->state_value(&Afterglow_Render_State::buffer_size, src);
}
void Afterglow::set_buffer_size(int value) {
d()->set_state_value(&Afterglow_Render_State::buffer_size, value);
}
bool Afterglow::interpolate(SRC src) {
return d()->state_value(&Afterglow_Render_State::interpolate, src);
}
void Afterglow::set_interpolate(bool value) {
d()->set_state_value(&Afterglow_Render_State::interpolate, value);
}
double Afterglow::attenuation_rate(SRC src) {
return d()->state_value(&Afterglow_Render_State::attenuation_rate, src);
}
void Afterglow::set_attenuation_rate(double value) {
d()->set_state_value(&Afterglow_Render_State::attenuation_rate, value);
}
int Afterglow::init_strong_value(SRC src) {
return d()->state_value(&Afterglow_Render_State::init_strong_value, src);
}
void Afterglow::set_init_strong_value(int value) {
d()->set_state_value(&Afterglow_Render_State::init_strong_value, value);
}
void Afterglow::set_frequent_point_size(int t) {
Afterglow_Private* pd = d();
Render_Edit_Lease<Afterglow_Private, Afterglow_Render_State> edit(pd);
edit->frequent_point_size = std::move(t);
edit->buffer_size = edit->frequent_point_size * edit->power_point_size;
}
void Afterglow::set_power_point_size(int t) {
Afterglow_Private* pd = d();
Render_Edit_Lease<Afterglow_Private, Afterglow_Render_State> edit(pd);
edit->power_point_size = std::move(t);
edit->buffer_size = edit->frequent_point_size * edit->power_point_size;
}
Afterglow::Builder::Builder(Frequent_Axis* frequent_axis, Axis* power_axis) {
init(frequent_axis, power_axis);
}
Afterglow* Afterglow::Builder::build() {
auto ret = new Afterglow();
set(ret);
return ret;
}
void Afterglow::give_data(const QVector<double>& powerRangeData) {
if (!ok())
return;
Afterglow_Private* pd = d();
Render_State_Lease<Afterglow_Private, Afterglow_Render_State> state(pd);
int frequent_point_size = state->frequent_point_size;
if (powerRangeData.size() != frequent_point_size) {
qDebug() << QString("push_data(const QVector<double> &powerRangeData) error 数组大小不匹配 需要%1, 实际为%2")
.arg(frequent_point_size)
.arg(powerRangeData.size());
return;
}
Render_Input_Lease<Afterglow_Private, Afterglow_Input_Data> input(pd);
input->mDataList.push_back(powerRangeData);
}
void Afterglow_Private::push_data(const QVector<double>& powerRangeData, const Afterglow_Render_State* s) {
if (curIndex == s->init_strong_value) {
curIndex = 0;
double oldRemain = 1.0 - s->attenuation_rate;
double cacheRemain = s->attenuation_rate / (double)s->init_strong_value;
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<int> indexList(s->frequent_point_size);
double rate = (double)s->power_point_size / s->power_range.size();
for (int i = 0; i < s->frequent_point_size; ++i) {
int lineIndex = (int)((powerRangeData[i] - s->power_range.lower) * rate);
if (lineIndex < 0)
lineIndex = 0;
if (lineIndex > s->power_point_size - 1)
lineIndex = s->power_point_size - 1;
indexList[i] = lineIndex;
}
if (!s->interpolate) {
for (int i = 0; i < s->frequent_point_size; ++i) {
int index = indexList[i] * s->frequent_point_size + i;
cachedPowerData[index]++;
}
}
else {
int lastLower = -1, lastUpper = -1;
for (int i = 0; i < s->frequent_point_size; ++i) {
int y = indexList[i];
cachedPowerData[y * s->frequent_point_size + i]++;
if (y - lastUpper >= 2) {
for (int curY = lastUpper + 1; curY < y; ++curY) {
cachedPowerData[curY * s->frequent_point_size + i]++;
}
lastUpper = y;
lastLower = lastLower + 1;
continue;
}
if (lastLower - y >= 2) {
for (int curY = y + 1; curY < lastLower; ++curY) {
cachedPowerData[curY * s->frequent_point_size + i]++;
}
lastUpper = lastLower - 1;
lastLower = y;
continue;
}
lastUpper = y;
lastLower = y;
}
}
curIndex++;
}
} // namespace YSG