Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.09.16;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.02 c
9-1160220897
alpha5
2006-10-07 15:34
2007.09.16
Углы поворота


15-1185599882
IMHO
2007-07-28 09:18
2007.09.16
Шведский стол


15-1185471908
Константинов
2007-07-26 21:45
2007.09.16
Delphi забоставал


15-1184229560
evvcom
2007-07-12 12:39
2007.09.16
FMP (Феодосия Мастак Пати)


1-1183721180
mr_ko
2007-07-06 15:26
2007.09.16
Rave report