#include #include "Afterglow_p.h" namespace YSG { using Afterglow_Binding = Renderable_Binding; 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 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 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& powerRangeData) { if (!ok()) return; Afterglow_Private* pd = d(); Render_State_Lease state(pd); int frequent_point_size = state->frequent_point_size; if (powerRangeData.size() != frequent_point_size) { qDebug() << QString("push_data(const QVector &powerRangeData) error 数组大小不匹配 需要%1, 实际为%2") .arg(frequent_point_size) .arg(powerRangeData.size()); return; } Render_Input_Lease input(pd); input->mDataList.push_back(powerRangeData); } void Afterglow_Private::push_data(const QVector& 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 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