📄 camera.java
字号:
package myprojects.graph3dapp;
import java.awt.*;
class Camera {
protected Vector3d vrp = new Vector3d(0, 0, 3); //观察参考点
protected Vector3d vpn = new Vector3d(0, 0, -1); //观察平面法向
protected Vector3d vup = new Vector3d(0, 1, 0); //观察正向(观察方向)
protected double fd = 0, bd = 10; //前后截面距离
protected Vector3d prp = new Vector3d(0.0f, 0.0f, -15.0f); //(观察坐标系下)投影参考点坐标
protected double uMin = -1.5, uMax = 1.5; //(观察坐标系下)观察窗口横向范围
protected double vMin = -1.5, vMax = 1.5; //(观察坐标系下)观察窗口纵向范围
protected int canvasWidth = 200; //画布尺寸
protected int canvasHeight = 200;
protected Matrix3d transMatrix = Matrix3d.unit();
public Camera() {
}
public void setVRP(double x, double y, double z) {
vrp.x = x; vrp.y = y; vrp.z = z;
}
public void setVPN(double x, double y, double z) {
vpn.x = x; vpn.y = y; vpn.z = z;
}
public void setVUP(double x, double y, double z) {
vup.x = x; vup.y = y; vup.z = z;
}
void setFD(double fd) {
this.fd = fd;
}
void setBD(double bd) {
this.bd = bd;
}
void setViewSize(double uMin, double uMax, double vMin, double vMax) {
this.uMin = uMin; this.uMax = uMax;
this.vMin = vMin; this.vMax = vMax;
}
void setCanvasSize(int width, int height) {
canvasWidth = width;
canvasHeight = height;
}
/** 计算空间变换矩阵 */
protected Matrix3d SpaceTransform() {
Vector3d n = Vector3d.normalize(vpn);
Vector3d a = Vector3d.normalize(vup);
Vector3d u = Vector3d.cross(n, a);
Vector3d v = Vector3d.cross(u, n);
Matrix3d t1 = Matrix3d.unit();
t1.matrix[3][0] = -vrp.x;
t1.matrix[3][1] = -vrp.y;
t1.matrix[3][2] = -vrp.z;
Matrix3d t2 = Matrix3d.unit();
t2.matrix[0][0] = u.x; t2.matrix[0][1] = v.x; t2.matrix[0][2] = n.x;
t2.matrix[1][0] = u.y; t2.matrix[1][1] = v.y; t2.matrix[1][2] = n.y;
t2.matrix[2][0] = u.z; t2.matrix[2][1] = v.z; t2.matrix[2][2] = n.z;
return Matrix3d.mul(t1, t2);
}
/** 计算规范化投影空间变换矩阵*/
protected Matrix3d normalizeTransform() {
Matrix3d t3 = Matrix3d.unit();
t3.matrix[3][0] = -prp.x;
t3.matrix[3][1] = -prp.y;
t3.matrix[3][2] = -prp.z;
Matrix3d t4 = Matrix3d.unit();
double ucw = 0.5f*(uMax+uMin)-prp.x;
double vcw = 0.5f*(vMax+vMin)-prp.y;
double ncw = -prp.z;
t4.matrix[2][0] = -ucw/ncw;
t4.matrix[2][1] = -vcw/ncw;
Matrix3d t5 = Matrix3d.unit();
t5.matrix[0][0] = -2*prp.z/((uMax-uMin)*(bd-prp.z));
t5.matrix[1][1] = -2*prp.z/((vMax-vMin)*(bd-prp.z));
t5.matrix[2][2] = 1/(bd-prp.z);
return Matrix3d.mul(Matrix3d.mul(t3, t4), t5);
}
/** 计算图像空间变换矩阵*/
protected Matrix3d projectTransform() {
Matrix3d t6 = Matrix3d.unit();
double f = (fd-prp.z)/(bd-prp.z);
t6.matrix[2][2] = 1.0f/(1-f);
t6.matrix[3][2] = -f/(1-f);
t6.matrix[2][3] = 1;
t6.matrix[3][3] = 0;
Matrix3d t7 = Matrix3d.unit();
t7.matrix[1][1] = -1;
t7.matrix[3][0] = -uMin;
t7.matrix[3][1] = vMax;
Matrix3d t8 = Matrix3d.unit();
t8.matrix[0][0] = (canvasWidth-1)/(uMax-uMin);
t8.matrix[1][1] = (canvasHeight-1)/(vMax-vMin);
t8.matrix[2][2] = (canvasWidth-1)/(uMax-uMin);
return Matrix3d.mul(Matrix3d.mul(t6, t7), t8);
}
public void refresh() {
transMatrix = SpaceTransform();
transMatrix.mul(normalizeTransform());
transMatrix.mul(projectTransform());
}
public Vector3d project(Vector3d v) {
return Vector3d.mulMatrix(v, transMatrix);
}
public Vector3d project(Vector3d v, Matrix3d transMatrix) {
return project(Vector3d.mulMatrix(v, transMatrix));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -