Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Углы поворота [Delphi, Windows]


Страницы:   1 2

alpha5 ©   (2006-10-07 15:34:00) 

Привет всем! У меня такая проблема. Я программирую, используя средства 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

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

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


alpha5   (2006-10-11 13:29:00) [1]

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

Достаточно двух углов — например т.н. 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


Спасибо!


@!!ex   (2006-10-10 22:49:00) [2]


glLoadName
glPushName


Ketmar   (2006-10-10 22:44:00) [3]

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


@!!ex   (2006-10-10 22:41:00) [4]


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

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


Ketmar   (2006-10-10 22:22:00) [5]

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


@!!ex   (2006-10-10 22:18:00) [6]


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

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

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


Ketmar   (2006-10-09 21:31:00) [7]

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


alpha5   (2006-10-09 21:29:00) [8]

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


Ketmar   (2006-10-09 17:10:00) [9]

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


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

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

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

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


alpha5   (2006-10-09 16:40:00) [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 14:23:00) [12]

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

WindowHeight - CursorY


alpha5   (2006-10-09 14:16:00) [13]

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


@!!ex   (2006-10-08 21:27:00) [14]

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


alpha5   (2006-10-08 21:03:00) [15]

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

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 11:06:00) [16]


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

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


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


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

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

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

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


alpha5   (2006-10-07 22:39:00) [17]

Спасибо

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

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-07 21:26:00) [18]

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

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

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


alpha5   (2006-10-07 18:24:00) [19]

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


alpha5   (2006-10-07 18:16:00) [20]

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

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

XRotate:= xChange
YRotate:= yChange


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

wx := x;
wy := y;


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

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо