Форум: "Игры";
Текущий архив: 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.51 MB
Время: 0.035 c