-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfull_test.html
168 lines (143 loc) · 8.99 KB
/
full_test.html
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>complete test</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="./js/three.min.js"></script>
<script>
// -------- 你可以修改下面的值来进行测试 --------- //
// -------- You can modify the data below for testing --------- //
// 设置为 true 则观察方向为 z 的正半轴,设置为 false 则观察方向为 z 的负半轴
// Set to true to observe the positive half-axis of z, and set to false to observe the negative half-axis of z
var zPositive = true;
// 设置整个窗口大小
// setup window size of the entire UI
var windowWidth = 640;
var windowHeight = 480;
// 用来渲染图形的窗口大小,它不同于窗口大小
// setup viewport of the rendering area, which is different from the window size
var viewStartX = 40; // viewStartX and viewStartY are actually set to 0 in z_positive.html and z_negtive.html
var viewStartY = 60;
var viewWidth = 580; // viewStartX + viewWidth <= windowWidth; So does viewHeight
var viewHeight = 400;
// 设置摄像机内参矩阵 K
// zPositive = true, K = [[fx, 0, u0], [0, fy, v0], [0, 0, 1]
// zPositive = false, K = [[-fx, 0, u0], [0, fy, v0], [0, 0, 1]
var fx = 565.5;
var fy = 516.3;
var u0 = 328.2;
var v0 = 238.8;
var calibrationWidth = 640; // 摄像机在标定时候的分辨率
var calibrationHeight = 480; // the resolution of the image which is used for camera calibration
// 设置远近裁剪面
// setup near and far clipping plane
var near = 0.5;
var far = 1000;
// -------- 你可以修改上面的值来进行测试 --------- //
// -------- You can modify the data above for testing --------- //
// K 的参数往往需要根据渲染窗口大小进行缩放,注意这里用的是 viewWidth 而不是 windowWidth
// parameters of often need to be scaled according to the size of the rendering window.
// Note that viewWidth is used here rather than windowWidth
ratioX = viewWidth / calibrationWidth;
ratioY = viewHeight / calibrationHeight;
fx = fx * ratioX;
fy = fy * ratioY;
u0 = u0 * ratioX;
v0 = v0 * ratioY;
var projectionMatrix = new THREE.Matrix4();
// 旋转和平移矩阵 (rotation and translation matrix) [R t; 0 0 0 1]
// q = R * p + t, p 是空间中的一点在世界坐标系中的坐标,q 是该点在摄像机坐标系中的坐标
// 这里 R/t 的定义仅仅是我习惯的定义
// q = R * p + t, p is the coordinate of a point in space in the world coordinate system,
// and q is the coordinate of the point in the camera coordinate system
var transformMatrix = new THREE.Matrix4();
if (zPositive) { // same as z_positive.html
var l = - u0 / fx * near;
var r = (viewWidth - u0) / fx * near;
var t = - v0 / fy * near;
var b = (viewHeight - v0) / fy * near;
var A = - (far + near) / (near - far);
var B = 2 * (far * near) / (near - far);
projectionMatrix.set(2*near/(r-l), 0, - (r + l) / (r - l), 0,
0, 2*near/(t - b), - (t + b) / (t - b), 0,
0, 0, A, B,
0, 0, 1, 0);
// 可以修改 R/t 数据,但可能会有些困难,算错了可能会让物体不在视野范围内
// You can modify the R/t data, but the object is not visible if you provide wrong data.
transformMatrix.set(0.4608, 0, -0.8875, 3.5841,
0.4045, -0.8901, 0.2100, 9.0800,
-0.7900, -0.4558, -0.4102, 70.0336,
0, 0, 0, 1);
}
else { // same as z_negative.html
var l = - u0 / fx * near;
var r = (viewWidth - u0) / fx * near;
var t = v0 / fy * near;
var b = (v0 - viewHeight) / fy * near;
var A = (far + near) / (near - far);
var B = 2 * (far * near) / (near - far);
projectionMatrix.set(2*near/(r-l), 0, (r + l) / (r - l), 0,
0, 2*near/(t - b), (t + b) / (t - b), 0,
0, 0, A, B,
0, 0, -1, 0);
// 可以修改 R/t 数据,但可能会有些困难,算错了可能会让物体不在视野范围内
// You can modify the R/t data, but the object is not visible if you provide wrong data.
transformMatrix.set(-0.7071, 0.7071, 0, 0,
-0.4083, -0.4083, 0.8165, 0,
0.5774, 0.5774, 0.5774, -86.603,
0, 0, 0, 1);
}
// You can random setup the default value of PerspectiveCamera below, it will be replaced by the projectionMatrix above
var camera = new THREE.PerspectiveCamera( 45, viewWidth / viewHeight, near, far ); // 随意设置,会被后面的替换
camera.projectionMatrix = projectionMatrix; // 设置投影矩阵取代上面初始化时候的设置
// 注意! three.js 里面camera定义的矩阵是世界坐标系到相机坐标系的变换矩阵,和我常用的定义相反,因此需要求逆.
// 如果在OpenGL里面直接操作ModelView那个矩阵则不用求逆
// Note! The matrix defined in the camera in three.js is the transformation matrix from the world coordinate system to the camera coordinate system,
// which is opposite to the definition I often use, so it needs to be inverted.
// If you directly operate the ModelView matrix in OpenGL, you don't need to invert it.
camera.applyMatrix(transformMatrix.getInverse(transformMatrix));
// [u;v;1] = K * (R * [x; y; z] + t)) / zc
// 注意这里使用的 R 和 t 就是transformMatrix里面的值,不用求逆
// Note that the R and t used here are the values in transformMatrix, no need to invert
var O = new THREE.Vector3( 0, 0, 0); // original point in world; calculate (u, v) yourself,or you can refer to projection.py
var X = new THREE.Vector3( 10, 0, 0); // a point on axis x;
var Y = new THREE.Vector3( 0, 10, 0); // a point on axis y;
var Z = new THREE.Vector3( 0, 0, 10); // a point on axis z;
var P = new THREE.Vector3( 10, 15, 20); // an arbitrary point;
var Q = new THREE.Vector3( -10, 15, -20); // another arbitrary point;
var scene = new THREE.Scene();
addVector(scene, O, X, 0xff0000);
addVector(scene, O, Y, 0x00ff00);
addVector(scene, O, Z, 0x0000ff);
addVector(scene, O, P, 0xffffff);
addVector(scene, O, Q, 0xff00ff);
// 图形渲染完毕后可以将鼠标移至上面那些点的位置,查看是否与上面计算的的图像坐标(u, v)一致
// After the graphics are rendered, you can move the mouse to the position of those points above to see
//if the image coordinates (u, v) calculated above are consistent
document.addEventListener("mousemove", function(event) {
console.log("Mouse position:", event.clientX, event.clientY);
});
var renderer = new THREE.WebGLRenderer();
renderer.setSize( windowWidth, windowHeight ); // the window size of the entire UI
// 这里的(viewStartX, viewStartY)是左上角点,而OpenGL 中的 glViewport 是左下角点
// The (viewStartX, viewStartY) here is the upper left corner point, while the glViewport in OpenGL is the lower left corner point
renderer.setViewport(viewStartX, viewStartY, viewWidth, viewHeight);
document.body.appendChild( renderer.domElement );
renderer.render(scene, camera);
function addVector(scene, startPoint, endPoint, color) {
var geometry = new THREE.Geometry();
geometry.vertices.push(startPoint);
geometry.vertices.push(endPoint);
var material = new THREE.LineBasicMaterial( { color: color });
var line = new THREE.Line( geometry, material );
scene.add( line );
}
</script>
</body>
</html>