Advertisement
fevzi02

6lab КГ 3vers

Jan 30th, 2022
1,392
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 4.81 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <link rel="shortcut icon" href="images/faviconClass.png" type="image/png">
  5. </head>
  6.     <body>
  7.         <canvas id="pic" width="700" height="700" style="border:1px solid red">
  8.         </canvas><br>
  9.         <button onclick="ctx.clearRect(0,0,700,700);">clear</button><br>
  10.         <button onclick="draw(0,0)">draw</button>
  11.  
  12.         <script type="text/javascript">
  13.             let _ = undefined;
  14.             let c = document.getElementById('pic');
  15.             let ctx = c.getContext('2d');
  16.             let shape = []
  17.             let xRotation=0, yRotation=0;
  18.             let prevPointer = [];
  19.             let ctxClicked = false;
  20.       let K = 30;
  21.  
  22.             class Point
  23.             {
  24.                 constructor(f, x, z)
  25.                 {
  26.           let dx = 0.12;
  27.               let dz = 0.12;
  28.                     let y = f(x, z);
  29.                     let d = 0;
  30.                     let dydx = (f(x+dx, z)+d - f(x-dx, z)+d)/(dx*2);
  31.                     let dydz = (f(x, z+dz)+d - f(x, z-dz)+d)/(dz*2);
  32.                     let div = Math.sqrt(dydx*dydx + 1 + dydz*dydz);
  33.                     this.point = [x, y, z];
  34.                     this.normal = [-(dydx/div), -1, -(dydz/div)];
  35.                     this.N = Math.sqrt(this.normal[0]*this.normal[0]+this.normal[1]*this.normal[1]+this.normal[2]*this.normal[2]); // длина вектора
  36.                 }
  37.  
  38.             }
  39.       let osi = [[0, 0, 0], [10, 0, 0], [0,-10,0], [0, 0, 10]]
  40.       let colOSI = ["red", "green", "blue"]
  41.  
  42.             //DIRECT COMPUTATION PART
  43.             let F = (x, z) => { return Math.sin(x+z)/(x+z)*(-4); }
  44.       let temp;
  45.             for(let z=-5; z<5; z+=0.12)
  46.             {
  47.                 temp = [];
  48.                 for(let x=-5; x<5; x+=0.12)
  49.                 {
  50.                     temp.push(new Point(F, x, z));
  51.                 }
  52.                 shape.push(temp);
  53.             }
  54.             //EVENT ATTACHMENT
  55.             c.onmousedown = (e)=>{ ctxClicked = true; prevPointer = [e.pageX-8, e.pageY-8];}
  56.             c.onmouseup   = (e)=>
  57.             {
  58.                 ctxClicked = false;
  59.                 prevPointer = [];
  60.             }
  61.             c.onmousemove = (e)=>
  62.             {
  63.                 if(ctxClicked)
  64.                 {
  65.                     x = e.pageX-8;
  66.                     y = e.pageY-8;
  67.                     if(prevPointer[0]!=x || prevPointer[1]!=y)
  68.                     {
  69.                         xRotation = ((x - prevPointer[0]))/(Math.PI*180);
  70.                         yRotation = ((y - prevPointer[1]))/(Math.PI*180);
  71.                         draw(-yRotation, -xRotation);
  72.                         prevPointer = [x, y];
  73.                     }
  74.                 }
  75.             }
  76.  
  77.  
  78.             function rotate(x, y, z, axis=0, alpha=undefined) // axis 1=x, 2=y, 3=z. 0=no rotation
  79.             {
  80.                 if(axis==0 || alpha===undefined) return [x, y, z];
  81.                 else if(axis==1) return [x, y*Math.cos(alpha)+z*Math.sin(alpha), -y*Math.sin(alpha)+z*Math.cos(alpha)];
  82.                 else if(axis==2) return [x*Math.cos(alpha)+z*Math.sin(alpha), y, -x*Math.sin(alpha)+z*Math.cos(alpha)];
  83.                 else if(axis==3) return [x*Math.cos(alpha)+y*Math.sin(alpha), -x*Math.sin(alpha)+y*Math.cos(alpha), z];
  84.             }
  85.  
  86.       function getProjectionXY(x, y, z, k=K, x_bias=350, y_bias=350) // default is k=120, coeff=0.1, bias=20
  87.             {
  88.                 let scale = 50;
  89.                 return [((k*x)/(z+k))*scale+x_bias, ((k*y)/(z+k))*scale+y_bias];
  90.             }
  91.  
  92.             function draw(degreesX, degreesY)
  93.             {
  94.                 ctx.clearRect(0, 0, 700, 700);
  95.  
  96.                 for(const i in shape)
  97.                 {
  98.                     ctx.beginPath();
  99.                     shape[i][0].point =  rotate(...rotate(...shape[i][0].point, 1, degreesX), 2, degreesY);
  100.                     shape[i][0].normal =  rotate(...rotate(...shape[i][0].normal, 1, degreesX), 2, degreesY);
  101.                     ctx.moveTo(...getProjectionXY(...shape[i][0].point));
  102.                     for(const j in shape[i])
  103.                     {
  104.                         if(j != 0)
  105.                         {
  106.                             shape[i][j].point = rotate(...rotate(...shape[i][j].point, 1, degreesX), 2, degreesY);
  107.                             shape[i][j].normal = rotate(...rotate(...shape[i][j].normal, 1, degreesX), 2, degreesY);
  108.                             shape[i][j].N = Math.sqrt(shape[i][j].normal[0]*shape[i][j].normal[0] + shape[i][j].normal[1]*shape[i][j].normal[1] + shape[i][j].normal[2]*shape[i][j].normal[2]);
  109.                             ctx.fillStyle = 'red';
  110.                             ctx.fillRect(...getProjectionXY(...shape[i][j].point),2,2);
  111.                             if((shape[i][j].normal[2]*(-K))/(shape[i][j].N*Math.sqrt(K*K)) >= 0) // скалярное произведение (угол между направлением на камеру и нормалью к точке)
  112.                             {
  113.  
  114.                                 ctx.fillStyle = 'green';
  115.                                 ctx.fillRect(...getProjectionXY(...shape[i][j].point),2,2);
  116.                             }
  117.                         }
  118.                     }
  119.                     ctx.stroke();
  120.                     ctx.closePath();
  121.                 }
  122.         osi[0] =  rotate(...rotate(...osi[0], 1, degreesX), 2, degreesY);
  123.  
  124.  
  125.                   for(const j in osi)
  126.                   {   ctx.beginPath();
  127.                       ctx.moveTo(...getProjectionXY(...osi[0]));
  128.                       if(j != 0)
  129.                       {
  130.                           osi[j] = rotate(...rotate(...osi[j], 1, degreesX), 2, degreesY);
  131.                           ctx.lineTo(...getProjectionXY(...osi[j]));
  132.                           ctx.strokeStyle = colOSI[j-1];
  133.                           ctx.stroke();
  134.                           ctx.closePath();
  135.                       }
  136.                   }
  137.                   ctx.stroke();
  138.                   ctx.closePath();
  139.             }
  140.       draw(0,0)
  141.         </script>
  142.     </body>
  143. </html>
  144.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement