4

我想在 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)很简单,给出曲线的视觉效果。

4

2 回答 2

3

我最终使用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()
于 2013-05-13T21:53:52.850 回答
0

这个问题没有一个正确的答案,因为弧的曲率不受限制。这个问题的数学基础是抛射运动,它给出了两个关键方程:

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 公式。

于 2013-05-13T16:12:21.357 回答