» Blog » Mechanika » Programowanie obiektowe: Obiekty Vector3D i Matrix4D

Programowanie obiektowe: Obiekty Vector3D i Matrix4D

Pisanie skryptów w środowisku Mechanical nie musi ograniczać się do prostej automatyzacji czynności niezbędnych do wykonania analizy MES. Dzięki narzędziom takim jak np. ResultReader możemy uzyskać dostęp do surowych wyników w pliku RST i przetworzyć wyniki w sposób specyficzny dla naszych potrzeb, co zwykle wymaga implementacji szeregu funkcji matematycznych. Niniejszy artykuł przybliży dwa zaimplementowane w Mechanical API obiekty, których wykorzystanie pozwoli zaoszczędzić nieco czasu: Vector3D i Matrix4D.

Z uwagi na zakres zagadnienia, artykuł został podzielony na 3 części, z których każda porusza kolejny etap pracy:

Część I – Obiekty Vector3D i Matrix4D

Część II – Transformacja koordynat do lokalnego układu współrzędnych: pełen opis przykładu kodu transformującego koordynaty punktu 3D do lokalnego układu współrzędnych z wykorzystaniem opisanych wcześniej obiektów Vector3D i Matrix4D.

Część III – Odczyt danych z pliku RST i transformacja tensora naprężeń: opisuje proces odczytu danych z pliku RST (na bazie elementów powłokowych) oraz ich transformacji do lokalnego układu współrzędnych z wykorzystaniem obiektów Vector3D i Matrix4D.

Obiekty Vector3D i Matrix4D

Krótkie wprowadzenie do programowania obiektowego – jak je tworzyć i jak z nich korzystać.

  1. Programowanie obiektowe 101
  2. Obiekt Vector3D
  3. Obiekt Matrix4D

Programowanie obiektowe 101

Aby dobrze zrozumieć i efektywnie wykorzystać obiekty Vector3D i Matrix4D musimy zacząć od krótkiego wprowadzenia do programowania obiektowego. Większość użytkowników pisze skrypty w formie funkcji, które automatyzują pewne procesy. Potoczna nazwa „skryptu” lub „procedury” idealnie oddaje naturę takiego podejścia. Kolejne czynności następują po sobie, czasem z wykorzystaniem pętli lub instrukcji warunkowych. Każdy użytkownik, który zna definicję obiektu i klasy oraz rozumie różnicę pomiędzy metodą oraz metodą statyczną może pominąć poniższy akapit i przejść do sedna artykułu, czyli pracy z obiektami Vector3D i Matrix4D.

Każdy obiekt jest tworzony w oparciu o definicję (klasę). Tworzenie obiektu określamy mianem inicjalizacji. Aby korzystać z metod i własności obiektu, musimy go utworzyć korzystając z konstruktora. Robimy to pisząc nazwę klasy, a następnie podając określone argumenty (w nawiasach zaraz po nazwie klasy):

v = Vector3D(1,1,1)

Niektóre obiekty nie wymagają argumentów podczas inicjalizacji, po inicjalizacji obiektu możemy korzystać z funkcji i własności dostępnych dla danego obiektu:

reader = ResultReader()
reader.GetData()

Niektóre klasy posiadają definicje metod i własności, które nie wymagają inicjalizacji obiektu, tzw. metody i własności statyczne. Korzystamy z nich poprzez wpisanie nazwy klasy, a następnie funkcji lub własności, której chcemy użyć (bez nawiasów, nazwa metody lub własności bezpośrednio po kropce). Metody statyczne mogą również przyjmować argumenty:

v = Vector3D.Dot(v1,v2)

Powyższy przykład obrazuje wykorzystanie statycznej metody do obliczenia iloczynu skalarnego dwóch wektorów. Metoda Dot przyjmuje dwa argumenty (wektory v1 i v2) oraz zwraca iloczyn skalarny przypisany do zmiennej v.

Poniższy przykład obrazuje utworzenie dwóch wektorów oraz obliczenie iloczynu skalarnego na dwa sposoby: z wykorzystaniem metody obiektu oraz metody statycznej.

v1 = Vector3D(10,10,10)
v2 = Vector3D(5,5,5)
#metoda obiektu
dot1 = v1.DotProduct(v2)
print(dot1)
#150
#metoda statyczna

dot2 = Vector3D.Dot(v1, v2)
print(dot2)
#150

Obiekt Vector3D

Vector3D jest obiektem pozwalającym na łatwą definicję wektora w przestrzeni 3D. Konstruktor wymaga trzech koordynat punktu. Obiekt ten jest wykorzystywany w definicji niektórych obiektów drzewa np. CoordinateSystem.PrimaryAxisDirection, Graphics.Camera.ViewVector.

Vector3D pozwala na wykonywanie operacji na wektorach oraz obliczanie ich własności. Dostępne są metody, metody statyczne oraz operatory. Poniższe przykłady obrazują kilka operacji na wektorach z wykorzystaniem różnych metod:

a) Suma wektorowa – metoda

v1 = Vector3D(10,10,10)
v2 = Vector3D(2,2,2)
v1.Add(v2)
print(v1)
#(12,12,12)

b) Suma wektorowa – operator

v1 = Vector3D(10,10,10)
v2 = Vector3D(2,2,2)
v3 = v1+v2
print(v3)
#(12,12,12)

c) Wielkość

v1 = Vector3D(10,10,10)
print(v1.Magnitude)
#17.3205080757

d) Normalizacja

v1 = Vector3D(10,10,10)
v1.Normalize()
print(v1)
#(0.577350269189626, 0.577350269189626, 0.577350269189626)

e) Odległość pomiędzy dwoma wektorami (metoda statyczna)

v1 = Vector3D(10,10,10)
v2 = Vector3D(2,2,2)
d = Vector3D.GetDistance(v1,v2)
print(d)
#13.8564064606

Używanie klasy jest proste i intuicyjne. Należy zwracać uwagę na podpowiedzi, aby prawidłowo wybrać funkcję. Niektóre metody np. Normalize są oznaczone jako void. Oznacza to, że funkcja nic nie zwraca, a jedynie wykonuje pewne operacje zmieniając nasz obiekt. Inne metody np. CrossProduct wymagają podania argumentu i zwracają nowy obiekt (w tym przypadku wektor).

Obiekt Matrix4D

Obiekt Matrix4D reprezentuje macierz 4×4 pomocną w transformacjach koordynat oraz tensora naprężeń. Podobnie jak Vector3D udostępnia metody, własności oraz metody statyczne. Poniższa lista nie jest wyczerpująca, zachęcam do samodzielnego zapoznania się ze wszystkimi oferowanymi funkcjami.

Najprostszą metodą na utworzenie macierzy jest wywołanie konstruktora, który utworzy macierz jednostkową. Klasa posiada również statyczną macierz jednostkową (Identity) należy jednak uważać, gdyż przypisanie jej do zmiennej, a następnie modyfikacja powoduje, że modyfikujemy wzorcową macierz jednostkową, a nie jej kopię.

m = Matrix4D()
print(m)
#| 1, 0, 0, 0 |
#| 0, 1, 0, 0 |
#| 0, 0, 1, 0 |
#| 0, 0, 0, 1 |

print(d)
#13.8564064606

Tak utworzoną macierz możemy modyfikować używając indeksów (wiersz, kolumna):

m[0,0] = 10
m[1,3] = 10
print(m)
#| 10, 0, 0, 0 |
#| 0, 1, 0, 10 |
#| 0, 0, 1, 0 |
#| 0, 0, 0, 1 |

Klasa posiada konstruktor pozwalający na utworzenie macierzy w oparciu o wektory (wektor -> kolumna):

m1 = Matrix4D.CreateSystem(
Vector3D(1,0,0),
Vector3D(2,1,0),
Vector3D(3,1,1))
print(m1)
#| 1, 2, 3, 0 |
#| 0, 1, 1, 0 |
#| 0, 0, 1, 0 |
#| 0, 0, 0, 1 |

m2 = Matrix4D.CreateSystem(
Vector3D(1,0,0),
Vector3D(0,1,0),
Vector3D(2,2,1)
print(m2)
#| 1, 0, 2, 0 |
#| 0, 1, 2, 0 |
#| 0, 0, 1, 0 |
#| 0, 0, 0, 1 |

Implementacja operatorów pozwala na wykonywanie operacji na macierzach:

m3 = m1+m2
print(m3)
#| 2, 2, 5, 0 |
#| 0, 2, 3, 0 |
#| 0, 0, 2, 0 |
#| 0, 0, 0, 2 |

m4 = m1*m2
print(m4)
#| 1, 2, 9, 0 |
#| 0, 1, 3, 0 |
#| 0, 0, 1, 0 |
#| 0, 0, 0, 1 |

Macierz można transponować, ale należy pamiętać, że operacja jest wykonywana na obiekcie:

m4.Transpose()
print(m4)
#| 1, 0, 0, 0 |
#| 2, 1, 0, 0 |
#| 9, 3, 1, 0 |
#| 0, 0, 0, 1 |

Wyznacznik macierzy dostępny jest jako własność:

print(M4.Determinant)
#1

Klasa umożliwia utworzenie macierzy translacyjnej w oparciu o trzy koordynaty:

v = Vector3D(0,0,0)
m = Matrix4D.CreateTranslate(10,10,10)
print(m)
#| 1, 0, 0, 10 |
#| 0, 1, 0, 10 |
#| 0, 0, 1, 10 |
#| 0, 0, 0, 1 |

v2 =m.Transform(v)
print(v2)
#(10, 10, 10)

Na podstawie osi i kąta obrotu możemy utworzyć macierz obrotu. Poniższy przykład przedstawia obrót wektora reprezentującego oś X (1,0,0) o 90 stopi względem osi Y (0,1,0). W ten sposób, zmieniamy oś X na oś Z (0,0,1).

import math
m = Matrix4D.CreateRotate(Vector3D(0,1,0), math.radians(90))
print(m)
#| 2.22044604925031E-16, 0, -1, 0 |
#| 0, 1, 0, 0 |
#| 1, 0, 2.22044604925031E-16, 0 |
#| 0, 0, 0, 1 |

v = Vector3D(1,0,0)
v2 = m.Transform(v)
print(v2)
#(2.22044604925031E-16, 0, 1)

Autor: Bartosz Płochocki, MESco sp. z o.o.

Zainteresował Cię temat? Zobacz nasze szkolenia poświęcone skryptowaniu na poziomie podstawowym i zaawansowanym.