powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / DirectX вращение камеры вокруг центра
20 сообщений из 20, страница 1 из 1
DirectX вращение камеры вокруг центра
    #38132671
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте! По возможности поделитесь пожалуйста ссылками на примеры или статьи где реализовано вращение камеры вокруг определенной точно(центра). А то в инете ничего подходящего найти не могу.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38132901
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предположим, точка находится в центре вьюпорта:
- рассчитать мировое расстояние от камеры до точки
- переместить камеру вперед на указанное расстояние
- повернуть камеру на нужный угол
- переместить камеру назад на указанное расстояние
- сделать рефреш
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38133261
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему, статьи не нужны. Обычно хватает элементарных знаний аналитической геометрии (учебник для 1-го курса техвуза) и help по DirectX.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38133386
wvetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KokonЗдравствуйте! По возможности поделитесь пожалуйста ссылками на примеры или статьи где реализовано вращение камеры вокруг определенной точно(центра). А то в инете ничего подходящего найти не могу.
Я у себя так делал:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
float cam_z=-13;
float cam_y=0;
float cam_x=0;
float r=13;
float ugol=1.570796327;
float ugol2=0;

...

//-----------------------------------------------
if (KEY_DOWN(VK_UP) || keyboard_state[DIK_UP])
    {
		ugol-=0.01;
		cam_z=-r*sin(ugol)*cos(ugol2);
		cam_x=r*sin(ugol)*sin(ugol2);
		cam_y=r*cos(ugol);
		
    } // end if
	//-----------------------------------------------
if (KEY_DOWN(VK_DOWN) || keyboard_state[DIK_DOWN])
    {
		ugol+=0.01;
		cam_z=-r*sin(ugol)*cos(ugol2);
		cam_x=r*sin(ugol)*sin(ugol2);
		cam_y=r*cos(ugol);
				
    } // end if
	//-----------------------------------------------
if (KEY_DOWN(VK_RIGHT) || keyboard_state[DIK_RIGHT])
    {
		ugol2+=0.01;
		cam_z=-r*sin(ugol)*cos(ugol2);
		cam_x=r*sin(ugol)*sin(ugol2);
		cam_y=r*cos(ugol);
				
    } // end if
	//-----------------------------------------------
	if (KEY_DOWN(VK_LEFT) || keyboard_state[DIK_LEFT])
    {
		ugol2-=0.01;
		cam_z=-r*sin(ugol)*cos(ugol2);
		cam_x=r*sin(ugol)*sin(ugol2);
		cam_y=r*cos(ugol);
		
    } // end if
	//-----------------------------------------------
	if (KEY_DOWN(VK_RCONTROL) || keyboard_state[DIK_RCONTROL])
    {
		r+=0.5;
		cam_z=-r*sin(ugol)*cos(ugol2);
		cam_x=r*sin(ugol)*sin(ugol2);
		cam_y=r*cos(ugol);
    } // end if
	//-----------------------------------------------
	if (KEY_DOWN(VK_RSHIFT) || keyboard_state[DIK_RSHIFT])
    {
		r-=0.5;
		cam_z=-r*sin(ugol)*cos(ugol2);
		cam_x=r*sin(ugol)*sin(ugol2);
		cam_y=r*cos(ugol);
    } // end if
	//-----------------------------------------------
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38133984
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wvetal,
спасибо за помощь. чуть-чуть переделал

Код: c#
1.
2.
3.
4.
  ugol -= speed; // кнопка W
  cam_y = -r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Sin(ugol2 * Math.PI / 180);
  cam_x = r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Cos(ugol2 * Math.PI / 180);
  cam_z = r * (float)Math.Cos(ugol * Math.PI / 180);



вроде по формулам сферических координат так должно быть. Но все равно есть какой-то косяк. Просто в центре сцены есть куб. когда он крутиться(точнее камера вокруг него) он доходит до определенного момента и начинает обратно крутиться, потом снова чуть покрутиться и снова в обратную сторону. Пока не разобрался почему.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38133987
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pirovindos, да у меня знаний то особо нет, я только начала все это дело изучать.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134172
wvetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kokonwvetal,
... Просто в центре сцены есть куб. когда он крутиться(точнее камера вокруг него) он доходит до определенного момента и начинает обратно крутиться, потом снова чуть покрутиться и снова в обратную сторону. Пока не разобрался почему.
А как надо? Чтоб он не начинал обратно крутится? Чтоб крутился все время в одну сторону?
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134187
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kokon
вроде по формулам сферических координат так должно быть. Но все равно есть какой-то косяк. Просто в центре сцены есть куб. когда он крутиться(точнее камера вокруг него) он доходит до определенного момента и начинает обратно крутиться, потом снова чуть покрутиться и снова в обратную сторону. Пока не разобрался почему.

Точка вокруг которой должна крутится камера какие координаты имеет: (0,0,0)?
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134203
wvetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kokon,

А если так попробовать:
Код: plaintext
1.
2.
3.
4.
ugol -= speed; // кнопка W
cam_x = r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Sin(ugol2 * Math.PI / 180);
cam_z = -r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Cos(ugol2 * Math.PI / 180);
cam_y = r * (float)Math.Cos(ugol * Math.PI / 180);
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134214
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kokon когда он крутиться(точнее камера вокруг него) он доходит до определенного момента и начинает обратно крутиться, потом снова чуть покрутиться и снова в обратную сторону.

Если куб с незакрашенными гранями, а в виде "каркаса из проволочек", то наблюдаемый эффект может быть оптической иллюзией, а крутится все правильно.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134407
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pirovindosKokon когда он крутиться(точнее камера вокруг него) он доходит до определенного момента и начинает обратно крутиться, потом снова чуть покрутиться и снова в обратную сторону.

Если куб с незакрашенными гранями, а в виде "каркаса из проволочек", то наблюдаемый эффект может быть оптической иллюзией, а крутится все правильно.

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

попробовал как подсказал wvetal но там направление меняется каждые 90 градусов.

а вообще я хочу сделать чтобы камера облетала сцену как это сделано в 3d max или в любом другом 3d редакторе. Я бы просто потом движение камеры привязал не к клаве, а к мышке.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134409
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pirovindosKokonвроде по формулам сферических координат так должно быть. Но все равно есть какой-то косяк. Просто в центре сцены есть куб. когда он крутиться(точнее камера вокруг него) он доходит до определенного момента и начинает обратно крутиться, потом снова чуть покрутиться и снова в обратную сторону. Пока не разобрался почему.

Точка вокруг которой должна крутится камера какие координаты имеет: (0,0,0)?

да (0,0,0). т.е. центр сцены
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38134448
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, когда вправо или влево вращаешь, то все нормально, проблема только когда вверх вниз
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135625
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Kokon:

В 3ds max (и его бесплатном варианте, gmax ), режим вращения камеры называется «arc rotate». При этом есть особая точка, arc rotate center, проекция которой остаётся неподвижной. То есть, во время вращения камеры, arc rotate center проецируется в один и тот же пиксел viewport-а. В качестве arc rotate center обычно берётся центр выделенных объектов.

Реализовать max-овский режим arc rotate можно например так: (C++, Direct3D 9)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
// градусы -> радианы
inline double rad_from_deg(double angle) {
  return (3.141592653589793 / 180) * angle;
}

struct Vec_3 {
  double x, y, z;
};

inline Vec_3 v3(double x, double y, double z) {
  Vec_3 res = {x, y, z};
  return res;
}

inline Vec_3 operator*(double a, const Vec_3& v) {
  return v3(a * v.x, a * v.y, a * v.z);
}

inline Vec_3 operator+(const Vec_3& a, const Vec_3& b) {
  return v3(a.x + b.x, a.y + b.y, a.z + b.z);
}

inline Vec_3 operator-(const Vec_3& a, const Vec_3& b) {
  return v3(a.x - b.x, a.y - b.y, a.z - b.z);
}

// скалярное произведение (dot product)
inline double dot(const Vec_3& a, const Vec_3& b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}

// векторное произведение (cross product)
// может быть записано как определитель (determinant):
// |i  j  k |
// |ax ay az|
// |bx by bz|
inline Vec_3 cross(const Vec_3& a, const Vec_3& b) {
  return v3(
    /*x:*/ a.y * b.z - b.y * a.z,
    /*y:*/ a.z * b.x - b.z * a.x,
    /*z:*/ a.x * b.y - b.x * a.y
  );
}

inline double len(const Vec_3& v) {
  return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

// поворачивает точку вокруг оси
Vec_3 rotate(const Vec_3& point_on_axis, const Vec_3& axis_dir, double angle, const Vec_3& point) {
  assert(fabs(len(axis_dir) - 1) < 1e-3); // axis_dir должен быть единичным вектором
  Vec_3 r = point - point_on_axis;
  double a = rad_from_deg(angle);
  return point_on_axis + cos(a) * r + ((1 - cos(a)) * dot(axis_dir, r)) * axis_dir + sin(a) * cross(axis_dir, r);
}

Vec_3 _cam_pos = {0, -200, 200};

// углы, задающие ориентацию камеры
double _cam_yaw = 90;
double _cam_pitch = -45;

// оси камеры в мировых координатах
Vec_3 _cam_dir;
Vec_3 _cam_right;
Vec_3 _cam_up;

void calc_cam_axes() {
  _cam_dir.x = cos(rad_from_deg(_cam_pitch)) * cos(rad_from_deg(_cam_yaw));
  _cam_dir.y = cos(rad_from_deg(_cam_pitch)) * sin(rad_from_deg(_cam_yaw));
  _cam_dir.z = sin(rad_from_deg(_cam_pitch));

  _cam_right.x = cos(rad_from_deg(_cam_yaw - 90));
  _cam_right.y = sin(rad_from_deg(_cam_yaw - 90));
  _cam_right.z = 0;

  _cam_up = cross(_cam_right, _cam_dir);
}

Vec_3 _arc_rotate_center = {0, 0, 0}; // в мировых координатах

// move_x, move_y можно брать из движений мыши
void arc_rotate(int move_x, int move_y) {
  if (move_x != 0) {
    double yaw_diff = move_x;
    _cam_pos = rotate(/*point_on_axis:*/_arc_rotate_center, /*axis_dir:*/v3(0, 0, 1), yaw_diff, _cam_pos);
    _cam_yaw += yaw_diff;
    calc_cam_axes();
  }
  if (move_y != 0) {
    double pitch_diff = -move_y;
    _cam_pos = rotate(/*point_on_axis:*/_arc_rotate_center, /*axis_dir:*/_cam_right, pitch_diff, _cam_pos);
    _cam_pitch += pitch_diff;
    calc_cam_axes();
  }
  request_paint(); // invalidate
}

void key_down(int key) {
  switch (key) {
  case VK_LEFT: arc_rotate(-5, 0); break;
  case VK_RIGHT: arc_rotate(5, 0); break;
  case VK_DOWN: arc_rotate(0, -5); break;
  case VK_UP: arc_rotate(0, 5); break;
  }
}

void update_view_transform() {
  assert(_device != NULL); // указатель на IDirect3DDevice9
  D3DMATRIX m;
  m._11 = _cam_right.x;               m._12 = _cam_up.x;               m._13 = _cam_dir.x;               m._14 = 0;
  m._21 = _cam_right.y;               m._22 = _cam_up.y;               m._23 = _cam_dir.y;               m._24 = 0;
  m._31 = _cam_right.z;               m._32 = _cam_up.z;               m._33 = _cam_dir.z;               m._34 = 0;
  m._41 = -dot(_cam_pos, _cam_right); m._42 = -dot(_cam_pos, _cam_up); m._43 = -dot(_cam_pos, _cam_dir); m._44 = 1;
  _device->SetTransform(D3DTS_VIEW, &m);
}


Использовал тип double (а не float), чтобы погрешность поменьше накапливалась после многих вызовов функции rotate. Как реализовать arc rotate, чтобы погрешность не накапливалась, мне пока в голову не пришло.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135781
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
ugol -= speed;

- это вверх (ну или вниз)?

Как задан вектор ориентации камеры и "точка зрения"? Они меняются при вращении?
По идее точка зрения меняться не должна.
А ориентация должна и там нужно аккуратно посчитать.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135807
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седов, спасибо код поразбираюсь с кодом
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135855
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pirovindos
Код: plaintext
1.
ugol -= speed;

- это вверх (ну или вниз)?

Как задан вектор ориентации камеры и "точка зрения"? Они меняются при вращении?
По идее точка зрения меняться не должна.
А ориентация должна и там нужно аккуратно посчитать.

Камера у меня устанавливается вот так
Код: c#
1.
2.
3.
4.
Vector3 campos = new Vector3(cam_x, cam_y, cam_z);
Vector3 center = new Vector3(0, 0, 0);
Vector3 camup = new Vector3(0, 0, 1);
device.Transform.View = Matrix.LookAtLH(campos, center, camup);



в этом коде
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 switch (e.KeyCode)
            {
                case Keys.W:
                    
                    ugol += speed;
                    cam_y =  -r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Sin(ugol2 * Math.PI / 180);
                    cam_x = r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Cos(ugol2 * Math.PI / 180);
                    cam_z =  r * (float)Math.Cos(ugol * Math.PI / 180);
                   break;
}


синус меняется от 0 до 1. т.е. пока ugol растет от 0 до 90 градусов камера двигается нормально, потом синус начинается уменьшаться и камера двигается в обратную сторону. т.е. получается что угол меняться не должен. я должен сдвигать камеру на одинаковый угол. Пробовал при неменяющимся значении ugol делать cam-x=cam-x+r*...... но тогда камера постоянно отодвигается пока вообще не улетает.
Вот такая у меня сейчас проблема.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135888
wvetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kokon,

Я уже приводил этот код.
У себя его пробовал? К чему он приводит? Что не работает?
Код: plaintext
1.
2.
3.
4.
ugol -= speed; // кнопка W
cam_x = r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Sin(ugol2 * Math.PI / 180);
cam_z = -r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Cos(ugol2 * Math.PI / 180);
cam_y = r * (float)Math.Cos(ugol * Math.PI / 180);
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135889
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему, при вращении "вверх/вниз", при переходе через зенит, не получится использовать постоянный
Код: plaintext
1.
 Vector3 camup = new Vector3(0, 0, 1);


Нужно его менять. Сейчас у тебя при переходе через зенит скачком меняются местами верх и низ на кадре камеры.
...
Рейтинг: 0 / 0
DirectX вращение камеры вокруг центра
    #38135915
Kokon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wvetalKokon,

Я уже приводил этот код.
У себя его пробовал? К чему он приводит? Что не работает?
Код: plaintext
1.
2.
3.
4.
ugol -= speed; // кнопка W
cam_x = r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Sin(ugol2 * Math.PI / 180);
cam_z = -r * (float)Math.Sin(ugol * Math.PI / 180) * (float)Math.Cos(ugol2 * Math.PI / 180);
cam_y = r * (float)Math.Cos(ugol * Math.PI / 180);



Пробовал, но все равно как-то странно двигается, тоже вроде направление меняется на обратное. Попробую на с# реализовать код который Пётр Седов предложил, потом отпишусь о результатах.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / DirectX вращение камеры вокруг центра
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]