2

is possible to convert the (x;y) coordinates system into a NURBS definition control points and knots?

The main idea is that I'm trying to develop a modeling tool in python for air wind generator and I want mathematically model the blades as a NURBS surfaces, but the curves that defines the blade transversal sections are normalized into (x;y) coordinates files.

Now I have all the (x;y) points defined into 2D Numpy array.

efirvida
  • 4,592
  • 3
  • 42
  • 68

2 Answers2

4

You can use scipy.interpolate for this.

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()

enter image description here

The tuple tck contains your knot vector and control points (coefficients). There are also more involved routines in SciPy, look here.

Note that these are only for bspline curves. As far as I know there are no equivalent methods for surfaces in SciPy. If you want to use surfaces, depending on your requirement, you can either use 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]])

enter image description here

or the 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.

Community
  • 1
  • 1
romeric
  • 2,325
  • 3
  • 19
  • 35
2

Are you certain that you need NURBS surfaces? As far as I can tell, their primary advantage over b-spline surfaces is that they can precisely model circular arcs. I've worked with airfoils for many years, and arcs aren't something that are particularly useful to me.

Anyway, romeric is correct when he states that there is nothing analogous to scipy.interpolate.splprep for surfaces. But if you're not against rolling your own, you can create a 3D array from your section data of shape (3, m, n), where 'm' is the number of points per section, 'n' is the number of sections, and the first dimension holds x, y, and z values on the m x n grid. Once you have that, you can use scipy.interpolate.RectBivariateSpline to create 3 separate 2D parametric surfaces for the x, y and z coordinates. Then write a class to combine these into a single 2D surface in 3D space, so that when you call mysurf.ev(0.5, 0.2) for instance, it evaluates the 3 RectBivariateSpline instances embedded in your class and returns an (x, y, z) coordinate.

I've posted a Gist here that may get you started. To try it, either run it from the command line, or do this:

from bsplinesurf import DemoBSplineSurf
srf = DemoBSplineSurf()
srf.plot()
subnivean
  • 1,132
  • 11
  • 19