Плоские уравнения в PythonPython

Программы на Python
Ответить
Anonymous
 Плоские уравнения в Python

Сообщение Anonymous »

Я создаю твердое тело в питоне (кубовидную форму) с определенной высотой, шириной, глубиной и центральным положением. Я хочу найти нормаль к каждой грани кубоида, а затем уравнения связанной плоскости для каждой. Я написал код, который, похоже, возвращает то, что я хочу, с точки зрения вектора нормали. Есть ли более эффективный способ сделать это? Я знаю, что немного невнимательно использовал матрицы, но в целом это нормально?
Мой код выглядит следующим образом. В начале я установил пару функций вращения: одну для вращения вокруг y и одну для вращения вокруг x. Следующим шагом будет объединение их в 1, просто пока не дошли руки. Затем я выделил класс твердого тела, который содержит функции, определяющие центр каждой грани, вершины каждой грани, а затем нормальное уравнение каждой грани. В настоящее время это работает: когда углы поворота равны нулю, я получаю -x для передней и задней части, -y для левого и правого и -z для верха и низа как векторы нормалей. Это хороший способ найти нормалей? Я хочу использовать это для моделирования Монте-Карло во времени, когда углы и положение меняются для каждого t
import numpy as np

def rotation_xy(theta, vector):
theta = np.radians(theta)
R = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]])
vector_rotated = np.dot(R, vector)

return vector_rotated

def rotation_xz(phi, vector):
phi = np.radians(phi)
R = np.array([[np.cos(phi), 0,np.sin(phi)], [0, 1, 0], [-np.sin(phi), 0, np.cos(phi)]])
#vector_rotated = np.dot(R, vector)
vector_rotated = np.dot(R, vector)

return vector_rotated

class paddle():
def __init__(self, height, width, depth, centre, theta = 0, phi = 0):
self.height = height
self.width = width
self.depth = depth
self.centre = centre
self.theta = theta
self.phi = phi

self.faces = self.calculate_faces()

def calculate_faces(self):
"""
Calculate the plane equations for each face
"""
half_width = self.width/2
half_height = self.height/2
half_depth = self.depth/2

face_offsets = {
"front": np.array([half_depth, 0, 0]),
"back": np.array([-half_depth, 0, 0]),
"left": np.array([0, -half_width, 0]),
"right": np.array([0, half_width, 0]),
"top": np.array([0, 0, half_height]),
"bottom": np.array([0, 0, -half_height]),
}

plane_equations = {}
for face_name, offset in face_offsets.items():
# Get the four vertices for the current face dynamically
corners = self.get_face_vertices(offset, half_width, half_height, half_depth)
# Calculate the normal vector and D value in Ax + By + Cz + D = 0
normal_vector, D = self.get_normal_and_D(corners, self.theta, self.phi)
plane_equations[face_name] = (normal_vector, D)
return plane_equations

def get_face_vertices(self, offset, half_width, half_height, half_depth):
"""
Calculate the 4 vertices of the selected face
Uses the face offset to determine these
If offset is non-zeo in x, then vertices are at constant x, changing y and z
-> Done dynamically through matrices
for example, for the front face the offset matrix is
[0 ,0 ,0]
[0 ,+/-1 ,0]
[0 ,0 ,+/-1]
"""
face_array = np.array([half_width, half_height, half_depth])
non_zero_indices = np.where(offset !=0)[0] # offset indices that are non-zero
zero_indices = np.where(offset == 0)[0] # offset indices that are zero
offset_matrix = np.eye(3)
offset_matrix[non_zero_indices,: ] = 0
start = self.centre
corners = []
corners.append(start + np.dot(face_array, (offset_matrix * -np.eye(3))))
corners.append(start + np.dot(face_array, offset_matrix))
for a in zero_indices:
offset_matrix = np.eye(3)
offset_matrix[non_zero_indices,: ] = 0
offset_matrix[a,a] = -1
corners.append(start + np.dot(face_array, offset_matrix))
return corners

def get_normal_and_D(self, vertices, theta, phi):
"""
Calculate the normal vector and D value for the plane equation.
Uses the first 3 vertices to compute the normal.
"""
# Get two vectors from the vertices
v1 = vertices[1] - vertices[0] # Vector from corner 1 to corner 2
v2 = vertices[3] - vertices[0] # Vector from corner 1 to corner 4
v1, v2 = rotation_xy(theta, v1), rotation_xz(theta, v2) # rotate around z axis
v1, v2 = rotation_xz(phi, v1), rotation_xz(phi, v2) # rotate around y axis
normal_vector = np.cross(v1, v2) # Cross product to get normal vector
normal_vector = normal_vector / np.linalg.norm(normal_vector) # Normalize the vector

# Calculate D for the plane equation: Ax + By + Cz + D = 0
D = -np.dot(normal_vector, self.centre)

return normal_vector, D

paddle = paddle(height=1, width=0.1, depth=0.04, centre=np.array([0, 0, 0]))
plane_equations = paddle.calculate_faces()
for face, (normal, D) in plane_equations.items():
print(f"Plane equation for {face} face: {normal[0]}x + {normal[1]}y + {normal[2]}z + {D}")
print(normal)



Подробнее здесь: https://stackoverflow.com/questions/793 ... -in-python
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»