Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2007.09.16;
Скачать: [xml.tar.bz2];

Вниз

Углы поворота   Найти похожие ветки 

 
alpha5 ©   (2006-10-07 15:34) [0]

Привет всем! У меня такая проблема. Я программирую, используя средства OpenGL на Delphi 7.
У меня есть сфера радиусом 1. На ней есть какая-то произвольная точка (x; y; z). И вот эту вот произвольную точку мне надо повернуть лицом к наблюдателю, т. е. в координату (0; 0; 1). Т. е. здесь получается, что надо найти угол поворота по OX, по OY и по OZ. Пробовал использовать формулы направляющих углов:
 d := sqrt(x * x + y * y + z * z);
 alpha := ArcCos( x / d);  // угол по OX
 beta :=  ArcCos( y / d);  // угол по OY
 gamma := ArcCos( z / d);  // угол по OZ

Потом я перевёл их в градусную меру измеренния углов и присвоил их:
glRotatef(alpha, 1, 0, 0);  // поворот вокруг оси OX
 glRotatef(beta, 0, 1, 0);  // поворот вокруг оси OY
 glRotatef(gamma , 0, 0, 1);  // поворот вокруг оси OZ

Не получилось.

Так как же мне найти эти углы?


 
@!!ex ©   (2006-10-07 16:10) [1]

Маненьникй такой ньюансик.....
Вращать нужно только по двум углам....

В своем проекте реализовывал вращение геосферы аля X-Com.
Если интересно, могу дать ссылку... Около 5 мегабайт...


if wx>=0 then
xChange:=Round(arcsin(abs(wx)/sqrt(sqr(radius)-sqr(wy)))/PI*180)
else
xChange:=-Round(arcsin(abs(wx)/sqrt(sqr(radius)-sqr(wy)))/PI*180);

if wy>=0 then
yChange:=Round(arcsin(abs(wy)/sqrt(sqr(radius)-sqr(wx)))/PI*180)
else
yChange:=-Round(arcsin(abs(wy)/sqrt(sqr(radius)-sqr(wx)))/PI*180);


Где wx,wy - координаты точки которую нужно центрировать.

Вращение соответственно по осям:


 glRotate(YRotate,1,0,0);
 glRotate(XRotate,0,0,1);


У меня все прекрасно работает.


 
alpha5 ©   (2006-10-07 18:16) [2]

Что-то у меня не заработало.

Вы имели в виду, что

XRotate:= xChange
YRotate:= yChange


Пробую, не получается.
А куда тогда делась координата Z, ведь точка определяется тремя координатами (x, y, z)?
У вас получается, что

wx := x;
wy := y;


А куда делась Z?
Не пойму, в чём тут загвоздка.

А насчёт ссылки, то давайте. Очень даже пригодится.


 
alpha5 ©   (2006-10-07 18:24) [3]

Кстати, попытался переставить углы поворота
glRotatef(...);
- всё равно не работает


 
@!!ex ©   (2006-10-07 21:26) [4]

Не помню математического обоснования данных формул(помню что парился целый вечер), вполне допускаю, что оно не корректно.... Но у меня работает. тьфу-тьфу-тьфу.

http://afera-net.narod.ru/UAM.rar 3 465 КБ

После запуска переключись в режми 3Д. Вращение правой кнопой(Как раз здесь учавствует приведенный выше код. ПРи нажатии мыши берется координата на сфере и по ней центрируется).


 
alpha5 ©   (2006-10-07 22:39) [5]

Спасибо

кстати может проблема в том что расположение кода

glRotatef(alpha, 1, 0, 0);  // поворот вокруг оси OX
glRotatef(beta, 0, 1, 0);  // поворот вокруг оси OY
glRotatef(gamma , 0, 0, 1);  // поворот вокруг оси OZ

и

glRotatef(gamma , 0, 0, 1);  // поворот вокруг оси OZ
glRotatef(alpha, 1, 0, 0);  // поворот вокруг оси OX
glRotatef(beta, 0, 1, 0);  // поворот вокруг оси OY

Уже совсем разные вещи.
Только что узнал.

А как вы проверяли выделения объекта мышью, т.е. по двумерным координатам мыши определить 3-мерные, на которые сейчас направлен курсор мыши?


 
@!!ex ©   (2006-10-08 11:06) [6]


> Уже совсем разные вещи.
> Только что узнал.

Мммм.... Ну вроде перемножение матриц не комутативно....
А всё 3Д через матрицы реализовано....


> А как вы проверяли выделения объекта мышью, т.е. по двумерным
> координатам мыши определить 3-мерные, на которые сейчас
> направлен курсор мыши?


gluUnProject - для пробразования из экранных в пространственные.

gluProject - для пробразования из пространственных в экранные.

P.S.
Может не надо на вы? А то это звучит как оскарбление. :)

P.P.S.
Для того чтобы центрировать ЛЮБУЮ точку сферы нужно вращение только по ДВУМ углам.


 
alpha5 ©   (2006-10-08 21:03) [7]

Н-да...
Что-то я совсем запутался с поворотом сферы :( . Хоть головой об стенку бейся...

gluUnProject я уже пробовал - не получается - координата Z всегда одна и та же.
И пробовал gluUnProject совместно с glReadPixels для считывания координаты Z из Z-буфера.
Всё равно координата Z одинаковая. А ведь сфера - выпуклая! Соответственно координата Z должна изменятся при перемещении указателя мыши.
Так почему же координата Z - всегда одна и та же?

Кстати.
Сфера у меня задана таким образом:

x = r sin(q) cos(a)
y = r sin(q) sin(a)
z = r cos(q)
где
q E [0; 2pi]
a E [0; pi]
pi - это число ПИ


 
@!!ex ©   (2006-10-08 21:27) [8]

Там нужно преобразование экранных координат делать.
По вертикали.


 
alpha5 ©   (2006-10-09 14:16) [9]

А как это сделать?
Что-то я не пойму...


 
@!!ex ©   (2006-10-09 14:23) [10]

Просто систему координат перевернуть.

WindowHeight - CursorY


 
alpha5 ©   (2006-10-09 16:40) [11]

Попробовал - не получается.

Вот как это у меня реализовано:



procedure TFormMain.Calc_select_line( mouse_x,  mouse_y : integer; var  p1,  p2 : TPointReal);
var
 // mouse_x, mouse_y  - оконные координаты курсора мыши.
 // p1, p2            - возвращаемые параметры - концы селектирующего отрезка,
 //                     лежащие соответственно на ближней и дальней плоскостях
 //                     отсечения.
 viewport : array [0..3] of GLint  ;    // параметры viewport-a.
 projection : array [0..15] of GLdouble; // матрица проекции.
 modelview : array [0..15] of GLdouble;  // видовая матрица.
 vx,vy,vz : GLdouble;       // координаты курсора мыши в системе координат viewport-a.
 wx,wy,wz : GLdouble;       // возвращаемые мировые координаты.
begin
 glGetIntegerv(GL_VIEWPORT,@viewport);           // узнаём параметры viewport-a.
 glGetDoublev(GL_PROJECTION_MATRIX,@projection); // узнаём матрицу проекции.
 glGetDoublev(GL_MODELVIEW_MATRIX,@modelview);   // узнаём видовую матрицу.
 // переводим оконные координаты курсора в систему координат viewport-a.
 vx := mouse_x;
 vy := Height - mouse_y; // где height - текущая высота окна.

 // вычисляем ближний конец
 vz := -1;
 gluUnProject(vx, vy, vz, @modelview, @projection, @viewport, wx, wy, wz);
 p1.X := wx;
 p1.Y := wy;
 p1.Z := wz;
 // вычисляем дальний конец
 vz := 1;
 gluUnProject(vx, vy, vz, @modelview, @projection, @viewport, wx, wy, wz);
 p2.X := wx;
 p2.Y := wy;
 p2.Z := wz;
end;



Да... что-то тут явно не получается...
???


 
@!!ex ©   (2006-10-09 17:05) [12]

Что такое ближний конец? Дальний конец?

Вообще, если я правильно пнимаю математику 3Д преобразований, все что делает эта функция - это перемножает вектора на матрицу обратную матрице трансормаций......

По идее код верный... Не соображу сейчас.


 
Ketmar ©   (2006-10-09 17:10) [13]

собственно, а режим "selection" не помогает? разбиваем сферу на треугольники (как будто она иначе рисуется %-), "выбираем" ближайший треугольник, на основе его нормали выясняем, чего и куда вертеть. кажется, должно работать.


 
alpha5 ©   (2006-10-09 21:29) [14]

А немного поподробней про режим  "selection" можно?
А то я ни разу не пробовал его использовать.


 
Ketmar ©   (2006-10-09 21:31) [15]

Ян Хорн - это наше всё. иди на сулаку, там отличный примерчик. (кажется, именно там). я уж больно давно это делал -- тебе проще будет нарыть в сети. или на Delphi3d посмотри -- так, кажись, тоже было.


 
@!!ex ©   (2006-10-10 22:18) [16]


> Ketmar ©   (09.10.06 17:10) [13]

Хм...  уменя сфера состоит от 1 000 до 10 000 треугольников.
Буффер выбора не умрет? :) Тем более, что клик может производится не непосредственно на сфере, а на каком нить объекте случайно подвернувшемся под руку(городе, самолете, танке, и т.д. и т.п.), тогда опять же буффер выбора не работает....

Мне кажется не оптимально.
Хотя с буффером выбора дел особо не имел, как то он мне изначально не приглянулся...


 
Ketmar ©   (2006-10-10 22:22) [17]

>[16] @!!ex(c) 10-Oct-2006, 22:18
>Хм...  уменя сфера состоит от 1 000 до 10 000
>треугольников.
>Буффер выбора не умрет? :)
и что, все они на один пиксель попадают? %-)


 
@!!ex ©   (2006-10-10 22:41) [18]


> Ketmar ©   (10.10.06 22:22) [17]

Нет, конечно. :))
Но разве буффер выбора не требует наименования каждого выбираемого элемента?


 
Ketmar ©   (2006-10-10 22:44) [19]

>[18] @!!ex(c) 10-Oct-2006, 22:41
>Но разве буффер выбора не требует наименования каждого
>выбираемого элемента?
afair, просто возврашает выбранные. но могу и наврать -- не помню просто. %-)


 
@!!ex ©   (2006-10-10 22:49) [20]


glLoadName
glPushName


 
alpha5 ©   (2006-10-11 13:29) [21]

Ура, у меня получилось.
фишка заключалась в следующем:

Достаточно двух углов — например т.н. yaw и pitch.

Пусть наблюдатель (камера) и центр сферы находятся в начале координат, ось oX уходит вправо от наблюдателя, ось oY вверх, ось oZ вперёд. Пусть (tx,ty,tz) — заданная точка в пространстве XYZ.

Пусть yaw — угол поворота в плоскости XoZ отсчитываемый от положительной части оси X в сторону положительной части оси Z, а pitch — угол поворота в плоскости ToY, отсчитываемый аналогично, где T — ось, проходящая из начала координат через точку (tx,0,tz).

Тогда

yaw = atan2( tx, tz ) * 180 / Pi, а
pitch = atan2( sqrt(tx*tx+tz*tz), ty ) * 180 / Pi.


А дальше пишем

glRotatef(-pitch+90, 1, 0, 0);  // поворот вокруг оси OX
glRotatef(-yaw, 0, 1, 0);  // поворот вокруг оси OY
glRotatef(0 , 0, 0, 1);  // поворот вокруг оси OZ


Спасибо!



Страницы: 1 вся ветка

Форум: "Игры";
Текущий архив: 2007.09.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.045 c
3-1179329587
Sashok2007
2007-05-16 19:33
2007.09.16
Клиент-серверное приложение


15-1187356097
TUser
2007-08-17 17:08
2007.09.16
Украина первой в мире признала астрологию наукой


2-1188129926
nord489
2007-08-26 16:05
2007.09.16
Свойства Формы


2-1187532488
DelphiKettle
2007-08-19 18:08
2007.09.16
WM_CONTEXTMENU


2-1187927020
Gydvin
2007-08-24 07:43
2007.09.16
Чтение wmf





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский