我编写了这段代码,将六边形连接晶格的一组 2d 坐标包装到 3d 圆柱体中:
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d
import matplotlib.colors
with open("test_A_aux.dat", "r") as aux:
dim = np.genfromtxt(aux, skip_header =3, max_rows = 1)
n = int(input("Enter the value for n: "))
m = int(input("Enter the value for m: "))
# Open coordinate file and import data to array
with open("test_A_crds.dat", "r") as crds:
array = np.genfromtxt(crds)
# Defines the chiral angle based on a1 and a2 vectors
# This is then used to manipulate x,y coords onto the vector
def chiral_angle(n, m):
# a1 vector is set along x axis
a1 = np.array([np.sqrt(3),0])
a2 = np.array([np.sqrt(3)/2, 3/2])
# chiral vector is the dot product of n * a1 and m * a2
chiral_vector = np.add(np.multiply(a1, n), np.multiply(a2, m))
# magnitude of chiral vector
mag = np.linalg.norm(chiral_vector)
# dot product formula to find cos theta
cos_theta = np.dot(chiral_vector, np.array([1,0])) / mag
theta = np.arccos(cos_theta)
return theta
# This function wraps the 2d coordinates into a cylinder by maniuplating
# the y cooridnates and generating z coordinates
# x coordinates unchaged
def wrap(n, m):
# normalises to max length of the dimensions of the input cell
normalise = matplotlib.colors.Normalize(0, dim[1])
X = array[:,0]
THETA = np.array([2*np.pi * normalise(i) for i in array[:,1]])
r = dim[1] / (2 * np.pi)
Y = np.array([r * np.sin(angle) for angle in THETA])
Z = np.array([r * np.cos(angle) for angle in THETA])
# stacks X and Y into n*2 array
tube = np.vstack((X, Y))
# stacks above n*2 array with Z to make n*3 array
tube = np.vstack((tube, Z))
# transposes array to make 3*n array of 3D coordinates
tube = np.transpose(tube)
return tube
# Plotting function
def plot_tube():
fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
plot = ax.scatter(tube[:,0], tube[:,1], tube[:,2])
plt.show()
return
# creates file and writes it to vmd for visualisation
# with open("nanotube.xyz", "w") as vmd:
# vmd.write("{:}\n\n " .format(array.shape[0]))
# for i in range(array.shape[0]):
# vmd.write("{:} {:<10} {:<10} {:<10}\n" .format(i, tube[i,0], tube[i,1], tube[i,2]))
tube = wrap(n, m)
print(tube)
plot_tube()
但是更改 n 和 m 变量对输出的 3d 坐标没有影响。作为参考,手性向量如下所示:
a1 沿 x 轴设置。
如何使 n 和 m 影响手性矢量,从而影响角度 theta 和管子的最终形状?
您没有在wrap 函数中使用chiral_angle 计算。我无法测试,没有数据,但在我看来,你需要在 THETA 计算行中使用 chiral_angle(n, m) 而不是 2*np.pi 。