我正在寻找采用3D坐标并将其更改为2D坐标的算法。
我尝试了这个维基百科页面的步骤:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection
我的代码到目前为止是这样的:
var WIDTH = 1280/2;
var HEIGHT = 720/2;
// Distance from center of Canvas (Camera) with a Field of View of 90 digress, to the Canvas
var disToCanvas = Math.tan(45) * WIDTH/2;
var canvas = document.createElement('canvas');
canvas.width = WIDTH;
canvas.height = HEIGHT;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
var Player = function (){ // Camera
// Camera Coordinates
this.x = 0;
this.y = 0;
this.z = 0;
// Camera Rotation (Angle)
this.rx = 0;
this.ry = 90;
this.rz = 0;
};
var player = new Player();
var Point = function (x, y ,z){
// Point 3D Coordinates
this.x = x;
this.y = y;
this.z = z;
// Point 2D Coordinates
this.X2d = 0;
this.Y2d = 0;
// The function that changes 3D coordinates to 2D
this.update = function (){
var X = (player.x - this.x);
var Y = (player.y - this.y);
var Z = (player.z - this.z);
var Cx = Math.cos(player.rx); // cos(θx)
var Cy = Math.cos(player.ry); // cos(θy)
var Cz = Math.cos(player.rz); // cos(θz)
var Sx = Math.sin(player.rx); // sin(θx)
var Sy = Math.sin(player.ry); // sin(θy)
var Sz = Math.sin(player.rz); // sin(θz)
var Dx = Cy * (Sy*Y + Cz*X) - Sy*Z;
var Dy = Sx * (Cy*Z + Sy * (Sz*Y + Cz*X)) + Cx * (Cy*Y + Sz*X);
var Dz = Cx * (Cy*Z + Sy * (Sz*Y + Cz*X)) - Sx * (Cy*Y + Sz*X);
var Ex = this.x / this.z * disToCanvas; // This isn't 100% correct
var Ey = this.y / this.z * disToCanvas; // This isn't 100% correct
var Ez = disToCanvas; // This isn't 100% correct
this.X2d = Ez/Dz * Dx - Ex + WIDTH/2; // Adding WIDTH/2 to center the camera
this.Y2d = Ez/Dz * Dy - Ez + HEIGHT/2; // Adding HEIGHT/2 to center the camera
}
}
// CREATING, UPDATING AND RENDERING A SQUARE
var point = [];
point[0] = new Point(10, 10, 10);
point[1] = new Point(20, 10, 10);
point[2] = new Point(20, 20, 10);
point[3] = new Point(10, 20, 10);
var run = setInterval(function (){
for (key in point){
point[key].update();
}
ctx.beginPath();
ctx.moveTo(point[0].X2d, point[0].Y2d);
ctx.lineTo(point[1].X2d, point[1].Y2d);
ctx.lineTo(point[2].X2d, point[2].Y2d);
ctx.lineTo(point[3].X2d, point[3].Y2d);
ctx.lineTo(point[0].X2d, point[0].Y2d);
}, 1000/30);
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: rgba(73,72,62,.99);
}
canvas {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
outline: 1px solid white;
}
<html>
<head>
</head>
<body>
</body>
</html>
我想要一个可以根据相机的位置和旋转将3D转换为2D的功能。
答案 0 :(得分:1)
看一下你链接的维基百科页面,看来你的方程式中有D的错误。它应该是:
var Dx = Cy * (Sz*Y + Cz*X) - Sy*Z;
var Dy = Sx * (Cy*Z + Sy * (Sz*Y + Cz*X)) + Cx * (Cz*Y + Sz*X);
var Dz = Cx * (Cy*Z + Sy * (Sz*Y + Cz*X)) - Sx * (Cz*Y + Sz*X);
此外,我认为您使用错误的坐标E,即“观察者相对于显示表面的位置”,并且不应该取决于该点的坐标。
2D位置的y坐标似乎也包含错误;你使用Ez而不是Ey。
此外,我可以推荐this site。它是为C ++和OpenGL编写的,但它包含了很多很好的解释和图表,可以更好地理解你想要做什么。