Python,如何将 x;y 点列表定义的样条转换为 NURB 曲线
Python, how to convert spline defined by x;y list of point into NURB curve
是否可以将 (x;y) 坐标系转换为 NURBS 定义控制点和节点?
主要的想法是我正在尝试在 python 中开发一个用于空气风力发电机的建模工具,我想在数学上将叶片建模为 NURBS 表面, 但定义叶片横截面的曲线被归一化为 (x;y) 坐标文件。
现在我已将所有 (x;y) 点定义到 2D Numpy 数组中。
您可以为此使用 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里面还有更多涉及的套路,看here.
请注意,这些仅适用于 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 package. For fancier stuff Blender and Salome have complete Python API for all family of NURBS curves/surfaces with the latter being based on OpenCascade.
您确定需要 NURBS 曲面吗?据我所知,
与 b 样条曲面相比,它们的主要优势在于它们可以精确地建模
圆弧。我从事机翼工作多年,弧形不是什么东西
对我特别有用。
无论如何,romeric 是正确的,他说表面没有类似于 scipy.interpolate.splprep
的东西。
但是如果你不反对自己动手,你可以创建一个 3D 数组
来自形状为 (3, m, n) 的截面数据,其中 'm' 是每个截面的点数,'n' 是
部分数,第一个维度包含 m x n 网格上的 x、y 和 z 值。
一旦你有了它,你可以使用 scipy.interpolate.RectBivariateSpline
来创建
3 个独立的 2D 参数曲面,用于 x、y 和 z 坐标。然后写
a class 将它们组合成 3D space 中的单个 2D 表面,这样当您调用
mysurf.ev(0.5, 0.2)
例如,它评估 3 RectBivariateSpline
class 和 returns (x, y, z) 坐标中嵌入的实例。
我发布了一个 Gist here 可以帮助您入门。要尝试它,可以从命令行 运行,或者这样做:
from bsplinesurf import DemoBSplineSurf
srf = DemoBSplineSurf()
srf.plot()
是否可以将 (x;y) 坐标系转换为 NURBS 定义控制点和节点?
主要的想法是我正在尝试在 python 中开发一个用于空气风力发电机的建模工具,我想在数学上将叶片建模为 NURBS 表面, 但定义叶片横截面的曲线被归一化为 (x;y) 坐标文件。
现在我已将所有 (x;y) 点定义到 2D Numpy 数组中。
您可以为此使用 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里面还有更多涉及的套路,看here.
请注意,这些仅适用于 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 package. For fancier stuff Blender and Salome have complete Python API for all family of NURBS curves/surfaces with the latter being based on OpenCascade.
您确定需要 NURBS 曲面吗?据我所知, 与 b 样条曲面相比,它们的主要优势在于它们可以精确地建模 圆弧。我从事机翼工作多年,弧形不是什么东西 对我特别有用。
无论如何,romeric 是正确的,他说表面没有类似于 scipy.interpolate.splprep
的东西。
但是如果你不反对自己动手,你可以创建一个 3D 数组
来自形状为 (3, m, n) 的截面数据,其中 'm' 是每个截面的点数,'n' 是
部分数,第一个维度包含 m x n 网格上的 x、y 和 z 值。
一旦你有了它,你可以使用 scipy.interpolate.RectBivariateSpline
来创建
3 个独立的 2D 参数曲面,用于 x、y 和 z 坐标。然后写
a class 将它们组合成 3D space 中的单个 2D 表面,这样当您调用
mysurf.ev(0.5, 0.2)
例如,它评估 3 RectBivariateSpline
class 和 returns (x, y, z) 坐标中嵌入的实例。
我发布了一个 Gist here 可以帮助您入门。要尝试它,可以从命令行 运行,或者这样做:
from bsplinesurf import DemoBSplineSurf
srf = DemoBSplineSurf()
srf.plot()