165 lines
6.4 KiB
C++
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
|