diff --git a/render_2D/render_2D/plottable/Afterglow.hpp b/render_2D/render_2D/plottable/Afterglow.hpp index 179589b..eb9d817 100644 --- a/render_2D/render_2D/plottable/Afterglow.hpp +++ b/render_2D/render_2D/plottable/Afterglow.hpp @@ -15,7 +15,6 @@ struct Afterglow : Def>>> { using Scene_Object = Impl; using Frequency_Object = Impl; using Power_Object = Impl; struct Prop : Prev_Prop { - Prop() { cache_enabled = true; } std::size_t frequency_point_size{}; /* 栅格频率列数;零值使用最新频谱尺寸。 */ std::size_t power_point_size{}; /* 栅格功率行数;零值使用默认尺寸。 */ Plot_Partition_Grid partition_grid{}; /* framebuffer 按列×行显式分块;任一维为零时禁用栅格任务。 */ diff --git a/render_2D/render_2D/plottable/Constellation_Diagram.hpp b/render_2D/render_2D/plottable/Constellation_Diagram.hpp index 61a3948..18530fb 100644 --- a/render_2D/render_2D/plottable/Constellation_Diagram.hpp +++ b/render_2D/render_2D/plottable/Constellation_Diagram.hpp @@ -20,9 +20,6 @@ struct Constellation_Diagram : Def; using Axis_Object = Impl; struct Prop : Prev_Prop { - Prop() { - cache_enabled = true; - } Plot_Partition_Count partition_count{1}; /* 接收点 Paint 子图的显式分块数;零值禁用接收点任务。 */ Plot_Duration_Milliseconds point_lifetime_ms{1000}; /* 接收点保留时间,单位为毫秒。 */ Constellation_Diagram_Type type{Constellation_Diagram_Type::psk8}; /* 理想 PSK 锚点数量。 */ diff --git a/render_2D/render_2D/plottable/Frequency_Trace.hpp b/render_2D/render_2D/plottable/Frequency_Trace.hpp index db294af..6575b05 100644 --- a/render_2D/render_2D/plottable/Frequency_Trace.hpp +++ b/render_2D/render_2D/plottable/Frequency_Trace.hpp @@ -19,7 +19,6 @@ struct Frequency_Trace : Def; using Value_Object = Impl; struct Prop : Prev_Prop { - Prop() { cache_enabled = true; } Plot_Partition_Count partition_count{1}; /* 曲线 Prepare/Paint 子图的显式分块数;零值禁用曲线分块任务。 */ Pen pen{Color::yellow()}; /* 频率轨迹折线样式。 */ bool operator==(const Prop&) const; diff --git a/render_2D/render_2D/plottable/Spectrum.hpp b/render_2D/render_2D/plottable/Spectrum.hpp index 19ceee9..dd08d3b 100644 --- a/render_2D/render_2D/plottable/Spectrum.hpp +++ b/render_2D/render_2D/plottable/Spectrum.hpp @@ -24,7 +24,6 @@ struct Spectrum : Def; using Power_Object = Impl; struct Prop : Prev_Prop { - Prop() { cache_enabled = true; } Spectrum_Frequency center_frequency{50.0}; /* 中心频率标记位置,单位为 Hz。 */ Plot_Partition_Count partition_count{1}; /* 曲线 Prepare/Paint 子图的显式分块数;零值禁用曲线分块任务。 */ bool max_hold_visible{}; /* 是否绘制逐点历史最大值曲线。 */ diff --git a/render_2D/render_2D/plottable/Sweep_Spectrum.hpp b/render_2D/render_2D/plottable/Sweep_Spectrum.hpp index 953851d..75b859a 100644 --- a/render_2D/render_2D/plottable/Sweep_Spectrum.hpp +++ b/render_2D/render_2D/plottable/Sweep_Spectrum.hpp @@ -25,7 +25,6 @@ struct Sweep_Spectrum : Def; using Power_Object = Impl; struct Prop : Prev_Prop { - Prop() { cache_enabled = true; } std::size_t bins_per_block{}; /* 每个扫频块期望的功率点数;零值接受首块尺寸。 */ std::size_t block_count{1}; /* 一个完整扫频周期包含的块数;零值按 1 处理。 */ Plot_Partition_Count partition_count{1}; /* 曲线 Prepare/Paint 子图的显式分块数;零值禁用曲线分块任务。 */ diff --git a/render_2D/render_2D/plottable/Waterfall.hpp b/render_2D/render_2D/plottable/Waterfall.hpp index d99dd5f..cefbf55 100644 --- a/render_2D/render_2D/plottable/Waterfall.hpp +++ b/render_2D/render_2D/plottable/Waterfall.hpp @@ -22,7 +22,6 @@ struct Waterfall : Def; using Time_Object = Impl; struct Prop : Prev_Prop { - Prop() { cache_enabled = true; } bool tooltip_enabled{true}; /* 是否响应指针位置显示提示。 */ Font tooltip_font{}; /* 提示文字字体。 */ Pen tooltip_text_pen{Color::white()}; /* 提示文字样式。 */ @@ -32,7 +31,7 @@ struct Waterfall : Def(layout.width); - const double right = target.x + target.width * partition.last_x / - static_cast(layout.width); - const double top = target.y + target.height * partition.first_y / - static_cast(layout.height); - const double bottom = target.y + target.height * partition.last_y / - static_cast(layout.height); - constexpr double overlap{1.0}; - return {left - overlap, top - overlap, - right - left + overlap * 2.0, - bottom - top + overlap * 2.0}; + const auto pixel_boundary = [](double origin, double extent, + int source_boundary, int source_extent, + bool last) { + const double projected = origin + extent * source_boundary / + static_cast(source_extent); + return last ? std::ceil(projected) : std::floor(projected); + }; + const double left = pixel_boundary(target.x, target.width, + partition.first_x, layout.width, false); + const double right = pixel_boundary(target.x, target.width, + partition.last_x, layout.width, partition.last_x == layout.width); + const double top = pixel_boundary(target.y, target.height, + partition.first_y, layout.height, false); + const double bottom = pixel_boundary(target.y, target.height, + partition.last_y, layout.height, partition.last_y == layout.height); + return {left, top, right - left, bottom - top}; } void paint_raster(Painter& painter, const Raster_Layout& layout, std::span pixels, Image_Interpolation_Mode interpolation) { if (layout.valid() && pixels.size() == static_cast(layout.width) * static_cast(layout.height)) painter.heatmap(layout.target, layout.width, layout.height, pixels, interpolation); diff --git a/render_2D/render_2D/plottable/common/Raster_Plot.hpp b/render_2D/render_2D/plottable/common/Raster_Plot.hpp index ae12de4..fa07bc0 100644 --- a/render_2D/render_2D/plottable/common/Raster_Plot.hpp +++ b/render_2D/render_2D/plottable/common/Raster_Plot.hpp @@ -41,7 +41,7 @@ struct Raster_Partition { Plot_Partition_Grid grid); [[nodiscard]] std::pair raster_coordinates( const Raster_Layout& layout, int x, int y) noexcept; -/* 将目标矩形按列×行网格切成 framebuffer 视图;相邻 tile 保留一像素重叠。 */ +/* 将目标矩形切成互斥的整数 framebuffer 视图;每个目标像素只有一个写入者。 */ [[nodiscard]] Rect_F raster_paint_region(const Raster_Layout& layout, Plot_Partition_Count partition_index, Plot_Partition_Grid grid); diff --git a/render_2D/tests/Partition_Configuration_Test.cpp b/render_2D/tests/Partition_Configuration_Test.cpp index be5ddb9..7bf7da0 100644 --- a/render_2D/tests/Partition_Configuration_Test.cpp +++ b/render_2D/tests/Partition_Configuration_Test.cpp @@ -1,5 +1,8 @@ +#include #include +#include #include +#include #include #include #include @@ -26,6 +29,9 @@ TEST(partition_configuration, using Power = Impl; using Time = Impl; using Spectrum_Object = Impl; + using Trace_Object = Impl; + using Sweep_Object = Impl; + using Afterglow_Object = Impl; using Constellation_Object = Impl; using Waterfall_Object = Impl; @@ -35,6 +41,10 @@ TEST(partition_configuration, auto time = build_object