【发布时间】:2019-07-09 09:14:24
【问题描述】:
我正在尝试通过应用平移、旋转和缩放变换来绘制一些基本形状。
但是,随着坐标系的缩小,线条变得越来越细(我想保持不变):
请参阅下面的附加代码块,它说明了我已经尝试过的内容。
开罗官方教程提供了这样一种更新线宽的方法:
double ux=1, uy=1;
cairo_device_to_user_distance (cr, &ux, &uy);
if (ux < uy)
ux = uy;
cairo_set_line_width (cr, ux);
(参见https://cairographics.org/tutorial/,“提示和技巧”/“线宽”部分)
import cairo
def rect(ctx, x, y, w, h):
ctx.move_to(x, y)
ctx.rel_line_to(w, 0)
ctx.rel_line_to(0, h)
ctx.rel_line_to(-w, 0)
ctx.close_path()
ctx.stroke()
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 300, 300)
context = cairo.Context(surface)
context.scale(300, 300)
# background
context.set_source_rgb(0.5, 0.8, 0.8)
context.paint()
# new stroking color is black
context.set_source_rgb(0, 0, 0)
# translating to the center point
context.translate(0.5, 0.5)
# See https://cairographics.org/tutorial/ -> Tips and Tricks -> Line width
context.set_line_width(context.device_to_user_distance(1, 1)[0])
# So far so good, the rect is ok
rect(context, -0.1, -0.1, 0.2, 0.2)
# With each iteration, I rotate the coordinate system 60˚ clockwise,
# translate and scale down a bit
for i in range(6):
scale_factor = 0.5
angle = np.pi/3.
dy = -0.3
context.rotate(angle)
context.translate(0, dy)
context.scale(scale_factor, scale_factor)
old_lw = context.get_line_width()
dist = context.device_to_user_distance(1, 1)
print('{0} Old: {1:2.4f} New: {2:2.4f}'.format(i, old_lw, dist[0]))
context.set_line_width(dist[0])
rect(context, -0.05, -0.05, 0.1, 0.1)
# Scaling and translating back, keeping current rotation cumulative
context.scale(1/scale_factor, 1/scale_factor)
context.translate(0, -dy)
surface.write_to_png('test.png')
打印块产生这个:
0 Old: 0.0033 New: 0.0091
1 Old: 0.0091 New: 0.0024
2 Old: 0.0024 New: -0.0067
3 Old: 0.0000 New: -0.0091
4 Old: 0.0000 New: -0.0024
5 Old: 0.0000 New: 0.0067
所以,我认为问题出在这一行:
dist = context.device_to_user_distance(1, 1)
在迭代时,它开始产生负值。这会导致奇怪和错误的结果:。
要绘制我一开始提到的初始图像,只需要在循环内设置线宽来注释行。
我错在哪里?提前致谢。
【问题讨论】:
-
想象你的距离“向右”移动一个单位。那是(0,1)的距离。现在您将其旋转 180°。现在它“向左”移动一个单位,因此距离变为 (0,-1)。我认为这就是
cairo_device_to_user_distance()给你负值的原因:因为方向“转身”。
标签: python graphics cairo pycairo