python:如何在两个3d点之间绘制曲线?

时间:2013-05-13 15:31:23

标签: python curve

我想在3d空间中的任意两点之间绘制曲线。曲线必须是,嗯,“垂直”。我的意思是,曲线点的x,y位置必须在同一条线上,但是z值必须改变,好像你从地面发射了一个射弹,它在空中移动,并再次击中地面。它不需要物理上正确,弧线也可以。

这是起始代码:

import numpy as np

p1=np.array([1,1,1]) #x,y,z coordinates of the first point
p2=np.array([3,3,3]) #x,y,z coordinates of the second point

xi=np.linspace(p1[0],p2[0],100) #determine 100 x coordinates between two points
yi=np.linspace(p1[1],p2[1],100) #determine 100 y coordinates between two points
zi= ??                          #determine 100 z coordinates between two points. 

如何确定那100个z坐标(zi)?

在确定zi之后,在连续点之间绘制线条是非常简单的(使用mayavi或mplot3d),给出曲线的视觉效果。

2 个答案:

答案 0 :(得分:2)

我最终使用scipy.interpolate获取曲线,并将其添加到点之间的直线的z坐标。正如其他人所说,有不止一种方法可以做到这一点。这对我来说已足够了。

### objective: draw an arc between points p1 and p2. z coordinates are raised.

import numpy as np
from scipy import interpolate
from mayavi import mlab

###inputs
p1=np.random.uniform(0,20,(3)) #first point
p2=np.random.uniform(0,20,(3)) #second point
npts = 100 # number of points to sample
y=np.array([0,.5,.75,.75,.5,0]) #describe your shape in 1d like this
amp=5 #curve height factor. bigger means heigher 

#get the adder. This will be used to raise the z coords
x=np.arange(y.size)
xnew = np.linspace(x[0],x[-1] , npts) #sample the x coord
tck = interpolate.splrep(x,y,s=0) 
adder = interpolate.splev(xnew,tck,der=0)*amp
adder[0]=adder[-1]=0
adder=adder.reshape((-1,1))

#get a line between points
shape3=np.vstack([np.linspace(p1[dim],p2[dim],npts) for dim in xrange(3)]).T

#raise the z coordinate
shape3[:,-1]=shape3[:,-1]+adder[:,-1]

#plot
x,y,z=(shape3[:,dim] for dim in xrange(3))
mlab.points3d(x,y,z,color=(0,0,0))
mlab.plot3d(x,y,z,tube_radius=1)
mlab.outline()
mlab.axes()
mlab.show()

答案 1 :(得分:0)

这个问题没有一个正确的答案,因为弧的曲率没有受到约束。这个问题的数学基础是projectile motion,它给出了两个关键方程:

x_2 - x_1 = v_1 cos theta dt
z_2 - z_1 = -1/2 g dt^2 + v_0 sin theta dt

其中v_1是射弹的初始速度,theta是弹丸射击的水平角度,dt是射弹从1点到2点所需的时间,g是重力常数。为简单起见,这暂时忽略了y。你遇到的问题是,这给你两个方程式,但你有三个未知数,v_1,theta和dt。

您可以添加约束,例如,p1和p2中的较高者是轨迹的峰值。如果p2更高,例如,

v_2 = v_1 - g dt = 0

求解这三个方程会得到v_1,它随时间推移给出z坐标:

z = -1/2 g t^2 + v_1 t + z_1

t = np.linspace(0, dt, 100)为您提供了一个numpy向量,您可以将其插入z的公式中。