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

Вниз

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

 
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 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.037 c
1-1087725582
R
2004-06-20 13:59
2004.07.04
AnsiPos но не чувствительная к регистру символа


4-1085349762
Malya
2004-05-24 02:02
2004.07.04
ShellExecute?


3-1086124736
Kirill
2004-06-02 01:18
2004.07.04
Книги по работе с Interbase из-под Delphi


3-1086335885
Ven
2004-06-04 11:58
2004.07.04
InterBase,IBDataset


14-1087369345
Saturn
2004-06-16 11:02
2004.07.04
Delphi 8