![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Углы поворота [Delphi, Windows]
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?
Не пойму, в чём тут загвоздка.
А насчёт ссылки, то давайте. Очень даже пригодится.