Форум программистов, компьютерный форум, киберфорум
Геометрия
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.96/25: Рейтинг темы: голосов - 25, средняя оценка - 4.96
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282

Как поворачивать направление движения? (Java)

13.01.2016, 16:13. Показов 4923. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть движение по осям (X, Y, Z) за 1 такт, мне надо сделать так, что-бы вектор направления повернулся на 90° по оси Х (вправо). Как это сделать?

Добавлено через 2 часа 25 минут
К примеру направление "1 0 0" (1 еденица/такт по оси Х), я хочу повернуть на 90° и должно выйти "0 1 0" (1 еденица/такт по оси Y) (Вектор направления повернулся направо (90°))
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.01.2016, 16:13
Ответы с готовыми решениями:

направление движения
Подскажите пожалуйста. Есть дуга: начальная точка дуги предположим x = 0.00000, y = 0.00000, z= 0.00000 конечная точка дуги x...

Через случайное количество тактов движения изменять направление движения
Помогите пожалуйста. Движение вдоль периметра экрана. Через случайное количество тактов движения изменять направление движения. ...

Как изменить направление движения эффекта
Здравствуйте. Есть страница ruseller.com/lessons/les2098/demo/index2.html там на картинке эффект поднимающихся шариков. Вот скрипт...

28
Эксперт по математике/физике
 Аватар для jogano
6360 / 4067 / 1512
Регистрация: 09.10.2009
Сообщений: 7,550
Записей в блоге: 4
13.01.2016, 16:33
Новые координаты будут равны
https://www.cyberforum.ru/cgi-bin/latex.cgi?\begin{pmatrix}0 & -1 & 0\\ 1 & 0 & 0\\ 0 & 0 & 1\end{pmatrix}\begin{pmatrix}X\\ Y\\ Z\end{pmatrix}=\begin{pmatrix}-Y\\ X\\ Z\end{pmatrix}
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
14.01.2016, 08:48
Школьные формулы поворота на плоскости (a - угол поворота в радианах)

x_new = x * cos(a) - y * sin(a)
y_new = y * cos(a) + x * sin(a)

В 3D - все то же самое, просто x, y (и x_new, y_new) - вектора. Если неясно откуда их взять - расскажу
0
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
14.01.2016, 22:53  [ТС]
X Y понятно, а Z?
0
Эксперт по математике/физике
 Аватар для jogano
6360 / 4067 / 1512
Регистрация: 09.10.2009
Сообщений: 7,550
Записей в блоге: 4
14.01.2016, 22:58
А что Z? Вокруг OZ вы вращаете, координата остаётся той же.
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
15.01.2016, 09:03
Цитата Сообщение от svk2140 Посмотреть сообщение
X Y понятно, а Z?
Если "на плоскости", то x, y просто числа, а z не меняется. Если же вектор скорости в пр-ве (x, y, z), то X и Y - вектора, и надо создать систему координат, иначе не определено "вокруг чего же вращать". Часто принимают ось выравнивания = мировому Y (вверх). Для этого случая

X = вектор (x, y, z) текущей скорости
wY = (0, 1, 0) направление выравнивания

Тогда

Y = cross(cross(X, wY).normalized(), X);

Где cross - векторное произведение. И подставляете вектора X, Y в формулы поворота
0
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
15.01.2016, 09:58  [ТС]
Мне нужна универсальная формула для поворота в трёхмерном пространстве.

Я знаю что найти точку на круге будет так:
X = Math.cos(a)
Z = Math.sin(a)

Для сферы будет так? (Из параметрического уравнения сферы предположение сделал):
X = Math.sin(a) * Math.cos(b)
Y = Math.sin(a) * Math.sin(b)
Z = Math.cos(a)

Может как-то определять градусы, а потом их изменять?


Просто вы мне пытаетесь намекнуть, но я математику на уровне 10 класса знаю...
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
15.01.2016, 10:51
Цитата Сообщение от svk2140 Посмотреть сообщение
Просто вы мне пытаетесь намекнуть, но я математику на уровне 10 класса знаю...
Немного "основ". На плоскости (2D) вектор можно повернуть единственным способом, поэтому просто задается угол поворота - и все. Но в 3D нужна еще ось поворота, Вам ее надо как-то определить. Понятно что для разных осей поворота рез-т будет разным. Наиболее популярный способ определения оси я Вам рассказал.

Цитата Сообщение от svk2140 Посмотреть сообщение
Мне нужна универсальная формула для поворота в трёхмерном пространстве.
Я Вам ее и дал

x_new = x * cos(a) - y * sin(a)

x и у здесь вектора (3 числа), как умножаются и вычитаются вектора Вы знаете. Как найти вектор Y - тоже рассказал. Что неясно - спрашивайте, попробую ответить

Цитата Сообщение от svk2140 Посмотреть сообщение
Для сферы будет так? (Из параметрического уравнения сферы предположение сделал):
X = Math.sin(a) * Math.cos(b)
Y = Math.sin(a) * Math.sin(b)
Z = Math.cos(a)
Это перевод из полярных координат в декартовы, оно здесь ни к чему
0
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
15.01.2016, 12:08  [ТС]
Так дело в том, что я не понимаю.

x_new = x * cos(a) - y * sin(a)
y_new = y * cos(a) + x * sin(a)

А Z тогда что? Это поворот в плоскости, если я захочу повернуть на 45° в плоскости XY и на 45° в плоскости XZ?

Так что-ли?


x_new = x * cos(a) - y * sin(a)
y_new = y * cos(a) + x * sin(a)

x_super_new = x_new * cos(b) - y * sin(b)
z_new = z * cos(b) + x_new * sin(b)

?
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
15.01.2016, 13:21
Цитата Сообщение от svk2140 Посмотреть сообщение
А Z тогда что? Это поворот в плоскости,
Знову "за рибу грошi" Уже 3 раза сказал - в пр-ве (3D) это ВЕКТОРА. Т.е.

newV.x = vecX.x * cos(a) - vecY.x * sin(a)
newV.y = vecX.y * cos(a) - vecY.y * sin(a)
newV.z = vecX.z * cos(a) - vecY.z * sin(a)
0
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
16.01.2016, 12:20  [ТС]
А, ясно

Надо было написать тогда vec1 и vec2, а то X и Y для меня неопределённо было.
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
16.01.2016, 12:25
Цитата Сообщение от svk2140 Посмотреть сообщение
А, ясно
Ну слава богу. А с вычислением vecY я немного насвистел. Правильно так

vecX = вектор (x, y, z) текущей скорости
wY = (0, 1, 0) направление выравнивания (ось вращения)

Тогда

vecY = cross(wY, vecX).normalized();

Др словами ось вращения - мировая Y (вверх)
1
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
16.01.2016, 13:00  [ТС]
Так ничего и не понял...

Так будет в итоге что-ли?

vecY = cross(wY, vecX).normalized();
newV.x = vecX.x * cos(a) - vecY.x * sin(a)
newV.z = vecX.z * cos(a) - vecY.z * sin(a)

Что-то не сходится, а если я потом захочу повернуть по оси X или Z?

Добавлено через 1 минуту
А, тогда просто изменять wY?

Добавлено через 20 секунд
Щас попробуем...
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
16.01.2016, 14:09
Цитата Сообщение от svk2140 Посмотреть сообщение
Так будет в итоге что-ли?
Да, только newV.y тоже меняется

Цитата Сообщение от svk2140 Посмотреть сообщение
Что-то не сходится, а если я потом захочу повернуть по оси X или Z?
Добавлено через 1 минуту
А, тогда просто изменять wY?
Да, но не спешите вращать по 2 и более. При повороте вектора вокруг мирового Y все 3 координаты вектора изменятся, обычно этого достаточно.

Не по теме:

Цитата Сообщение от svk2140 Посмотреть сообщение
Так ничего и не понял...
Для программиста на жабе не так уж плохо :)



Добавлено через 8 минут
Да, и надо учесть длину

vecY = cross(wY, vecX).normalized() * vecX.length();

Строго говоря, это вращение вокруг локальной оси Y, которая выбирается так чтобы быть как можно ближе к мировой
1
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
20.01.2016, 13:35  [ТС]
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        Vector3d aVec = new Vector3d();
        aVec.set(motionX, motionY, motionZ);
 
        Vector3d rVec = new Vector3d();
        rVec.set(0, 1, 0);
        
        Vector3d bVec = new Vector3d();
        bVec.cross(rVec, aVec);
        bVec.normalize();
        
        Vector3d cVec = new Vector3d();
        
        cVec.x = aVec.x * Math.cos(90) - bVec.x * Math.sin(90);
        cVec.z = aVec.z * Math.cos(90) - bVec.z * Math.sin(90);
Спасибо большое, всё сработало!
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
20.01.2016, 13:50
Цитата Сообщение от svk2140 Посмотреть сообщение
Спасибо большое, всё сработало!
А не должно , длины aVec и bVec должны быть одинаковы, после нормализации еще домножьте bVec на длину aVec. И "опять двадцать пять"

Поворот вокруг локальной оси меняет все 3 компоненты (x, y, z)

Это гарантирует что повернутый вектор (cVec) будет иметь с исходным (aVec) заданный угол поворота (у Вас 90). Это легко проверить, dot(aVec, cVec) должен быть = 0
0
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
20.01.2016, 15:07  [ТС]
Вот что наделал, но всё равно не работает

Java
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
    public static Vector3d rotateLocVectorX(double x, double y, double z, double angle)
    {
        Vector3d rotationVec = new Vector3d();
        rotationVec.set(0, 0, 1);
        
        Vector3d aVec = new Vector3d();
        aVec.set(x, y, z);
        
        Vector3d bVec = new Vector3d();
        bVec.cross(rotationVec, aVec);
        bVec.normalize();
        bVec.set(bVec.x * aVec.length(), bVec.y * aVec.length(), bVec.z * aVec.length());
                
        Vector3d cVec = new Vector3d();
        
        cVec.x = aVec.x * Math.cos(angle) - bVec.x * Math.sin(angle);
        cVec.y = aVec.y * Math.cos(angle) - bVec.y * Math.sin(angle);
        cVec.z = z;
                            
        return cVec;
    }
    
    public static Vector3d rotateLocVectorY(double x, double y, double z, double angle)
    {
        Vector3d rotationVec = new Vector3d();
        rotationVec.set(0, 1, 0);
        
        Vector3d aVec = new Vector3d();
        aVec.set(x, y, z);
        
        Vector3d bVec = new Vector3d();
        bVec.cross(rotationVec, aVec);
        bVec.normalize();
        bVec.set(bVec.x * aVec.length(), bVec.y * aVec.length(), bVec.z * aVec.length());
        
        Vector3d cVec = new Vector3d();
        
        cVec.x = aVec.x * Math.cos(angle) - bVec.x * Math.sin(angle);
        cVec.y = y;
        cVec.z = aVec.z * Math.cos(angle) - bVec.z * Math.sin(angle);
        
        return cVec;
    }
    
    public static Vector3d rotateLocVectorZ(double x, double y, double z, double angle)
    {
        Vector3d rotationVec = new Vector3d();
        rotationVec.set(1, 0, 0);
        
        Vector3d aVec = new Vector3d();
        aVec.set(x, y, z);
        
        Vector3d bVec = new Vector3d();
        bVec.cross(rotationVec, aVec);
        bVec.normalize();
        bVec.set(bVec.x * aVec.length(), bVec.y * aVec.length(), bVec.z * aVec.length());
        
        Vector3d cVec = new Vector3d();
 
        cVec.x = x;
        cVec.y = aVec.y * Math.cos(angle) - bVec.y * Math.sin(angle);
        cVec.z = aVec.z * Math.cos(angle) - bVec.z * Math.sin(angle);
 
        return cVec;
    }
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
21.01.2016, 06:28
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static Vector3d rotateLocal(Vector3d aVec, Vector3d alignAxis, double angle)
{
        Vector3d bVec = new Vector3d();
        bVec.cross(alignAxis, aVec);
        bVec.normalize();
        double len = aVec.length();
        bVec.set(bVec.x * len, bVec.y * len, bVec.z * len);
                
        double theCos = Math.cos(angle);
        double theSin = Math.sin(angle);
        
        Vector3d cVec = new Vector3d();
        cVec.x = aVec.x * theCos - bVec.x * theSin;
        cVec.y = aVec.y * theCos - bVec.y * theSin;
        cVec.z = aVec.z * theCos - bVec.z * theSin;;
                            
        return cVec;
}
Последний раз писал на жабе лет 20 назад, если где ошибся в синтаксисе - поправите. Да, и, насколько я помню, для Math.cos (sin) угол в радианах (а не в граадусах).

Если нужен поворот только на 90, то можно так

Java
1
2
3
        double len = aVec.length();
        bVec.set(-bVec.x * len, -bVec.y * len, -bVec.z * len);
        return bVec;
0
89 / 1 / 3
Регистрация: 04.07.2013
Сообщений: 282
21.01.2016, 11:59  [ТС]
Нет, не только на 90°. А вращаю я и так в радианах, Math.toRadians(90);

Попробую определять угол вектора и затем плюсововать угол.

Добавлено через 39 минут
Да нет, работает нормально, я наговариваю на вас.

Проблема в том, что вращает по мировым, а не локальным осям.

К примеру летит энтити по оси Х, что-бы повернуть направление на 90° надо повернуть по оси Y, но если она будет лететь по оси Y, то Z и X будет всегда нулю, и вращение не произойдёт.

Добавлено через 1 минуту
Надо как-то определить оси вращения, я бы мог предположить что надо изменять rotationVec у меня, но вы сказали что нельзя вращать, если в нём будет задано больше, чем 1 координата.

Добавлено через 1 минуту
1 ось вращения будет сам вектор движения, а остальные 2 надо определить, помогите пожалуйста.
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,921
Записей в блоге: 2
21.01.2016, 17:27
Цитата Сообщение от svk2140 Посмотреть сообщение
Проблема в том, что вращает по мировым, а не локальным осям.
Нет (если Вы конечно опять не пересчитали 2 координаты вместо 3)

Цитата Сообщение от svk2140 Посмотреть сообщение
К примеру летит энтити по оси Х, что-бы повернуть направление на 90° надо повернуть по оси Y, но если она будет лететь по оси Y, то Z и X будет всегда нулю, и вращение не произойдёт.
Этот случай неизбежен, он вытекает их теоремы "причесывания ежика". Есть "маленькая хитрость" (см код ниже)

Цитата Сообщение от svk2140 Посмотреть сообщение
1 ось вращения будет сам вектор движения, а остальные 2 надо определить,
Все верно, иначе не получится. Тут лучше сделать так
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static Vector3d rotateLocal(Vector3d aVec, int rotY, double angle)
{
        Vector3d bVec = new Vector3d();
        Vector3d align = new Vector3d(0.001, 1, 0.004); //  "маленькая хитрость"
        bVec.cross(align, aVec);  
        bVec.normalize();
 
        if (rotY != 0) {      
           double len = aVec.length();
           bVec.set(bVec.x * len, bVec.y * len, bVec.z * len);
        }
        else 
          bVec.cross(aVec, bVec);
 
        double theCos = Math.cos(angle);
        double theSin = Math.sin(angle);
        
        Vector3d cVec = new Vector3d();
        cVec.x = aVec.x * theCos - bVec.x * theSin;
        cVec.y = aVec.y * theCos - bVec.y * theSin;
        cVec.z = aVec.z * theCos - bVec.z * theSin;;
                            
        return cVec;
}
Так можно вращать вокруг локальной Y (rotY = 1) или др оси (rotY = 0). Ну а вращение вокруг третьей смысла не имеет т.к. это сам (вращаемый) вектор скорости, ничего не изменится
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.01.2016, 17:27
Помогаю со студенческими работами здесь

Как изменить направление движения объекта в лабиринте
Делаю игру про лабиринты win form есть поставить грибы и если ты к ним касаешся чтобы менялось направление мышки типа ты видешь мышку верх...

Найти уравнение траектории точки. Нарисовать траекторию движения точки и показать направление её движения
Материальная точка участвует одновременно в двух взаимно перпендикулярных колебаниях, выраженных уравнениями х = 2 sinωt см и у = -1...

Направление движения (круг)
Помогите сделать алгоритм GoDirection - это угол к которому нужно поворачиваться player.direction - это угол персонажа в данный момент ...

Изменить направление движения.
Не имеется идей. Корабль движется в четерёх направлениях - (север, юг, запад , восток), для него даются команды - (влево, вправо,...

Как можно просчитать траекторию движения обьекта имея направление и "возможную силу толчка"?
все знают АнгриБердс) как просчитать вот ту траекторию полета птицы?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru