2017-11-20 13 views
0

3D 좌표를 가져 와서 2D 좌표로 변경하는 알고리즘을 찾고 있습니다. https://en.wikipedia.org/wiki/3D_projection#Perspective_projection3D에서 2D 투영 알고리즘 (투시 투영법) - 자바 스크립트

내 코드는 지금까지 이것이다 :

나는 단계는이 위키 백과 페이지 형성 시도

 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 
 
     \t 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 
 
     \t 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(){ 
 
     \t for (key in point){ 
 
     \t 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 { 
 
     \t width: 100%; 
 
     height: 100%; 
 
     margin: 0; 
 
     padding: 0; 
 
     
 
     background: rgba(73,72,62,.99); 
 
     } 
 
     canvas { 
 
     \t position: absolute; 
 
     margin: auto; 
 
     top: 0; 
 
     bottom: 0; 
 
     left: 0; 
 
     right: 0; 
 
     
 
     outline: 1px solid white; 
 
     }
<html> 
 
    <head> 
 
    </head> 
 
    <body> 
 
    </body> 
 
</html>

내가 따라 2D로 3D를 변환 할 수있는 기능을 원하는 카메라의 위치와 회전 모두에서 위키 백과 페이지를 살펴보면

답변

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 좌표에도 오류가 있습니다. 당신은 Ey 대신에 Ez를 사용합니다.

또한 this site을 추천 할 수 있습니다. C++과 OpenGL 용으로 작성되었지만, 여러분이하고 싶은 것을 더 잘 이해할 수 있도록 많은 설명과 도표가 포함되어 있습니다.