gpt4 book ai didi

python - 使用 Wand 和 Python 生成样条曲线

转载 作者:行者123 更新时间:2023-12-01 02:06:24 27 4
gpt4 key购买 nike

我正在尝试绘制从 DXF 文件中提取的样条曲线的光栅表示。我使用 ezdxf 库从 DXF 文件中提取数据,并使用 Python Wand 库 (ImageMagick) 来绘制图像。 Wand 具有样条函数,但它绘制的内容并不总是与 DXF 文件中的曲线匹配。这并不奇怪,因为 Wand 样条函数没有节点或 DXF 样条曲线阶数的输入。下图显示了 DXF 形状的外观。 Wand 样条函数在一个示例中运行良好,但在另一个示例中则不然。

第一个是样条椭圆Oval Example .

Oval Example

第二个是书脊矩形 Rectangle Example .

Rectangle Example

这些形状的 DXF 文件中的数据点和结已被提取并在以下创建示例位图的示例代码中使用。即使不考虑结和度数,椭圆形也能很好地渲染 test_image_oval.bmp .

test_image_oval.bmp

矩形的所有边和角都变形 test_image_rect.bmp .

test_image_rect.bmp

控制点以红色绘制。包含但未使用结。

from wand.image import Image
from wand.color import Color
from wand.drawing import Drawing

############################################
point_list_oval = [ (5.0, 1.5, 0),
(5.0, 0.6715728753, 0),
(3.8807118745, 0.0, 0),
(2.5, 0.0, 0),
(1.1192881255, 0.0, 0),
(0.0, 0.6715728753, 0),
(0.0, 1.5, 0),
(0.0, 2.3284271247, 0),
(1.1192881255, 3.0, 0),
(2.5, 3.0, 0),
(3.8807118745, 3.0, 0),
(5.0, 2.3284271247, 0),
(5.0, 1.5, 0)]

knots_oval = [0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0]

############################################
point_list_rect = [(3.75, 0.0, 0),
(3.75, 0.0, 0),
(0.25, 0.0, 0),
(0.25, 0.0, 0),
(0.1125, 0.0, 0),
(0.0, 0.1125, 0),
(0.0, 0.25, 0),
(0.0, 0.25, 0),
(0.0, 5.75, 0),
(0.0, 5.75, 0),
(0.0, 5.8875, 0),
(0.1125, 6.0, 0),
(0.25, 6.0, 0),
(0.25, 6.0, 0),
(3.75, 6.0, 0),
(3.75, 6.0, 0),
(3.8875, 6.0, 0),
(4.0, 5.8875, 0),
(4.0, 5.75, 0),
(4.0, 5.75, 0),
(4.0, 0.25, 0),
(4.0, 0.25, 0),
(4.0, 0.1125, 0),
(3.8875, 0.0, 0),
(3.75, 0.0, 0)]

knots_rect = [0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 7.0, 7.0, 7.0, 8.0, 8.0, 8.0, 8.0]


############################################
def draw_spline(img_width, img_height, DPI, point_list, filename):
POINT_SIZE = 1
STROKE_WIDTH = 0.5

img = Image(width=img_width, height=img_height, background=Color('white'))

# Convert the points to a 96dpi image space, remove the z axis
converstion_list = []
for point in point_list:
point = (int(round(point[0] * DPI)), int(round(point[1] * DPI)))
converstion_list.append(point)
point_list = converstion_list

# Draw the control points
with Drawing() as draw:
draw.stroke_width = STROKE_WIDTH
draw.stroke_color = Color('red')
draw.fill_color = Color('red')

print '---------------------'
print 'image points'
for point in point_list:
perim = (point[0] + POINT_SIZE, point[1])
draw.circle(point, perim)
print point
draw(img)

# draw the bezier path
with Drawing() as draw:
draw.stroke_width = STROKE_WIDTH
draw.stroke_color = Color('green')
draw.fill_color = Color('transparent')

draw.bezier(point_list)

draw(img)

img.save(filename=filename)

############################################
DPI = 96
draw_spline(577,385, DPI, point_list_oval,'test_image_oval.bmp')
draw_spline(577, 700, DPI, point_list_rect, 'test_image_rect.bmp')

有人知道如何使用 Wand 库生成样条曲线并考虑节点和度数以及数据点吗?

我还尝试使用 SciPy 库样条函数 (interpolate.splprep),但效果有限。这是解决方案的另一种可能性。遵循该路径意味着使用 SciPy 库对大量点进行插值,并使用 Wand 中的折线函数来逼近曲线。如果有人感兴趣,我也可以包含该示例代码,但我不想让线程过于困惑。

任何有关 Spline 和 Wand 的见解将不胜感激。

谢谢。

最佳答案

要理解的关键是贝塞尔曲线是样条曲线,但并非所有样条曲线都是贝塞尔曲线。因此,对于 DXF,只需绘制四坐标 block ,并使用最后使用的点作为下一次迭代的第一个点。

# draw the bezier path
with Drawing() as draw:
draw.stroke_width = STROKE_WIDTH
draw.stroke_color = Color('green')
draw.fill_color = Color('transparent')
chunk = [] # Prototype a temporary list.
for points in point_list: # Iterate over all points.
chunk.append(points) # Append to temporary list.
if len(chunk) == 4: # Ready to draw?
draw.bezier(chunk) # Draw spline segment.
del chunk[0:3] # Clear first three items, and reuse last point.
draw(img)

oval rect

关于python - 使用 Wand 和 Python 生成样条曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49023851/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com