I am unsure how to solve the following problem in Python:
I have a cylindrical surface which I want to mesh
and then bin
data to each block of the mesh. I have positional data (X,Y,Z) of rays that hit the cylindrical surface. After generating a mesh on the cylinder I have to count the number of rays (data points) in each block of my mesh.
The parameters of the cylinder are as follow:
radius = 0.1m, height = 0.15m, midpoint: [X=0,Y=0,Z=0]
To generate the mesh one could use the answer from How to generate regular points on cylindrical surface with the code copied below: `
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)
` What remains now is to loop through the "Ray data" to find the number of rays that hit each block of the mesh.
My initial thought process were as followed:
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
This is where I am stuck. As mentioned, the "Ray Data" is a CSV file that contains the positions (X,Y,Z) of each ray that hit the cylindrical surface. See the provided link: Ray data sample for cylindrical surface.
I just need to figure how to check where the rays fall within my mesh. The number of rays in each block will be multiplied by a constant (power per ray) to obtain the power (in Watts) in each block. This value is then divided by the area of the block to obtain the heat flux (W/m^2).
The final output I need is an array containing the centroid of each Block of the mesh with the corresponding heat flux value.
Any ideas how to solve this problem?
I believe working with pandas
is also an option.