Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
5 / 4 / 1
Регистрация: 14.02.2018
Сообщений: 583
1

Поворот 3D вектора

07.05.2019, 17:54. Показов 5012. Ответов 29
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите пожалуйста, как исправить можно?

Входные данные:
1. 3D - координаты вектора.
2. Угол поворота в радианах.
3. Трехмерные координаты точки оси.
4. Трехмерные координаты вектора направления оси.
Длина вектора направления больше 1e-8.
Выход:
трехмерные координаты вектора после его вращения.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
 
using namespace std;
 
int main() {
    double points[3];
    double rotationMatrix[3][4];
    double inputMatrix[3][1] = { 0.0,0.0,0.0 };
    double outputMatrix[3][1] = { 0.0,0.0,0.0 };
    double angle;
    double a,b,c,u, v, w;
    cin >> points[0]>> points[1] >> points[2] >> angle >> a >> b >> c >> u >> v >> w;
    inputMatrix[0][0] = points[0];
    inputMatrix[1][0] = points[1];
    inputMatrix[2][0] = points[2];
    double L = (pow(u, 2) + pow(v, 2) + pow(w, 2));
    double u2 = u * u;
    double v2 = v * v;
    double w2 = w * w;
    rotationMatrix[0][0] = (cos(angle) + (1 - cos(angle)) * u2);
    rotationMatrix[0][1] = (u * v * (1 - cos(angle)) + w * sin(angle));
    rotationMatrix[0][2] = (u * w * (1 - cos(angle)) - v * sin(angle));
    rotationMatrix[1][0] = (u * v * (1 - cos(angle)) - w * sin(angle));
    rotationMatrix[1][1] = (cos(angle) + v2 * (1 - cos(angle)));
    rotationMatrix[1][2] = (v * w * (1 - cos(angle)) + u * sin(angle));
    rotationMatrix[2][0] = (u * w * (1 - cos(angle)) + v * sin(angle));
    rotationMatrix[2][1] = (v * w * (1 - cos(angle)) - u * sin(angle));
    rotationMatrix[2][2] = (cos(angle) + (1 - cos(angle))*w2);
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 1; j++) {
            outputMatrix[i][j] = 0;
            for (int k = 0; k < 3; k++) {
                outputMatrix[i][j] += rotationMatrix[i][k] * inputMatrix[k][j];
            }
        }
    }
    cout << outputMatrix[0][0] << " " << outputMatrix[1][0] << " " << outputMatrix[2][0];
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.05.2019, 17:54
Ответы с готовыми решениями:

Поворот двумерного вектора на 45 градусов
Нашел решение близко похожее на нужное, но поворот происходит на 90 градусов. Сначала решил по...

Поворот трехмерного вектора в заданной плоскости
Доброго времени суток. Задача: Даны два трехмерных вектора - A и B. Данные вектора ортгональны...

Поворот вектора на заданный угол в двумерном пространстве
Поворот заданного вектора на заданный угол в двумерном пространстве. Входными данными являются три...

А есть ли здесь функция поворот вектора вокруг вектора?
Задача пересчитать вектор с учётом поворота. Есть шар, заменяющий геоид, координаты камеры,...

29
330 / 145 / 56
Регистрация: 17.10.2015
Сообщений: 580
07.05.2019, 20:19 21
Author24 — интернет-сервис помощи студентам
ElKros, да, согласно скрину матрицы поворота, который я кидал
0
5 / 4 / 1
Регистрация: 14.02.2018
Сообщений: 583
07.05.2019, 20:29  [ТС] 22
Krokodil9798,
C++
1
2
3
4
5
6
7
8
9
10
11
12
double u = normal.x, v = normal.y, w = normal.z;
double u2 = pow(u, 2), v2 = pow(v, 2), w2 = pow(w, 2);
double rotationMatrix[3][3];
rotationMatrix[0][0] = (cos(angle) + (1 - cos(angle)) * u2);
rotationMatrix[0][1] = (u * v * (1 - cos(angle)) + w * sin(angle));
rotationMatrix[0][2] = (u * w * (1 - cos(angle)) - v * sin(angle));
rotationMatrix[1][0] = (u * v * (1 - cos(angle)) - w * sin(angle));
rotationMatrix[1][1] = (cos(angle) + v2 * (1 - cos(angle)));
rotationMatrix[1][2] = (v * w * (1 - cos(angle)) + u * sin(angle));
rotationMatrix[2][0] = (u * w * (1 - cos(angle)) + v * sin(angle));
rotationMatrix[2][1] = (v * w * (1 - cos(angle)) - u * sin(angle));
rotationMatrix[2][2] = (cos(angle) + (1 - cos(angle))*w2);
тогда не работает...

Добавлено через 1 минуту
Krokodil9798,
3.0 2.0 4.0 3.141592653 0.0 0.0 0.0 0.0 1.0 0.0
выводит:
0 0.00475624 0
0
330 / 145 / 56
Регистрация: 17.10.2015
Сообщений: 580
07.05.2019, 20:30 23
del
0
5 / 4 / 1
Регистрация: 14.02.2018
Сообщений: 583
07.05.2019, 20:31  [ТС] 24
Krokodil9798, ?
0
330 / 145 / 56
Регистрация: 17.10.2015
Сообщений: 580
07.05.2019, 20:33 25
Цитата Сообщение от ElKros Посмотреть сообщение
?
Попробуйте проверить правильность составления матрицы. Код должен работать, ошибки в алгоритме я не наблюдаю.
0
5 / 4 / 1
Регистрация: 14.02.2018
Сообщений: 583
07.05.2019, 20:33  [ТС] 26
Krokodil9798, я заполнила матрицу согласно вашему скрину, хотя также было изначально задано, но на всякий случай перепроверила.
пробовала брать
C++
1
double u = normal.x, v = normal.y, w = normal.z;
и вместо normal.x ... брала vector.x ... ни при одном из этих вариантов не работало
0
330 / 145 / 56
Регистрация: 17.10.2015
Сообщений: 580
07.05.2019, 20:35 27
Ааааа, cos и sin принимает значения в градусах. 1 рад = 180/π. Переведите введённое значение угла поворота в градусы.
0
5 / 4 / 1
Регистрация: 14.02.2018
Сообщений: 583
07.05.2019, 20:41  [ТС] 28
Krokodil9798, после перевода из радиан в градусы:
3.0 2.0 4.0 3.141592653 0.0 0.0 0.0 0.0 1.0 0.0
1.17134 0.806881 1.65053
а должно -3 2 -4
0
330 / 145 / 56
Регистрация: 17.10.2015
Сообщений: 580
07.05.2019, 21:28 29
ElKros,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <cmath>
#include <iomanip>
 
struct bad_index {};
 
struct Point3D
{
    double x, y, z;
 
    double& operator[](int index)
    {
        if (index == 0)
            return x;
        else if (index == 1)
            return y;
        else if (index == 2)
            return z;
        else
            throw bad_index();
    }
};
 
int main() {
    Point3D vector;
    Point3D center;
    Point3D normal;
    double angle;
 
    //Считываем
    std::cin >> vector.x >> vector.y >> vector.z >> angle >> center.x >> center.y >> center.z >> normal.x >> normal.y >> normal.z;
 
    //Нормализируем вектор
    const double length = std::pow(vector.x, 2) + std::pow(vector.y, 2) + std::pow(vector.z, 2);
    normal.x /= length;
    normal.y /= length;
    normal.z /= length;
 
    //Матрица поворота
    const int rows = 3, cols = 3;
    double x = normal.x, y = normal.y, z = normal.z;
    double x2 = pow(x, 2), y2 = pow(y, 2), z2 = pow(z, 2);
 
    double rotationMatrix[rows][cols];
    rotationMatrix[0][0] = (cos(angle) + (1 - cos(angle)) * x2);
    rotationMatrix[0][1] = (x * y * (1 - cos(angle)) - z * sin(angle));
    rotationMatrix[0][2] = (x * z * (1 - cos(angle)) + y * sin(angle));
    rotationMatrix[1][0] = (x * y * (1 - cos(angle)) + z * sin(angle));
    rotationMatrix[1][1] = (cos(angle) + y2 * (1 - cos(angle)));
    rotationMatrix[1][2] = (y * z * (1 - cos(angle)) - x * sin(angle));
    rotationMatrix[2][0] = (x * z * (1 - cos(angle)) - y * sin(angle));
    rotationMatrix[2][1] = (y * z * (1 - cos(angle)) + x * sin(angle));
    rotationMatrix[2][2] = (cos(angle) + (1 - cos(angle))*z2);
 
    //Переносим в точку вращения
    vector.x -= center.x;
    vector.y -= center.y;
    vector.z -= center.z;
 
    //Умножаем матрицу на вектор
    Point3D temp{0, 0, 0};
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            temp[i] += rotationMatrix[i][j] * vector[j];
    vector = temp;
 
    //Перемещаемся обратно
    vector.x += center.x;
    vector.y += center.y;
    vector.z += center.z;
 
    std::cout.setf(std::ios::fixed, std::ios::floatfield);
    std::cout << std::setprecision(1) << vector.x << " " << vector.y << " " << vector.z;
    system("pause");
}
И Вы, и я были неправы. Вы - потому, что матрицу всё-таки неправильно записали. Я - потому, что позор так делать умножение матрицы и вектора, как я делал.
Теперь всё работает, как нужно.

Добавлено через 5 минут
Цитата Сообщение от ElKros Посмотреть сообщение
а должно -3 2 -4
Учтите, ответ у Вас неверный. Должно -3 -2 -4. Потому, что ось поворота - Y, направлена вертикально вверх. Угол поворота - 3.14, равен Pi - полукругу.

Добавлено через 31 секунду
А значит, вектор просто изменит направление на противоположное.
0
6105 / 3460 / 1405
Регистрация: 07.02.2019
Сообщений: 8,790
07.05.2019, 21:33 30
ElKros, поскольку center в задаче не нужен, я его использовал как результат ( лень писать было ), вот код на базе того что Krokodil9798 написал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cmath>
 
struct Point3D
{
    double x, y, z;
};
 
int main() {
    Point3D vector;
    Point3D center;
    Point3D normal;
    double angle;
 
    //Считываем
    std::cin >> vector.x >> vector.y >> vector.z >> angle >> center.x >> center.y >> center.z >> normal.x >> normal.y >> normal.z;
 
    //Нормализируем вектор
    const double length = std::pow(normal.x, 2) + std::pow(normal.y, 2) + std::pow(normal.z, 2);
    normal.x /= length;
    normal.y /= length;
    normal.z /= length;
 
    //Матрица поворота
    const int rows = 3, cols = 3;
    double rotationMatrix[rows][cols]
    {
        {(cos(angle) + (1-cos(angle))*normal.x*normal.x), ((1 - cos(angle))*normal.x*normal.y - sin(angle)*normal.z), ((1 - cos(angle))*normal.x*normal.z + sin(angle)*normal.y)},
        {((1 - cos(angle))*normal.x*normal.y + sin(angle)*normal.z), (cos(angle) + (1 - cos(angle))*normal.y*normal.y), ((1 - cos(angle))*normal.y*normal.z - sin(angle)*normal.x)},
        {((1 - cos(angle))*normal.x*normal.z - sin(angle)*normal.y), ((1 - cos(angle))*normal.z*normal.y + sin(angle)*normal.x), (cos(angle) + (1 - cos(angle))*normal.z*normal.z)}
    };
    /*
    //Переносим в точку вращения
    vector.x -= center.x;
    vector.y -= center.y;
    vector.z -= center.z;
    */
    //Умножаем матрицу на вектор
    center.x = rotationMatrix[0][0] * vector.x + rotationMatrix[0][1] * vector.y + rotationMatrix[0][2] * vector.z;
    center.y = rotationMatrix[1][0] * vector.x + rotationMatrix[1][1] * vector.y + rotationMatrix[1][2] * vector.z;
    center.z = rotationMatrix[2][0] * vector.x + rotationMatrix[2][1] * vector.y + rotationMatrix[2][2] * vector.z;
 
    /*
    //Перемещаемся обратно
    vector.x += center.x;
    vector.y += center.y;
    vector.z += center.z;
    */
    std::cout << center.x << " " << center.y << " " << center.z;
    system("pause");
}
0
07.05.2019, 21:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.05.2019, 21:33
Помогаю со студенческими работами здесь

Поворот вектора
Всем доброго времени суток! Есть тело в пространстве с определенной нормалью (нормальный вектор),...

Поворот вектора
Здравствуйте. Есть вектор A{x,y,z} и вектор А'=M*A, где М - матрица поворота вокруг оси ОХ на 30...

Поворот вектора
известны начальные и конечные координаты вектора...необходимо направить его в противоположную...

Поворот вектора по кватерниону
судя по гуглу - заезженная тема, но.. но я убил грёбанных полтора дня, перепробовал n методов:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru