2

是否可以将 (x;y) 坐标系转换为NURBS定义控制点和节点?

主要思想是我正在尝试在 python 中为空气风力发电机开发一个建模工具,并且我想在数学上将叶片建模为NURBS曲面,但是定义叶片横截面的曲线被归一化为 (x;y) 坐标文件。

现在我将所有 (x;y) 点定义为 2D Numpy 数组。

4

2 回答 2

4

你可以用scipy.interpolate这个。

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splev, splrep

x = np.linspace(0, 10, 10) # x-coordinates
y = np.sin(x) # y-coordinates
tck = splrep(x, y) # get bspline representation given (x,y) values
x2 = np.linspace(0, 10, 200) # new set of values, just to check
y2 = splev(x2, tck) # evaluate the y values of new coordinates on NURBS curve
plt.plot(x, y, 'o', x2, y2) 
plt.show()

在此处输入图像描述

元组tck包含您的节点向量和控制点(系数)。SciPy 中还有更多涉及的例程,请看这里

请注意,这些仅适用于 bspline 曲线。据我所知,SciPy 中没有等效的表面方法。如果您想使用表面,根据您的要求,您可以使用igakit

from igakit.cad import ruled, circle
c1 = circle(angle=(0,np.pi/2.))
c2 = circle(radius=2,angle=(0,np.pi/2.))
print "knot vector:", c1.knots
print "control points:", c1.control
srf = ruled(c1,c2)
plt.plot(srf)
plt.show() 

knot vector: (array([ 0.,  0.,  0.,  1.,  1.,  1.]),)
control points: array([[  1.00000000e+00,   0.00000000e+00,   0.00000000e+00, 1.00000000e+00],
   [  7.07106781e-01,   7.07106781e-01,   0.00000000e+00, 7.07106781e-01],
   [  2.22044605e-16,   1.00000000e+00,   0.00000000e+00, 1.00000000e+00]])

在此处输入图像描述

NURBS 包。对于更高级的东西, BlenderSalome为所有 NURBS 曲线/曲面系列提供了完整的 Python API,后者基于OpenCascade

于 2015-10-20T17:50:55.570 回答
2

您确定需要 NURBS 曲面吗?据我所知,它们相对于 b 样条曲面的主要优势在于它们可以精确地模拟圆弧。我使用翼型已经很多年了,弧线对我来说并不是特别有用的东西。

无论如何,当 romeric 说没有任何东西类似于scipy.interpolate.splprep表面时,他是正确的。但是,如果您不反对自己滚动,您可以从形状为 (3, m, n) 的截面数据创建一个 3D 数组,其中“m”是每个截面的点数,“n”是部分,第一个维度保存 mxn 网格上的 x、y 和 z 值。完成后,您可以使用scipy.interpolate.RectBivariateSpline为 x、y 和 z 坐标创建 3 个单独的 2D 参数曲面。然后编写一个类,将它们组合成 3D 空间中的单个 2D 表面,这样当您调用 mysurf.ev(0.5, 0.2)实例时,它会评估RectBivariateSpline 嵌入在您的类中的 3 个实例并返回 (x, y, z) 坐标。

我在这里发布了一个要点,可以帮助您入门。要尝试它,请从命令行运行它,或者执行以下操作:

from bsplinesurf import DemoBSplineSurf
srf = DemoBSplineSurf()
srf.plot()
于 2015-11-30T12:24:18.730 回答