2017-10-05 5 views
1

Ich bin nicht sicher, wie das folgende Problem in Python zu lösen:
ich eine zylindrische Oberfläche haben, die ich mesh wollen und dann bin Daten zu jedem Block des Netzes. Ich habe Positionsdaten (X, Y, Z) von Strahlen, die auf die zylindrische Oberfläche treffen. Nach dem Erzeugen eines Gitters auf dem Zylinder muss ich die Anzahl der Strahlen (Datenpunkte) in jedem Block meines Gitters zählen.Erzeugen Sie eine Masche auf einer zylindrischen Oberfläche und Behälterdaten, um es

Die Parameter des Zylinders sind wie folgt:
radius = 0.1m, Höhe = 0,15 M, Mittelpunkt: [X = 0, Y = 0, Z = 0]

um das Netz zu erzeugen, könnte man verwenden Sie die Antwort von How to generate regular points on cylindrical surface mit dem folgenden Code kopiert: `

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) 

` Was jetzt ist durch die „Ray Daten“ Schleife bleibt die Anzahl der Strahlen zu finden, die jeden Block des Netzes getroffen.

Mein erster Gedanke Verfahren waren wie folgt:

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 

Dies ist, wo ich stecken bin. Wie bereits erwähnt, handelt es sich bei den "Ray-Daten" um eine CSV-Datei, die die Positionen (X, Y, Z) jedes Strahls enthält, der auf die zylindrische Oberfläche trifft. Siehe den angegebenen Link: Ray data sample for cylindrical surface.

Ich muss nur herausfinden, wie man überprüft, wo die Strahlen in mein Netz fallen. Die Anzahl der Strahlen in jedem Block wird mit einer Konstanten (Leistung pro Strahl) multipliziert, um die Leistung (in Watt) in jedem Block zu erhalten. Dieser Wert wird dann durch die Fläche des Blocks geteilt, um den Wärmefluss (W/m^2) zu erhalten.

Die endgültige Ausgabe, die ich brauche, ist ein Array, das den Schwerpunkt jedes Blocks des Gitters mit dem entsprechenden Wärmeflusswert enthält.

Irgendwelche Ideen, wie man dieses Problem löst? Ich glaube, mit pandas arbeiten ist auch eine Option.

+1

Sie sind nur interessiert an der Oberfläche so empfehle ich Ihre Daten & Zylinderoberfläche in einen 2-dimensionalen Raum zu verwandeln –

+0

die Daten in einen 2D-Raum Transforming Ich werde mich immer noch mit dem Problem beschäftigen, die Strahlen in das Gitter einzuordnen und den Schwerpunkt jedes Behälters zu bestimmen. –

+0

Ihre "Strahlen" sind nur Punkte.Stimmt es, dass du mit "Strahlen" tatsächlich Schnittpunkte eines Strahls (von dem ich dachte, dass er ein Vektor wäre) mit der Oberfläche des Zylinders meinst? – Paul

Antwort

0

Wie bereits im Kommentar vorgeschlagen, würde ich empfehlen, Ihre Oberfläche in einen 2D-Raum zu verwandeln. Auf diese Weise können Sie Ihre Daten problemlos gruppieren.

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() sieht jetzt in etwa wie folgt aus. z und phi ist eine Darstellung der Strahlen in 2d. Die intensity ist, was Sie "Power of Ray" genannt haben.

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 

Jetzt einfach Bins erstellen und die Daten gruppieren. Schließlich Summe über alle Intensitäten.

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() 

Die result.head() sieht dann wie folgt aus:

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 
Verwandte Themen