Koordinaten-Array in Matrix extrahieren

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
floppy
User
Beiträge: 10
Registriert: Samstag 9. Dezember 2017, 16:24

Guten Tag,
ich haette gerne einen Hinweis um weiterzukommen.
Ein Matrix wird erstellt und manipuliert damit die Koordinaten rotiert werden um ein Achse, und dann im Polar-Modus PHI erhöht wird.
Siehe unten.
Erstes Problem: wie kommt man von einer Matrix0 auf X0 Y0 Z0 ? X0,Y0,Y0=Matrix0[?] wo

Code: Alles auswählen

Matrix0 = np.mgrid[ 0.01:1.1:5j, 0.01:1.1:5j, 0.01:1.1:5j]
Danke sehr fuer die Hilfe

Code: Alles auswählen

import numpy as np
from scipy.spatial.transform import Rotation as R
from astropy.coordinates import cartesian_to_spherical,spherical_to_cartesian
#X0, Y0, Z0 = np.mgrid[ 0.01:1.1:5j, 0.01:1.1:5j, 0.01:1.1:5j]
Matrix0 = np.mgrid[ 0.01:1.1:5j, 0.01:1.1:5j, 0.01:1.1:5j]
Matrix0.resize(5*5*5, 3)
r = R.from_rotvec(np.arccos((1/np.sqrt(3))) *np.array([1/np.sqrt(2), -1/np.sqrt(2), 0]))
Matrix = r.apply(Matrix0)
Matrix.resize(5,5,5,3)
X,Y,Z = Matrix      # FIRST ISSUE IDENTIFIED THERE !!!!!!!!!!!!!!!!!!!!!!!!!!!!
R, Theta, Phi = cartesian_to_spherical(X,Y,Z)
Phi[:] += np.arccos(np.sqrt(2)/np.sqrt(3))
X,Y,Z = spherical_to_cartesian(R,Theta,Phi)
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Variablen werden klein_mit_Unterstrich geschrieben. Konstanten werden komplett groß geschrieben.
Du solltest Rotation nicht in R umbenennen, das macht es nur unnötig schlecht lesbar. Außerdem verwendest du den Namen `R` später noch mal für den Radius in Kugelkoordinaten. Das ist in der Doku meiner Meinung nach ein ungünstig gewähltes Beispiel.
Du schreibst im Post etwas von Polarkoordinaten, verwendest dann aber Kugelkoordinaten im Code. Das ist etwas verwirrend.
Was welche Spalte in der Matrix bedeutet, musst du selbst wissen. Ich vermute aber mal, dass du die Spalten jeweils für X, Y, Z-Koordinate in der Reihenfolge verwendest. Dann wäre `X = Matrix[:, 0]`, `Y = Matrix[:, 1]` usw.
Aber die ganze Umrechnung scheint mir mühselig. Wenn du nur Phi erhöhen willst (da es verschiedene Konventionen gibt, nehme ich hier an: Phi = Winkel in xy-Ebene eines rechtshändigen Koordinatensystems, Z nach oben positiv), entspricht das einer Rotation um die Z-Achse. Kannst das du auch gleich in kartesischen Koordinaten machen. Entweder mit dem schon verwendeten `scipy.spatial.transform.Rotation`oder eben mit einer Rotationsmatrix.
Was willst du denn letztlich damit erreichen?
floppy
User
Beiträge: 10
Registriert: Samstag 9. Dezember 2017, 16:24

Danke sehr für die Hinweise. Ich werde die Benennung der Variablen ändern. Ein Fehler hatte sich eingeschlichen: ich moechte Theta eigentlich reduzieren (und nicht Phi erhöhen). Ich benutze die Kugelkoordinaten-Funktion weil ich keine Polar-Umrechnungsfunktion gefunden habe. Ziel? eine Koordinaten-Matrix um ca 35,3 Grad oeffnen um die Z-Achse (wie ein Regenschirm). Nun versuche ich das Wert FLATT_VALUE von der gesamten theta_lat_compl matrix abzuziehen. Es haengt mit einer Fehlermeldung.

Code: Alles auswählen

radius, theta_lat_compl, phi_long = cartesian_to_spherical(x1,y1,z1)
FLATT_VALUE = np.arccos(np.sqrt(2)/np.sqrt(3))
operator.sub(theta_lat_compl,FLATT_VALUE) #!!!!!! issue there

Code: Alles auswählen

operator.sub(theta_lat_compl,FLATT_VALUE)
  File "/usr/local/lib/python3.5/dist-packages/astropy/coordinates/angles.py", line 543, in __array_ufunc__
    results = super().__array_ufunc__(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/astropy/units/quantity.py", line 444, in __array_ufunc__
    converters, unit = converters_and_unit(function, method, *inputs)
  File "/usr/local/lib/python3.5/dist-packages/astropy/units/quantity_helper/converters.py", line 189, in converters_and_unit
    .format(function.__name__))
astropy.units.core.UnitConversionError: Can only apply 'subtract' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan)
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

astropy.coordinates.cartesian_to_spherical gibt eine Quantity-Objekt zurück, welches eine Einheit berücksichtigt. Wenn du es also in einer Subtraktion verwenden willst, musst du FLATT_VALUE ebenfalls in ein Quantity-Objekt bringen; zum Beispiel so (ungetestet):

Code: Alles auswählen

import astropy.units
FLATT_VALUE = np.arccos(np.sqrt(2/3)) * astropy.units.m
Statt operator.sub() solltest du auch einfach ein Minus verwenden können (-). Eine Wurzel im Cosinus kannst du dir sparen: sqrt(a) / sqrt(b) = sqrt(a/b). Nach Blick in deinen ersten Beitrag scheint es mir immer noch etwas strubbelig. Was hältst du davon?

Code: Alles auswählen

import numpy as np
import astropy.units
from astropy.coordinates import cartesian_to_spherical,spherical_to_cartesian

matrix = np.mgrid[ 0.01:1.1:5j, 0.01:1.1:5j, 0.01:1.1:5j]
matrix.resize(5,5,5,3)
radius, theta, phi = cartesian_to_spherical(matrix[:, 0], matrix[:, 1], matrix[:, 2])
phi += np.arccos(np.sqrt(2/3)) * astropy.units.m
matrix[:, 0], matrix[:, 1], matrix[:, 2] = spherical_to_cartesian(radius, theta, phi)
(alles ungetestet - habe kein astropy installiert).
floppy
User
Beiträge: 10
Registriert: Samstag 9. Dezember 2017, 16:24

Danke sehr. Die Hinweise wurden aufgenommen. Leider scheinen einige Punkte falsch dargestellt zu sein. Ich mache weiter. Zwischenstand unten.
Mein Ziel? die Werte einer Funktion in (x0 y0 z0) berechnen und dann diese X0 y0 z0 kippen + manipulieren um x3 y3 z3 zu haben. Dann die iso-surface der Funktionswerte über x3 y3 z3 darstellen.

Code: Alles auswählen

import plotly.graph_objects as go
import numpy as np
from scipy.spatial.transform import Rotation as Rota
from astropy.coordinates import cartesian_to_spherical,spherical_to_cartesian
from astropy.coordinates import Angle
import astropy.units as u
#
matrix0 = np.mgrid[ 0.01:1.1:5j, 0.01:1.1:6j, 0.01:1.1:7j]    # matrix0 shape= (3, 5, 5, 5)
x0, y0, z0 = np.mgrid[ 0.01:1.1:5j, 0.01:1.1:6j, 0.01:1.1:7j]  
matrix1=matrix0.reshape(3, -1).T
#
rotation = Rota.from_rotvec((np.arccos(1/np.sqrt(3))) *np.array([np.sqrt(1/2), -1*np.sqrt(1/2), 0]))   # fine
matrix2 = rotation.apply(matrix1)
#
x2,y2,z2 = matrix2[:,0],matrix2[:,1],matrix2[:,2]   #
#
radius, theta_lat_compl, phi_long = cartesian_to_spherical(x2,y2,z2)
#
FLATT_VALUE = Angle(np.arccos(np.sqrt(2/3))*u.rad)
#
theta_lat_compl -= FLATT_VALUE
#
x3,y3,z3 = spherical_to_cartesian(radius,theta_lat_compl,phi_long)
#
fig = go.Figure(data=[go.Scatter3d(x=x3.flatten(), y=y3.flatten(), z=z3.flatten(),
                                   mode='markers')])
#
fig.show()
Antworten