[英]Wrapping a given coordinates (x,y,z) in a twisted structure
我正在嘗試將坐標(x,y,z)包裝在Mobius條帶上 (通過扭曲一次並連接條帶的兩端獲得的拓撲結構)。
使用以下代碼(從RG出發),其結構(我可以為其創建xyz坐標)。
import numpy as np
import matplotlib.pyplot as plt
bLength=1.6
numPoints=10
radius = bLength*numPoints / (2 * np.pi)
theta = np.linspace(0,2*np.pi,numPoints,endpoint=False)
dtheta=theta[1]-theta[0]
x0,y0=(radius * np.cos(theta)), (radius * np.sin(theta))
x1,y1=(radius * np.cos(theta+dtheta/2)) , (radius *
np.sin(theta+dtheta/2))
#plt.plot(x0,y0)
#plt.show()
#plt.plot(x1,y1)
#plt.show()
cons0=np.ones(x0.shape)*0
cons1=np.ones(x1.shape)*2
np.savetxt('cooRing1.csv',np.c_[x0,y0,cons0],delimiter=' ')
np.savetxt('cooRing2.csv',np.c_[x1,y1,cons1],delimiter=' ')
cat cooRing1.csv cooRing2.csv > coordinates.csv
[![在此處輸入圖片描述] [3]] [3]
我想在Mobius地帶上方的xyz坐標上進行映射。
網站上的其他示例提供了以下示例(代碼也使用了不公開的模塊)
import Twister as Twister
import math
def displacement(x, width, wrapping_angle):
"""
Function for converting a nanosheet coordinate into a partly wrapped nanotube
@param x : Coordinates of nanosheet atom
@param width : Width of the nano-sheet
@param wrapping_angle : maximum wrapping angle of the nanotube in radians
"""
# calculate the average radius of the incomplete wrapped tube
radius = width/wrapping_angle
# find the angle of the current atom
angle = (x[2]-width/2.)/radius
# calculate the radius of the current atom
atom_radius = radius+x[1]
# return atom position of the wrapped atom
return numpy.array([x[0], atom_radius*math.cos(angle),atom_radius*math.sin(angle)])
def configuration(n, m, repetition):
"""
Function for generating a moebius molecule
@param n : Chiral vector index
@param m : Chiral vector index
@param repetition : Repetition along z
"""
# build n,m ribbon
ribbon = NanoRibbon(n,m)
ribbon = ribbon.repeat(1,1,repetition)
# get properties of the ribbon
lattice = ribbon.bravaisLattice()
elements = ribbon.elements()
cartesian_coordinates=ribbon.cartesianCoordinates().inUnitsOf(Angstrom)
# calculate the length of the 1-d structure
z_length = numpy.linalg.norm(lattice.primitiveVectors()[2].inUnitsOf(Angstrom))
# calculate twist parameters
rotation_angle_per_z = math.pi /z_length
rotation_axis = numpy.array([0,0,1])
rotation_axis_center = numpy.sum(cartesian_coordinates,axis=0)/len(cartesian_coordinates)
# define a function of one variable, f(c), for displacing the atoms
f = lambda c : Twister.displacement(c, rotation_angle_per_z, rotation_axis,
rotation_axis_center, 0.,z_length)
# apply the function to find new displaced coordinates
cartesian_coordinates = numpy.apply_along_axis(f, 1, cartesian_coordinates)
cartesian_center = numpy.sum(cartesian_coordinates,axis=0)/len(cartesian_coordinates)
cartesian_coordinates = cartesian_coordinates - cartesian_center
# define a function of one variable, f(c), for displacing the atoms
f = lambda c : displacement(c, z_length,2.0*math.pi)
# apply the function to find new displaced coordinates
cartesian_coordinates = numpy.apply_along_axis(f, 1, cartesian_coordinates)
return MoleculeConfiguration(
elements=elements,
cartesian_coordinates=cartesian_coordinates * Angstrom
)
# Instantiate the builder object and choose our title
builder = Builder()
builder.title('Moebius ribbon')
# Set the configuration generator
builder.setConfigurationGenerator(configuration)
# Tube properties group
builder.newGroup('Tube parameters')
builder.integer( 'n', 6, 'n', min=1, max=1000)
builder.integer( 'm', 0, 'm', min=0, max=1000)
builder.integer( 'repetition', 40, 'C-direction', min=1, max=1000)
Python中是否有任何類似的模塊,以便我可以構建所需的結構並創建xyz坐標? 或如何進一步完成代碼?
無法將2xN個環之一的坐標轉換為莫比烏斯帶。 那是因為其中帶半個扭曲的交替帶必須具有奇數個原子,而您的當前環始終具有偶數。 您需要切掉一個原子或添加一個原子,以使扭曲起作用。 也許您可以通過將第一個原子和最后一個原子堆疊在一起來進行轉換,但是這種轉換非常丑陋(無論是從數學角度還是在情節上)。
盡管這可能使您無法通過3D轉換來實現,但是您可以從頭開始創建具有所需扭曲的坐標。 只需為條帶的單個邊緣生成單個點陣列(只有一條邊緣是使Möbius條帶怪異的原因之一)。 邊緣在圓上繞兩個圈,在鋼帶的每一側各繞一個圈,並且扭曲發生的速度是主旋轉速度的一半。
這是我的目的:
bLength=1.6
n = 10
numPoints = 2*n + 1
radius = bLength*numPoints / (4*np.pi) # 4*pi because the edge goes around the circle twice
theta = np.linspace(0, 4*np.pi, numPoints, endpoint=False) # here too
x = (radius + np.cos(theta/2)) * np.cos(theta)
y = (radius + np.cos(theta/2)) * np.sin(theta)
z = np.sin(theta/2)
plt.plot(x, y) # I don't know how to graph in 3d, so only x and y here
plt.show()
就像您當前的代碼一樣,這使寬度為2。 如果那不是正確的寬度,則應在計算x
和y
將添加到半徑中的cos
項與用於z
的sin
值相乘所需寬度的一半。
請注意,盡管這段代碼可以產生您想要的結果,但是在物理上描述原子的實際環時,坐標可能是無用的。 坐標之間的某些距離將與其他距離大不相同(例如,在條帶的內部而當條帶幾乎平坦時,則在外部),而真正的由原子構成的莫比烏斯條帶(如果可以做到的話)可能會以某種方式折疊,而不是以均勻的速度扭曲(紙制成的莫比烏斯帶也不會以這種方式扭曲)。 發現原子究竟如何真正將安排將是一個更加棘手的問題(和物理學家,不是程序員的一個問題)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.