如何生成随机3D形状(使用广义圆柱体)

时间:2015-05-19 13:55:56

标签: python matplotlib 3d computational-geometry

我正在尝试在3维控制变换后生成随机形状的视频(目前刚体变换)。 我想要各种各样的形状,但我并不局限于底层模型。我更喜欢使用python,因为我对它更熟悉但如果它使事情变得更简单,另一种语言也可以工作。

我尝试使用python和numpy这样做,但三角测量似乎不起作用。 我定义了一条曲线crv和圆圈bc,其随机直径使得圆圈围绕曲线以规则的间隔放置。

import matplotlib as mpl
import matplotlib.tri as mtri

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from matplotlib import pyplot as plt

def angle(v1,v2):
    av1 = np.sqrt((v1**2).sum(-1))
    av2 = np.sqrt((v2**2).sum(-1))
    v12 = np.dot(v1,v2.T)
    return (np.arccos(v12/(av1*av2)))

def rotation_matrix(axis, theta):
    """
    Return the rotation matrix associated with counterclockwise rotation about
    the given axis by theta radians.
    """
    axis = np.asarray(axis)
    theta = np.asarray(theta)
    axis = axis/np.sqrt(np.dot(axis, axis))
    a = np.cos(theta/2)
    b, c, d = -axis*np.sin(theta/2)
    aa, bb, cc, dd = a*a, b*b, c*c, d*d
    bc, ad, ac, ab, bd, cd = b*c, a*d, a*c, a*b, b*d, c*d
    return np.array([[aa+bb-cc-dd, 2*(bc+ad), 2*(bd-ac)],
                     [2*(bc-ad), aa+cc-bb-dd, 2*(cd+ab)],
                     [2*(bd+ac), 2*(cd-ab), aa+dd-bb-cc]])

CP=100
fig = plt.figure()
ax = fig.gca(projection='3d')
theta = np.linspace(-4 * np.pi, 4 * np.pi, CP)
crv = np.zeros((CP,3))
crv[:,2] = np.linspace(-2, 2, CP)
r = crv[:,2]**2 + 1
crv[:,0] = r * np.sin(theta)
crv[:,1] = r * np.cos(theta)


v1=np.array([0,0,1])[None,:]
v2s=np.diff(crv,axis=0)
ax12=np.cross(v1,v2s)
thetas=angle(v1,v2s).T

#Base circle
CiP=400
phi = np.linspace(0.0,2*np.pi,CiP)
r = np.random.rand(CiP)*0.4
bc = np.zeros((CiP,3))
bc[:,0] = r*np.cos(phi)
bc[:,1] = r*np.sin(phi)

points= np.zeros((v2s.shape[0],CiP,3))

for i in range(v2s.shape[0]):
    # Rotation matrix to align the base circle and the direction of the curve 
    rm1 = rotation_matrix(ax12[i,:],thetas[i,:])
    # This is an attempt to fine tune the alignment 
    rm2 = rotation_matrix(v2s[i,:], theta[i]/8.)
    # Rotate bc and center it to the curve.
    points[i,:,:]=np.dot(rm2.squeeze(), np.dot(rm1.squeeze(),bc.T)).T + crv[i]



ax.plot_trisurf(points[:,:,0].ravel(),points[:,:,1].ravel(),points[:,:,2].ravel())
plt.show()

到目前为止,我的方法似乎无法奏效。

你可以帮我解决这个问题吗?

你知道更好的方法吗?

请记住,它应该使用随机曲线而不是固定的曲线,如上例所示。实际上,通用圆柱体根本不是必需的,而是能够产生大量随机结构形状的东西。

谢谢!

0 个答案:

没有答案