数学图形之将曲线(curve)转化成曲面管

在我关于数学图形的博客中,一开始讲曲线的生成算法.然后在最近的章节中介绍了圆环,还介绍了螺旋管以及海螺的生成算法.一类是曲线,一类是环面,为什么不将曲线变成环的图形,毕竟曲线看上去太单薄了,这一节我将介绍如何依照曲线(Curve)生成其相应的曲面管.

相关软件参见:数学图形可视化工具,使用自己定义语法的脚本代码生成数学图形.

圆柱面这一节的最后,我提供了两种算法,以生成朝向任意方向的圆柱面,一种是极坐标原理,另一种是矩阵原理.这一节也是采用这两个原理生成曲面管,因为由曲线生成的曲面管就是若干个有朝向的圆柱面组成.

 

先看个三维曲线的代码:

圆环面螺线:

#http://xuxzmail.blog.163.com/blog/static/25131916200976114621705/
#Toroidal spiral

vertices = 1000

t = from 0 to (2*PI)

r = 5
n = 20

x = (r+sin(20*t))*cos(t)
y = (r+sin(20*t))*sin(t)
z = cos(n*t)

r = 10;
x = x*r
y = y*r
z = z*r

圆环面螺线管(极坐标原理):

#http://xuxzmail.blog.163.com/blog/static/25131916200976114621705/
#Toroidal spiral

vertices = D1:36 D2:720

u = from 0 to (2*PI) D1
v = from 0 to (2*PI) D2

r = 5
n = 20

xq = (r+sin(20*v))*cos(v)
yq = (r+sin(20*v))*sin(v)
zq = cos(n*v)

#由线变管

xd = array_difference(xq, 36)
yd = array_difference(yq, 36)
zd = array_difference(zq, 36)

len = sqrt(xd*xd + yd*yd + zd*zd)
a = xd/len
b = yd/len
c = zd/len

radius =0.2

ac = sqrt(a*a + c*c)
angleY = atan2(ac, b)
angleXZ = atan2(a,c)

m = cos(u) * radius
n = sin(u) * radius

e = sin(angleY)
f = cos(angleY)

g = sin(angleXZ)
h = cos(angleXZ)

x0 = m
y0 = -n*e
z0 = n*f

x1 = x0*h + z0*g
y1 = y0
z1 = -x0*g + z0*h

x = x1 + xq
y = y1 + yq
z = z1 + zq

圆环面螺线管(矩阵原理):

#http://xuxzmail.blog.163.com/blog/static/25131916200976114621705/
#Toroidal spiral

vertices = D1:36 D2:720

u = from 0 to (2*PI) D1
v = from 0 to (2*PI) D2

r = 5
n = 20

xq = (r+sin(20*v))*cos(v)
yq = (r+sin(20*v))*sin(v)
zq = cos(n*v)

#由线变管

xd = array_difference(xq, 36)
yd = array_difference(yq, 36)
zd = array_difference(zq, 36)

len = sqrt(xd*xd + yd*yd + zd*zd)
len = max(len, 0.00001)
a = xd/len
b = yd/len
c = zd/len

len = sqrt(b*b + c*c)
len = max(len, 0.00001)
m = c/len
n = -b/len

i = b*n - c*m
j = - a*n
k = a*m

radius = 0.2

x0 = cos(u) * radius
z0 = sin(u) * radius

x = x0*i + xq
y = x0*j + z0*m + yq
z = x0*k + z0*n + zq

这是我所写的最复杂的脚本代码了,为了写这种脚本,我不惜将脚本解析器实现对自定义变量的支持.

不过这两种写法都会有点瑕疵,因为在某个情况下拐点时,会出现扭曲,这种瑕疵似乎很难解决.

 

再举个节的例子:

line_torus_knot(37)

vertices = 10000
t = from 0 to (6*PI)

p = 3
q = 7

r = 2 + cos(q/p*t)

x = r*sin(t)
y = sin(q/p*t)
z = r*cos(t)

r = 0.5 + 0.5*sin(t)
g = 0.5 + 0.5*y
b = 0.5 + 0.5*cos(t)

pipe_torus_knot(37)极坐标原理

vertices = D1:36 D2:360

u = from 0 to (2*PI) D1
v = from 0 to (6*PI) D2

p = 3
q = 7

r = 2 + cos(q/p*v)

xq = r*sin(v)
yq = sin(q/p*v)
zq = r*cos(v)

r = 0.5 + 0.5*sin(v)
g = 0.5 + 0.5*yq
b = 0.5 + 0.5*cos(v)

#由线变管

xd = array_difference(xq, 36)
yd = array_difference(yq, 36)
zd = array_difference(zq, 36)

len = sqrt(xd*xd + yd*yd + zd*zd)
a = xd/len
b = yd/len
c = zd/len

radius = 0.2

ac = sqrt(a*a + c*c)
angleY = atan2(ac, b)
angleXZ = atan2(a,c)

m = cos(u) * radius
n = sin(u) * radius

e = sin(angleY)
f = cos(angleY)

g = sin(angleXZ)
h = cos(angleXZ)

x0 = m
y0 = -n*e
z0 = n*f

x1 = x0*h + z0*g
y1 = y0
z1 = -x0*g + z0*h

x = x1 + xq
y = y1 + yq
z = z1 + zq

pipe_torus_knot(37)矩阵原理

vertices = D1:36 D2:360

u = from 0 to (2*PI) D1
v = from 0 to (6*PI) D2

p = 3
q = 7

r = 2 + cos(q/p*v)

xq = r*sin(v)
yq = sin(q/p*v)
zq = r*cos(v)

r = 0.5 + 0.5*sin(v)
g = 0.5 + 0.5*yq
b = 0.5 + 0.5*cos(v)

#由线变管

xd = array_difference(xq, 36)
yd = array_difference(yq, 36)
zd = array_difference(zq, 36)

len = sqrt(xd*xd + yd*yd + zd*zd)
px = xd/len
py = yd/len
pz = zd/len

len = sqrt(py*py + pz*pz)
len = max(len, 0.00001)
m = pz/len
n = -py/len

i = py*n - pz*m
j = - px*n
k = px*m

radius = 0.2

x0 = cos(u) * radius
z0 = sin(u) * radius

x = x0*i + xq
y = x0*j + z0*m + yq
z = x0*k + z0*n + zq

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将已知坐标的三维点连接曲线并将其拉伸为曲面,您可以使用 Qt 和 VTK 库。以下是一个简单的代码示例,它演示了如何使用 VTK 创建曲线并将其拉伸为曲面: ```cpp #include <vtkSmartPointer.h> #include <vtkPoints.h> #include <vtkCellArray.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkParametricSpline.h> #include <vtkParametricFunctionSource.h> #include <vtkParametricSurfaceSource.h> int main(int, char *[]) { // Create some points vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->InsertNextPoint(0,0,0); points->InsertNextPoint(1,0,0); points->InsertNextPoint(2,1,0); points->InsertNextPoint(3,2,1); points->InsertNextPoint(4,3,2); // Create a spline vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New(); spline->SetPoints(points); // Create a curve vtkSmartPointer<vtkParametricFunctionSource> curveSource = vtkSmartPointer<vtkParametricFunctionSource>::New(); curveSource->SetParametricFunction(spline); curveSource->Update(); // Create a surface vtkSmartPointer<vtkParametricSurfaceSource> surfaceSource = vtkSmartPointer<vtkParametricSurfaceSource>::New(); surfaceSource->SetParametricFunction(spline); surfaceSource->SetUResolution(30); surfaceSource->SetVResolution(30); surfaceSource->Update(); // Visualize vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(curveSource->GetOutput()); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); vtkSmartPointer<vtkPolyDataMapper> surfaceMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); surfaceMapper->SetInputData(surfaceSource->GetOutput()); vtkSmartPointer<vtkActor> surfaceActor = vtkSmartPointer<vtkActor>::New(); surfaceActor->SetMapper(surfaceMapper); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->AddActor(surfaceActor); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetRenderWindow(renderWindow); renderWindow->Render(); renderWindowInteractor->Start(); return EXIT_SUCCESS; } ``` 以上代码使用了 `vtkParametricSpline` 类来创建一个样条曲线,然后使用 `vtkParametricFunctionSource` 类将曲线转换为 `vtkPolyData` 对象。接下来,使用 `vtkParametricSurfaceSource` 类将曲线拉伸为曲面。最后,使用 `vtkPolyDataMapper` 类和 `vtkActor` 类将曲线曲面添加到 `vtkRenderer` 类中,并使用 `vtkRenderWindow` 类将其显示在屏幕上。 您可以根据需要修改代码以适应您的应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值