Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.03.2021, 21:10   #1
_human_
Пользователь
 
Регистрация: 15.02.2021
Сообщений: 10
По умолчанию Numpy, неправильно поворачивается вектор.

Мне нужна была функция, поворачивающая вектор в 3д пространстве. Получилось вот это:
Код:
def turn(xy, xz, vect):
    xy, xz = np.radians(xy), np.radians(xz)
    a = vect.vect.copy()
    vect.vect[0] = a[0]*np.cos(xy) - a[1]*np.sin(xy)
    vect.vect[1] = a[0]*np.sin(xy) + a[1]*np.cos(xy)    
    a = vect.vect.copy()
    vect.vect[0] = a[0]*np.cos(xz) + a[2]*np.sin(xz)
    vect.vect[2] = -a[0]*np.sin(xz) + a[2]*np.cos(xz)    
#    print(np.degrees(xy), ': ', vect._len())
#    print(np.degrees(xy), ': ', vect.vect)
(функция turn)
Но, как видно, если запустить код, что вектор поворачивается неправильно.
Код:
Код:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()

class vector3D:
    vect = np.float32(np.array([0, 0, 0]))
    def __init__(self, vect):
        if list == type(vect):
            self.vect = np.float32(np.array(vect))
        else:
            print("!!!WARNING!!!", vect, "isn't a vector (it must be list). The default null vector is taken as the value")
    def __add__(self, vect2):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] + vect2.vect[0]
        vector_rezult[1] = self.vect[1] + vect2.vect[1]
        vector_rezult[2] = self.vect[2] + vect2.vect[2]
        return vector3D(vector_rezult)
    def __sub__(self, vect2):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] - vect2.vect[0]
        vector_rezult[1] = self.vect[1] - vect2.vect[1]
        vector_rezult[2] = self.vect[2] - vect2.vect[2]
        return vector3D(vector_rezult)
    def __mul__(self, chislo):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] * chislo
        vector_rezult[1] = self.vect[1] * chislo
        vector_rezult[2] = self.vect[2] * chislo
        return vector3D(vector_rezult)
    def __truediv__(self, chislo):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] / chislo
        vector_rezult[1] = self.vect[1] / chislo
        vector_rezult[2] = self.vect[2] / chislo
        return vector3D(vector_rezult)
    def __radd__(self, vect2):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] + vect2.vect[0]
        vector_rezult[1] = self.vect[1] + vect2.vect[1]
        vector_rezult[2] = self.vect[2] + vect2.vect[2]
        return vector3D(vector_rezult)
    def __rsub__(self, vect2):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] - vect2.vect[0]
        vector_rezult[1] = self.vect[1] - vect2.vect[1]
        vector_rezult[2] = self.vect[2] - vect2.vect[2]
        return vector3D(vector_rezult)
    def __rmul__(self, chislo):
        vector_rezult = [None, None, None]
        vector_rezult[0] = self.vect[0] * chislo
        vector_rezult[1] = self.vect[1] * chislo
        vector_rezult[2] = self.vect[2] * chislo
        return vector3D(vector_rezult)
    def _len(self):
        rezult = np.sqrt(self.vect[0]**2 + self.vect[1]**2 + self.vect[2]**2)
        return rezult

class point:
    def __init__(self, m, coord, V):
        self.m = m
        self.V = vector3D(V)
        self.coord = vector3D(coord)
        
class sphere(point):
    def __init__(self, R, m, coord, V):
        point.__init__(self, m, coord, V)
        self.R = R
    def point_in_sphere(self, Point):
        if len_vector(Point.coord - self.coord) <= self.R:
            return True
        else:
            return False

class physic:
    def __init__(self, objects):
        self.G = 6.6743015 * 10**(-11)
        self.objects = objects
    def gravity(self, m1, m2, r):
        F = (self.G * m1 * m2 * r)/(len_vector(r) ** 3)
        return F
    def delta_V(self, V, F, m, FPStime):
        V = V + (F/m) * FPStime
        return V
    def delta_coord(self, coord, V, FPStime):
        coord = coord + V * FPStime
        return coord
    def update(self):
        pass

def turn(xy, xz, vect):
    xy, xz = np.radians(xy), np.radians(xz)
    a = vect.vect.copy()
    vect.vect[0] = a[0]*np.cos(xy) - a[1]*np.sin(xy)
    vect.vect[1] = a[0]*np.sin(xy) + a[1]*np.cos(xy)    
    a = vect.vect.copy()
    vect.vect[0] = a[0]*np.cos(xz) + a[2]*np.sin(xz)
    vect.vect[2] = -a[0]*np.sin(xz) + a[2]*np.cos(xz)    
#    print(np.degrees(xy), ': ', vect._len())
#    print(np.degrees(xy), ': ', vect.vect)
    graph1 = plt.plot([0, vect.vect[0]], [0, vect.vect[1]])
    
a = vector3D([10, 0, 0])

for i in np.arange(0, 10, 0.1):
    turn(i, 0, a)
grid1 = plt.grid(True)
plt.show()
Я не понимаю, почему неправильно считается поворот, так как матрицы, по которой составлялись уравнения (поворот вокруг оси z и вокруг оси y) верны. Синусы/косинусы считаются правильно, а результат получается неправильным.
_human_ вне форума Ответить с цитированием
Старый 17.03.2021, 05:56   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Из-за того, что "крутится" один и тот же вектор, то получилось не 100 векторов с шагом между ними 0.1 градус (от 0 до 10 градусов), а первый вектор - 0 градусов, второй - 0.1, третий - 0.3, четвертый - 0.6 и т.д., последний ~ 505 градусов.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 17.03.2021, 14:54   #3
_human_
Пользователь
 
Регистрация: 15.02.2021
Сообщений: 10
По умолчанию

Надо же! А сейчас верно считается... А то я столько раз проверял один поворот на 90 градусов (то, что я забыл, что поворачиваю тот же самый вектор, не влияло в этом случае). Получалось всё время [10, 10, 0]. А сейчас считается правильно [0, 10, 0]...
_human_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Numpy, ошибка, при возведении массива в квадрат. VeryStupidPerson Python 2 15.02.2021 19:40
ошибка 'numpy.ndarray' object is not callable VeryStupidPerson Python 5 16.11.2020 18:19
Разобраться в задачке. Определить вектор скорости, вектор ускорения материальной точки? Mat Bourn Помощь студентам 4 24.12.2019 12:04
NumPy и чтение/запись массива в файл ViktorR Python 8 08.09.2018 15:40
matplotlib, numpy и чтение / запись CSV-фалов ViktorR Python 1 26.06.2017 10:15