我不确定如何在Python中解决以下问题:
我有一个圆柱面,我希望mesh
然后bin
数据到网格的每个块。我有射击圆柱面的光线的位置数据(X,Y,Z)。在圆柱体上生成网格后,我必须计算网格的每个块中的光线数量(数据点)。
气缸的参数如下:
半径= 0.1m,高度= 0.15m,中点:[X = 0,Y = 0,Z = 0]
要生成网格,可以使用How to generate regular points on cylindrical surface中的答案,其代码复制如下: `
import numpy as np
def make_cylinder(radius, length, nlength, alpha, nalpha, center, orientation):
"""
radius = radius of cylinder,
length = cylinder height, nlength = number of lengthwise divisions.
alpha = total degrees of cylinder, nalpha = number of circumferential divisions.
center = [X,Y,Z] coordinates of cylinder's midpoint.
"""
#Create the length array
I = np.linspace(0, length, nlength)
#Create alpha array avoid duplication of endpoints
#Conditional should be changed to meet your requirements
if int(alpha) == 360:
A = np.linspace(0, alpha, num=nalpha, endpoint=False)/180*np.pi
else:
A = np.linspace(0, alpha, num=nalpha)/180*np.pi
#Calculate X and Y
X = radius * np.cos(A)
Y = radius * np.sin(A)
#Tile/repeat indices so all unique pairs are present
pz = np.tile(I, nalpha)
px = np.repeat(X, nlength)
py = np.repeat(Y, nlength)
points = np.vstack(( pz, px, py )).T
#Shift to center
shift = np.array(center) - np.mean(points, axis=0)
points += shift
#Orient tube to new vector
#Grabbed from an old unutbu answer
def rotation_matrix(axis,theta):
a = np.cos(theta/2)
b,c,d = -axis*np.sin(theta/2)
return np.array([[a*a+b*b-c*c-d*d, 2*(b*c-a*d), 2*(b*d+a*c)],
[2*(b*c+a*d), a*a+c*c-b*b-d*d, 2*(c*d-a*b)],
[2*(b*d-a*c), 2*(c*d+a*b), a*a+d*d-b*b-c*c]])
ovec = orientation / np.linalg.norm(orientation)
cylvec = np.array([1,0,0])
if np.allclose(cylvec, ovec):
return points
#Get orthogonal axis and rotation
oaxis = np.cross(ovec, cylvec)
rot = np.arccos(np.dot(ovec, cylvec))
R = rotation_matrix(oaxis, rot)
return points.dot(R)
` 现在剩下的就是遍历" Ray数据"找到击中网格的每个块的光线数量。
我最初的思考过程如下:
data = np.genfromtxt('ray_data.csv', delimiter=',')
num_data_rows, num_data_cols = np.shape(data)
for i in range (num_data_rows): #Loop through the data
这是我被困的地方。如上所述," Ray Data"是一个CSV文件,包含撞击圆柱面的每条光线的位置(X,Y,Z)。请参阅提供的链接:Ray data sample for cylindrical surface。
我只需要弄清楚如何检查光线在网格中的位置。 每个块中的光线数量将乘以常数(每条光线的功率),以获得每个块中的功率(以瓦特为单位)。然后将该值除以块的面积以获得热通量(W / m ^ 2)。
我需要的最终输出是一个数组,其中包含每个网格块的质心以及相应的热通量值。
任何想法如何解决这个问题?
我相信与pandas
合作也是一种选择。
答案 0 :(得分:0)
正如评论中已经提出的,我建议将表面转换为2d空间。这样,您就可以轻松地对数据进行分组。
import numpy as np
import pandas as pd
# generate some random rays (for which we will just assume they hit the surface)
rays = pd.DataFrame(
np.random.uniform(-1,1,(8000,4)),
columns=["x", "y", "z", "intensity"]
)
# transform x and y to polar coordinates while dropping the radius
# (again, just assuming they hit the surface)
rays["phi"] = rays.T.apply(lambda row: np.arctan2(row.y, row.x)).T
rays.head()
现在看起来如下所示。 z
和phi
代表2d中的光线。 intensity
就是你所谓的“射线之力”。
x y z intensity phi
0 -0.237026 -0.634709 -0.889694 0.362156 -1.928199
1 -0.481137 -0.446912 0.687224 0.268080 -2.393056
2 -0.805538 0.068678 0.272009 0.990947 3.056541
3 0.549282 -0.330665 0.318683 -0.150776 -0.541886
4 -0.215676 -0.030922 -0.478929 0.408720 -2.999190
现在,只需创建分档并对数据进行分组。最后总结所有强度。
z_bins = np.arange(0, 1, .1)
phi_bins = np.arange(-np.pi, np.pi, np.pi/10)
result = rays.groupby([
pd.cut(rays.phi, phi_bins),
pd.cut(rays.z, z_bins),
]).intensity.sum()
result.head()
然后如下所示:
phi z
(-3.142, -2.827] (0, 0.1] 0.719154
(0.1, 0.2] -1.733479
(0.2, 0.3] 2.073013
(0.3, 0.4] 1.967453
(0.4, 0.5] 0.001312