图书馆能画粗线吗?
can the CImg library draw thick lines
本文关键字:图书馆 更新时间:2023-10-16
我一直在使用CImg库,并且对它的易于集成和使用感到满意。但是,我现在想要绘制粗线(即超过一个像素的粗线)。从draw_line
函数的API文档(此处)中不清楚如何做到这一点。这个函数的第二个版本(就在文档中第一个版本的下面)甚至接受纹理作为输入,但同样没有宽度。这样一个全面的库没有这个特性似乎很奇怪。也许应该用某种变换来完成?我知道我可以使用多边形(即,我将使用线的法线来计算多边形的角的矩形),但我担心这会显着慢。
显然,这是不可能的'开箱即用',但创建自己的例程,多次调用CImg的'draw_line()'例程,一个或两个像素的移动应该给你你想要的结果,没有太多的工作。
此函数可将粗线绘制为多边形。
void draw_line(cimg_library::CImg<uint8_t>& image,
const int x1, const int y1,
const int x2, const int y2,
const uint8_t* const color,
const unsigned int line_width)
{
if (x1 == x2 && y1 == y2) {
return;
}
// Convert line (p1, p2) to polygon (pa, pb, pc, pd)
const double x_diff = std::abs(x1 - x2);
const double y_diff = std::abs(y1 - y2);
const double w_diff = line_width / 2.0;
// Triangle between pa and p1: x_adj^2 + y_adj^2 = w_diff^2
// Triangle between p1 and p2: x_diff^2 + y_diff^2 = length^2
// Similar triangles: y_adj / x_diff = x_adj / y_diff = w_diff / length
// -> y_adj / x_diff = w_diff / sqrt(x_diff^2 + y_diff^2)
const int x_adj = y_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));
const int y_adj = x_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));
// Points are listed in clockwise order, starting from top-left
cimg_library::CImg<int> points(4, 2);
points(0, 0) = x1 - x_adj;
points(0, 1) = y1 + y_adj;
points(1, 0) = x1 + x_adj;
points(1, 1) = y1 - y_adj;
points(2, 0) = x2 + x_adj;
points(2, 1) = y2 - y_adj;
points(3, 0) = x2 - x_adj;
points(3, 1) = y2 + y_adj;
image.draw_polygon(points, color);
}
line_width
20和3种颜色的基准测试。第一次使用此函数,第二次使用image.draw_line()
绘制单个1px宽的线。
- 1000,1000 ~ 2000,2000: 216µs/123µs
- 2000、2000 ~ 8000、4000:588µs/151µs
- 3000、1000至3020、1000:21µs/5µs
基本上这段代码与@vll的回答相同,但也处理(x1-x2)/(y1-y2) < 0
时的情况(我删除了abs
函数)。
void draw_line(cimg_library::CImg<uint8_t>& image,
const int x1, const int y1,
const int x2, const int y2,
const uint8_t* const color,
const uint8_t line_width,
const double opacity=1.0)
{
if (x1 == x2 && y1 == y2) {
return;
}
// Convert line (p1, p2) to polygon (pa, pb, pc, pd)
const double x_diff = (x1 - x2);
const double y_diff = (y1 - y2);
const double w_diff = line_width / 2.0;
// Triangle between pa and p1: x_adj^2 + y_adj^2 = w_diff^2
// Triangle between p1 and p2: x_diff^2 + y_diff^2 = length^2
// Similar triangles: y_adj / x_diff = x_adj / y_diff = w_diff / length
// -> y_adj / x_diff = w_diff / sqrt(x_diff^2 + y_diff^2)
const int x_adj = y_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));
const int y_adj = x_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));
// Points are listed in clockwise order, starting from top-left
cimg_library::CImg<int> points(4, 2);
points(0, 0) = x1 - x_adj;
points(0, 1) = y1 + y_adj;
points(1, 0) = x1 + x_adj;
points(1, 1) = y1 - y_adj;
points(2, 0) = x2 + x_adj;
points(2, 1) = y2 - y_adj;
points(3, 0) = x2 - x_adj;
points(3, 1) = y2 + y_adj;
image.draw_polygon(points, color, opacity);
}
相关文章:
- 个人图书馆,数字正数或负数
- 像 POCO 这样的C++图书馆如何访问网络?
- 与第三方公共图书馆/代码接口
- Abseil和CMake在图书馆
- 如何制作跨平台图书馆
- MinGW在Cygwin上.关于链接GNU科学图书馆的一些问题
- 与libc相比,Gnu科学图书馆的性能较差
- 图书馆时间.H与C++
- C++的"皮条客我的图书馆"
- 制作不认识我的图书馆
- 谷歌丁克图书馆大楼C++
- 将Thirt-Party共享图书馆与Python Ctypes集成
- Visual Studio 2012静态图书馆与Visual Studio 2017
- Visual Studio 2017无法通过图书馆构建
- 如何获取当前图书馆路径
- 分配但不使用分配器的标准图书馆设施
- 带有Visual Studio的第三方图书馆
- Jacobi SVD的Eigen图书馆
- 在编译像Pillow之类的图书馆时,如何更改Python dll的名称
- 波科C++图书馆:"Not found: mysql"