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

Вниз

Движение мыши => трёхмерные вращения   Найти похожие ветки 

 
Pavlik_Morozov   (2004-03-30 12:38) [0]

Уважаемые господа! Кто-нибудь знает как делается преобразование: движение мыши => трёхмерные вращения? Т.е.: есть 3D-объект, его необходимо вращать мышкой (может видели 3D Orbit в AutoCAD-е), у меня есть некие формулы для вращения вокруг X (направлена слева направо), Y (направлена снизу вверх), Z (направлена "на нас") - если бы объект был 2D, то тут более-мения понято, так как координат мыши будет также две, а как для 3D быть??? Заранее благодарен за любые идеи...


 
Pavlik_Morozov   (2004-03-30 18:17) [1]

...неужели никто ничего не может подсказать?:( И в RSDN ничего:(


 
VMcL ©   (2004-03-30 18:59) [2]

Ну раз объект, грубо говоря, имеет три оси, а у мыша только 2 координаты, то наверное нужно какой-нибудь кнопкой сделать переключение осей, контролируемых мышом.


 
Algol   (2004-03-31 18:43) [3]

Для вращения трехмерного тела достаточно задания только двух углов. (см полярные координаты в трехмерном пространстве)


 
VMcL ©   (2004-03-31 19:00) [4]

>>Algol  (31.03.04 18:43) [3]

Если формулировать так, как ты, то я бы сказал, что <Для вращения трехмерного тела достаточно задания> вообще одного угла поворота.


 
Algol   (2004-03-31 19:14) [5]

Одного угла недостаточно, поскольку только одним углом невозможно задать произвольное положение тела. А двумя - возможно.


 
VMcL ©   (2004-04-01 00:41) [6]

>>Algol  (31.03.04 19:14) [5]

Обрати внимание еще раз на [3] и на [4]. В [3] слова "произвольно..." не было. Именно на это я и хотел обратить внимание.


 
Pa5ha   (2004-04-01 18:23) [7]

При каждом нажатии клавиши мыши создавай матрицу.
При каждом движении мыши изменяй матрицу.
При каждом отпусканий мыши умножай имеющуюся матрицу на созданную и удаляй оную...
Успехов.


 
Pavel_P   (2004-04-12 19:00) [8]

"При каждом нажатии клавиши мыши создавай матрицу..." - а как создавать-то?..

P.S. ...извиняюсь, что долго отсутствовал


 
Wyvern   (2004-04-21 00:36) [9]

Вращал камеру вокруг объекта:
По вертикальной мышиной оси - в направлении вектора UpCam,
по горизонтальной мышиной оси - в направлении нормали к векторам UpCam и PosCam (у меня было упрощение - объект находился в начале координат, т.е. ViewCam = (0.0, 0.0, 0.0)).

Вращение камеры:

procedure ReDraw;
....
gluLookAt (PosCam1.X, PosCam1.Y, PosCam1.Z, ViewCam.X, ViewCam.Y, ViewCam.Z, UpCam.X, UpCam.Y, UpCam.Z);
....


Событие при движении мышы:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: integer);
var PosCam1, Normal: TVector;
begin
 if not(ssLeft in Shift) then
 begin
   OldX := X;
   OldY := Y;
   exit;
 end;
 AlphaY := (Y - OldY)/100;
 AlphaX := (OldX - X)/100;
 Normal := GetNormal(PosCam, UpCam);//получаем нормаль к векторам UpCam и PosCam.
 UpCam := MultVector(UpCam, AlphaY);
 PosCam1 := AddVector(PosCam, UpCam);//Поворот камеры в вертикальной плоскости UpCam + PosCam.
 UpCam := GetNormal(Normal, PosCam);//Получаем новый вектор UpCam.
 Normal := MultVector(Normal, AlphaX);
 PosCam := AddVector(PosCam1, Normal);//Поворот камеры в горизонтальной плоскости.
 PosCam1 := NormVector(PosCam);//нормализуем вектор положения камеры (иначе при движении камера будет удаляться от объекта).
 PosCam := PosCam1;
 OldX := X;
 OldY := Y;
 ReDraw;//перерисовываем сцену.
end;


Процедуры обработки векторов:


function GetNormal(Vect1,Vect2: TVector): TVector;
var I,VX1,VY1,VZ1,VX2,VY2,VZ2,NX,NY,NZ: GLFloat;
begin
 // Вычисление нормали
 VX1:=-Vect1.X;
 VY1:=-Vect1.Y;
 VZ1:=-Vect1.Z;
 VX2:=Vect1.X-Vect2.X;
 VY2:=Vect1.Y-Vect2.Y;
 VZ2:=Vect1.Z-Vect2.Z;
 // вектор перпендикулярный центру треугольника
 NX:=VY1*VZ2-VZ1*VY2;
 NY:=VZ1*VX2-VX1*VZ2;
 NZ:=VX1*VY2-VY1*VX2;
 I:=-Sqrt(NX*NX+NY*NY+NZ*NZ);
 if I=0 then I:=-1;    // для предотвращения деления на ноль
 Result.X:=NX/I;
 Result.Y:=NY/I;
 Result.Z:=NZ/I;
end;

function NormVector(Vect1: TVector): TVector; // Нормализация вектора
var I: GLFloat;
begin
 I:=Sqrt(Vect1.X*Vect1.X+Vect1.Y*Vect1.Y+Vect1.Z*Vect1.Z);
 if I=0 then I:=1; // для предотвращения деления на ноль
 Result.X:=Vect1.X/I;
 Result.Y:=Vect1.Y/I;
 Result.Z:=Vect1.Z/I;
end;

function AddVector(Vect1,Vect2: TVector): TVector;
begin
 Result.X:=Vect1.X+Vect2.X;
 Result.Y:=Vect1.Y+Vect2.Y;
 Result.Z:=Vect1.Z+Vect2.Z;
end;

function MultVector(Vect1: TVector; Num: single): TVector;
begin
 Result.X:=Num*Vect1.X;
 Result.Y:=Num*Vect1.Y;
 Result.Z:=Num*Vect1.Z;
end;



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

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

Наверх




Память: 0.48 MB
Время: 0.035 c
3-1086335885
Ven
2004-06-04 11:58
2004.07.04
InterBase,IBDataset


1-1087333802
AndrewVolkov
2004-06-16 01:10
2004.07.04
Listview style vsList


14-1087147882
Slava-soft
2004-06-13 21:31
2004.07.04
создать seekbar


8-1082124067
xman
2004-04-16 18:01
2004.07.04
чтение текста


1-1087460995
besen-ok
2004-06-17 12:29
2004.07.04
Как узнать длину строки типа AnsiString ? (-)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский