簡體   English   中英

python:如何在兩個3d點之間繪制曲線?

[英]python: how to draw a curve between two 3d points?

我想在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),給出曲線的視覺效果。

我最終使用scipy.interpolate來獲取曲線,並將其添加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()

這個問題沒有一個正確的答案,因為弧的曲率不受約束。 這個問題的數學基礎是拋射運動 ,它給出了兩個關鍵方程:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM