使用Wand和Python生成样条曲线
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Wand和Python生成样条曲线相关的知识,希望对你有一定的参考价值。
我正在尝试绘制从DXF文件中提取的样条曲线的栅格表示。我使用ezdxf库从DXF文件中提取数据,并且我使用Python Wand库(ImageMagick)来绘制图像。 Wand具有样条函数,但它绘制的内容并不总是与DXF文件中的曲线匹配。这并不奇怪,因为魔杖样条函数没有结节的输入或DXF样条曲线的程度。以下图像显示了DXF形状的外观。魔杖样条函数适用于一个示例,但不适用于另一个示例。
第一个是花键椭圆形Oval Example。
第二个是脊柱矩形Rectangle Example。
这些形状的DXF文件中的数据点和节点已被提取并用于以下示例代码中,该代码创建了样本位图。即使没有考虑结和度数,椭圆形渲染良好的test_image_oval.bmp。
矩形在各个角落都是畸形的qazxsw poi。
控制点以红色绘制。包括但不使用。
有没有人知道如何使用Wand库生成样条曲线并考虑结点和度数以及数据点?
我也尝试过使用SciPy库样条函数(interpolate.splprep),但成效有限。这是解决方案的另一种可能性。遵循该路径将意味着使用SciPy库来插入一大组点,并使用Wand中的折线函数来近似曲线。如果有人感兴趣我也可以包含该示例代码,但我不想过多地混淆线程。
任何有关Spline和Wand的见解都将受到高度赞赏。
谢谢 。
要理解的关键是贝塞尔曲线是一个样条曲线,但并非所有样条曲线都更为精确。因此对于DXF,只需绘制四个坐标的块,并使用最后使用的点作为下一次迭代的第一个。
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')
# 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)
以上是关于使用Wand和Python生成样条曲线的主要内容,如果未能解决你的问题,请参考以下文章