Сейчас занимаюсь написанием software rendera, который осуществляет визуализацию 2D объектов в трехмерном пространстве. При визуализации используется матрица трансформации [4x4]: Код |
public class Matrix3D {
public float sx, sy, sz; public float xangle,yangle,zangle; public float xx, xy, xz, xo; public float yx, yy, yz, yo; public float zx, zy, zz, zo; static final double pi = 3.14159265; public Matrix3D () { xx = 1.0f; yy = 1.0f; zz = 1.0f; sx = 1.0f; sy = 1.0f; sz = 1.0f; xangle = 0; yangle = 0; zangle = 0; }
public void translate(float x, float y, float z) { xo += x; yo += y; zo += z; }
public void yrot(double theta) { yangle += theta; theta *= (pi / 180); double ct = Math.cos(theta); double st = Math.sin(theta);
float Nxx = (float) (xx * ct + zx * st); float Nxy = (float) (xy * ct + zy * st); float Nxz = (float) (xz * ct + zz * st); float Nxo = (float) (xo * ct + zo * st);
float Nzx = (float) (zx * ct - xx * st); float Nzy = (float) (zy * ct - xy * st); float Nzz = (float) (zz * ct - xz * st); float Nzo = (float) (zo * ct - xo * st);
xo = Nxo; xx = Nxx; xy = Nxy; xz = Nxz; zo = Nzo; zx = Nzx; zy = Nzy; zz = Nzz; }
public void xrot(double theta) { xangle += theta; theta *= (pi / 180); double ct = Math.cos(theta); double st = Math.sin(theta);
float Nyx = (float) (yx * ct + zx * st); float Nyy = (float) (yy * ct + zy * st); float Nyz = (float) (yz * ct + zz * st); float Nyo = (float) (yo * ct + zo * st);
float Nzx = (float) (zx * ct - yx * st); float Nzy = (float) (zy * ct - yy * st); float Nzz = (float) (zz * ct - yz * st); float Nzo = (float) (zo * ct - yo * st);
yo = Nyo; yx = Nyx; yy = Nyy; yz = Nyz; zo = Nzo; zx = Nzx; zy = Nzy; zz = Nzz; }
public void zrot(double theta) { zangle += theta; theta *= (pi / 180); double ct = Math.cos(theta); double st = Math.sin(theta);
float Nyx = (float) (yx * ct + xx * st); float Nyy = (float) (yy * ct + xy * st); float Nyz = (float) (yz * ct + xz * st); float Nyo = (float) (yo * ct + xo * st);
float Nxx = (float) (xx * ct - yx * st); float Nxy = (float) (xy * ct - yy * st); float Nxz = (float) (xz * ct - yz * st); float Nxo = (float) (xo * ct - yo * st);
yo = Nyo; yx = Nyx; yy = Nyy; yz = Nyz; xo = Nxo; xx = Nxx; xy = Nxy; xz = Nxz; }
public void rotateX(float angle) { float dx = xo; float dy = yo; float dz = zo; translate(-dx, -dy, -dz); xrot(angle); translate(dx, dy, dz); }
public void rotateY(float angle) { float dx = xo; float dy = yo; float dz = zo; translate(-dx,-dy,-dz); yrot(angle); translate(dx,dy,dz); }
public void rotateZ(float angle) { float dx = xo; float dy = yo; float dz = zo; translate(-dx,-dy,-dz); zrot(angle); translate(dx,dy,dz); }
|
Допустим есть точка с координатами (x,y,z). Перед выводом её на экран вычисляются её псевдо3D коодинаты для рисования: Код |
public Point2D getDrawPoint(float x,float y,float z, Matrix3D m)
double drawX = x*m.xx+y*m.xy+z*m.xz+m.xo; double drawY = x*m.yx +y*m.yy+z*m.yz+m.yo; double dZ = x*m.zx+y*m.zy+z*m.zz+m.zo;
Point2D point = new Point2D(drawX,drawY);
return point;
|
3D модель, которая визуализируется состоит из точек и линий, их соединяющих (проволочная модель). Нужно добавить возможность обзора(поворота) этой модели с помощью мыши. Как правильно это сделать, используя эту матрицу трансформации? В интернете нашел код для OpenGL-а и немного переделал его под свой пример : При щелчке мыши запоминаем её координаты: Код | float sx = mouse.getX(); float sy = mouse.getY(); float thetaX = 0.0f; float thetaY = 0.0f;
|
При передвижении мыши с нажатой кнопкой вычисляем два угла: Код | x = mouse.getX(); y = mouse.getY();
// вычисляются ширина и высота компонента на котором всё рисуется float width = component.getWidth(); float height = component.getHeight();
// вычисляются углы thetaY = 360.0f * ( (float)(x-sx)/(width)); thetaX = 360.0f * ( (float)(y-sy)/(height));
sx = x; sy = y;
// сохраняем поворот по X и Y в матрице трансформации
matrix.rotateX(thetaX); matrix.rotateY(thetaY);
|
Этот код позволяет вращать модель мышью, но получается очень криво и убого. Видно, что что-то неправильно. Хотя в OpenGL получалось неплохо. В чём ошибка? И как выполнить вращение (более правильное , используя матрицу Matrix3D ) такой модели мышью? Это сообщение отредактировал(а) x8m6 - 10.6.2009, 15:45
|