Files
Renderive/Core/primitive/Curve.h
T
2026-08-02 03:43:39 +08:00

131 lines
5.3 KiB
C++

#pragma once
#include <cstdint>
#include <memory_resource>
#include <span>
#include <utility>
#include <vector>
#include "../architecture/Renderable.h"
#include "../Axis/Abs_Axis.h"
#include "../base/Color.h"
#include "../base/Geometry.h"
#include "../base/Memory.h"
#include "../base/Style.h"
#include "../architecture/Update_Completion.h"
#include "../plottable/Interpolation.h"
#include "../render/Canvas.h"
namespace renderive {
struct Curve_Private;
/// @brief 曲线采样模式。
/// @brief Sampling strategy used when converting a continuous sample sequence to screen polyline points.
enum class Line_Sampling_Strategy : std::uint8_t {
/// @brief 直接按输入数据采样。
/// @brief Use every input sample.
All_Samples,
/// @brief 按像素峰值桶降采样。
/// @brief Keep a local peak envelope per screen-pixel bucket to limit the number of drawn points.
Pixel_Min_Max_Envelope
};
/// @brief 曲线构造属性。
struct Curve_Prop {
std::weak_ptr<Abs_Axis> domain_axis{};
std::weak_ptr<Abs_Axis> value_axis{};
Range data_range{0.0, 1.0};
Pen pen = Pen{Color::white()};
Brush fill_brush = Brush{};
bool visible_range_only = true;
bool antialias = false;
Line_Interpolation_Mode interpolation_mode = Line_Interpolation_Mode::Linear_Value;
Line_Sampling_Strategy sample_mode = Line_Sampling_Strategy::All_Samples;
};
/// @brief 按坐标轴绘制折线或填充曲线的图元。
class LIB_DECL Curve : public Renderable {
public:
/// @brief 写入按 data_range 均匀分布的采样值。
void update_samples(std::span<const double> values);
/// @brief 移动写入按 data_range 均匀分布的采样值。
void update_samples(std::pmr::vector<double>&& values);
/// @brief 提交采样值并返回完成票据。
Update_Ticket submit_samples(std::span<const double> values);
/// @brief 移动提交采样值并返回完成票据。
Update_Ticket submit_samples(std::pmr::vector<double>&& values);
/// @brief 写入容器中的采样值。
template <typename Values>
void update_samples(const Values& values) {
update_samples(std::span<const double>(values.data(), values.size()));
}
/// @brief 用 writer 填充并写入采样值。
template <typename Writer>
void write_samples(std::size_t count, Writer&& writer) {
std::pmr::vector<double> values(memory_resource(Memory_Domain::Curve));
values.resize(count);
std::forward<Writer>(writer)(std::span<double>(values.data(), values.size()));
update_samples(std::move(values));
}
/// @brief 写入显式坐标点。
void update_points(std::span<const PointF> points);
/// @brief 移动写入显式坐标点。
void update_points(std::pmr::vector<PointF>&& points);
/// @brief 提交显式坐标点并返回完成票据。
Update_Ticket submit_points(std::span<const PointF> points);
/// @brief 移动提交显式坐标点并返回完成票据。
Update_Ticket submit_points(std::pmr::vector<PointF>&& points);
/// @brief 写入容器中的显式坐标点。
template <typename Points>
void update_points(const Points& points) {
update_points(std::span<const PointF>(points.data(), points.size()));
}
/// @brief 用 writer 填充并写入显式坐标点。
template <typename Writer>
void write_points(std::size_t count, Writer&& writer) {
std::pmr::vector<PointF> points(memory_resource(Memory_Domain::Curve));
points.resize(count);
std::forward<Writer>(writer)(std::span<PointF>(points.data(), points.size()));
update_points(std::move(points));
}
/// @brief 绑定 X 轴。
PROP(std::shared_ptr<Abs_Axis>, domain_axis)
/// @brief 绑定 Y 轴。
PROP(std::shared_ptr<Abs_Axis>, value_axis)
/// @brief 采样值映射到 X 轴的数据范围。
PROP(Range, data_range)
/// @brief 折线画笔。
PROP(Pen, pen)
/// @brief 填充到 Y 轴目标边界的画刷。
PROP(Brush, fill_brush)
/// @brief 是否只生成当前可见范围。
PROP(bool, visible_range_only)
/// @brief 是否启用抗锯齿。
PROP(bool, antialias)
/// @brief 折线插值模式。
PROP(Line_Interpolation_Mode, interpolation_mode)
/// @brief 曲线采样模式。
PROP(Line_Sampling_Strategy, sample_mode)
struct Builder;
/// @brief 创建曲线图元。
Curve();
private:
Curve_Private* d();
Render_Object_Owner create_render_data() override;
Render_Object_Owner create_render_state() override;
Render_Object_Owner create_input_data() override;
};
/// @brief 曲线构造器。
struct LIB_DECL Curve::Builder : Curve_Prop {
PROP_B(std::shared_ptr<Renderable>, parent)
PROP_B(std::shared_ptr<Abs_Axis>, domain_axis)
PROP_B(std::shared_ptr<Abs_Axis>, value_axis)
PROP_B(Range, data_range)
PROP_B(Pen, pen)
PROP_B(Brush, fill_brush)
PROP_B(bool, visible_range_only)
PROP_B(bool, antialias)
PROP_B(Line_Interpolation_Mode, interpolation_mode)
PROP_B(Line_Sampling_Strategy, sample_mode)
/// @brief 创建曲线构造器。
Builder(std::shared_ptr<Renderable> parent, std::shared_ptr<Abs_Axis> domain_axis, std::shared_ptr<Abs_Axis> value_axis);
/// @brief 构建并返回曲线对象。
std::shared_ptr<Curve> build();
std::shared_ptr<Renderable> parent{};
};
} // namespace renderive