25#include <opencv2/imgproc.hpp>
30namespace func_sketch::plotter {
34 return cv::Scalar(color.
r, color.
g, color.
b);
38 const PlotConfig& config,
int left_margin,
const cv::MatSize& size) {
39 const int plot_width = size[1] - left_margin - config.
right_margin();
40 const int plot_height =
42 if (plot_width <= 0 || plot_height <= 0) {
46 const double x_ratio = (position.
x - range.
x_range().first) /
48 const double y_ratio = (position.
y - range.
y_range().first) /
52 const int x_in_pixel =
static_cast<int>(plot_width * x_ratio) + left_margin;
53 const int y_in_pixel =
54 static_cast<int>(plot_height * (1.0 - y_ratio)) + config.
top_margin();
56 return cv::Point(x_in_pixel, y_in_pixel);
74 const cv::MatSize& size,
int shift) {
75 const int plot_width = size[1] - left_margin - config.
right_margin();
76 const int plot_height =
78 if (plot_width <= 0 || plot_height <= 0) {
82 const double x_ratio = (position.
x - range.
x_range().first) /
84 const double y_ratio = (position.
y - range.
y_range().first) /
87 const double x_in_pixel_precise =
88 static_cast<double>(plot_width) * x_ratio +
89 static_cast<double>(left_margin);
90 const double y_in_pixel_precise =
91 static_cast<double>(plot_height) * (1.0 - y_ratio) +
94 const double coeff = std::ldexp(1.0, shift);
95 const int x_in_pixel_shifted =
static_cast<int>(x_in_pixel_precise * coeff);
96 const int y_in_pixel_shifted =
static_cast<int>(y_in_pixel_precise * coeff);
98 return cv::Point(x_in_pixel_shifted, y_in_pixel_shifted);
102 const cv::Scalar& color,
int line_width,
const PlotRange& range,
105 constexpr int shift = 10;
107 start_point, range, config, left_margin, image.size, shift);
109 end_point, range, config, left_margin, image.size, shift);
111 image, start_pixel, end_pixel, color, line_width, cv::LINE_AA, shift);
115 if (std::isinf(point.
x) && std::isinf(point.
y)) {
118 if (std::isinf(point.
x)) {
122 if (std::isinf(point.
y)) {
139 assert(point1.
x != point2.
x);
140 const Real slope = (point2.
y - point1.
y) / (point2.
x - point1.
x);
141 const Real y_value = point1.
y + slope * (x_value - point1.
x);
142 return Point{.x = x_value, .y = y_value};
155 assert(point1.
y != point2.
y);
156 const Real slope = (point2.
x - point1.
x) / (point2.
y - point1.
y);
157 const Real x_value = point1.
x + slope * (y_value - point1.
y);
158 return Point{.x = x_value, .y = y_value};
163 Point intersection = point_out_of_range;
165 if (intersection.
x < range.
x_range().first) {
167 point_in_range, intersection, range.
x_range().first);
168 }
else if (intersection.
x > range.
x_range().second) {
170 point_in_range, intersection, range.
x_range().second);
173 if (intersection.
y < range.
y_range().first) {
175 point_in_range, intersection, range.
y_range().first);
176 }
else if (intersection.
y > range.
y_range().second) {
178 point_in_range, intersection, range.
y_range().second);
Class of exceptions for invalid arguments.
Class of configurations of a plot.
PlotConfig & top_margin(int value)
Set the top margin of plots in pixels.
PlotConfig & right_margin(int value)
Set the right margin of plots in pixels.
PlotConfig & bottom_margin(int value)
Set the bottom margin of plots in pixels.
Class of a range of a plot.
auto y_range() const noexcept -> std::pair< double, double >
Get Y range.
auto x_range() const noexcept -> std::pair< double, double >
Get X range.
Definitions of common types.
double Real
Type of real numbers in this project.
Definition of exception classes.
Point compute_intersection_with_vertical_line(const Point &point1, const Point &point2, Real x_value)
Compute the intersection of a line segment with a vertical line.
Point compute_intersection_with_horizontal_line(const Point &point1, const Point &point2, Real y_value)
Compute the intersection of a line segment with a horizontal line.
cv::Point convert_position_with_shift(const Point &position, const PlotRange &range, const PlotConfig &config, int left_margin, const cv::MatSize &size, int shift)
Convert a position from plot coordinates to image coordinates with shift.
Declaration of functions for internal implementation of plotting.
Point compute_intersection_with_range(const Point &point_in_range, const Point &point_out_of_range, const PlotRange &range)
Compute the intersection of a line segment with the boundary of the plot range.
cv::Point convert_position(const Point &position, const PlotRange &range, const PlotConfig &config, int left_margin, const cv::MatSize &size)
Convert a position from plot coordinates to image coordinates.
cv::Scalar convert_color(const RGBColor &color)
Convert a color from RGBColor to cv::Scalar.
void write_line(Image &image, const Point &start_point, const Point &end_point, const cv::Scalar &color, int line_width, const PlotRange &range, const PlotConfig &config, int left_margin)
Write a line on an image.
bool try_clamp_infinity(Point &point, const PlotRange &range)
Try to clamp a point with infinity to the range.
std::uint8_t g
Green component.
std::uint8_t r
Red component.
std::uint8_t b
Blue component.