The Point class of the three-dimensional space contains methods for rotations by an angle and for obtaining projections onto a plane. When obtaining projections, the distance from the point to the projection center is calculated. Point also contains a static method to compare two projections of points. {% capture collapsed_md %} ```js class Point { // point coordinates constructor(x,y,z) { this.x=x; this.y=y; this.z=z; } // rotate this point by an angle (deg) along // axes (x,y,z) relative to the point (t0) rotate(deg, t0) { // functions to obtain sine and cosine of angle in radians const sin = (deg) => Math.sin((Math.PI/180)*deg); const cos = (deg) => Math.cos((Math.PI/180)*deg); // calculate new coordinates of point using the formulas // of the rotation matrix for three-dimensional space let x,y,z; // rotation along 'x' axis y = t0.y+(this.y-t0.y)*cos(deg.x)-(this.z-t0.z)*sin(deg.x); z = t0.z+(this.y-t0.y)*sin(deg.x)+(this.z-t0.z)*cos(deg.x); this.y=y; this.z=z; // rotation along 'y' axis x = t0.x+(this.x-t0.x)*cos(deg.y)-(this.z-t0.z)*sin(deg.y); z = t0.z+(this.x-t0.x)*sin(deg.y)+(this.z-t0.z)*cos(deg.y); this.x=x; this.z=z; // rotation along 'z' axis x = t0.x+(this.x-t0.x)*cos(deg.z)-(this.y-t0.y)*sin(deg.z); y = t0.y+(this.x-t0.x)*sin(deg.z)+(this.y-t0.y)*cos(deg.z); this.x=x; this.y=y; } // get a projection of (type) from a distance (d) // onto the plane of the observer screen (tv) projection(type, tv, d) { let proj = {}; // obtain a projection using experimental formulas switch (type) { case 'parallel': { proj.x = this.x; proj.y = this.y+(tv.y-this.z)/4; break; } case 'perspective': { proj.x = tv.x+d*(this.x-tv.x)/(this.z-tv.z+d); proj.y = tv.y+d*(this.y-tv.y)/(this.z-tv.z+d); break; } } // calculate distance to projection center proj.dist = Math.sqrt((this.x-tv.x)*(this.x-tv.x) +(this.y-tv.y)*(this.y-tv.y) +(this.z-tv.z+d)*(this.z-tv.z+d)); return proj; } // compare two projections of points (p1,p2), // coordinates (x,y) should match static pEquals(p1, p2) { return Math.abs(p1.x-p2.x)<0.0001 && Math.abs(p1.y-p2.y)<0.0001; } }; ``` {% endcapture %} {%- include collapsed_block.html summary="class Point" content=collapsed_md -%} The Cube class contains a collection of vertices of the Point class and an array of faces. Each face is an array of 4 vertices, coming from the same point and going clockwise. The Cube contains methods for rotating all vertices by an angle and for obtaining projections of all faces onto a plane. When obtaining projections, the tilt of the face is calculated — this is the remoteness from the projection plane. The cube also contains two static methods for comparing two face projections: for defining the equidistant faces from the projection center and adjacent walls between neighboring cubes. {% capture collapsed_md %} ```js class Cube { // left upper near coordinate and size constructor(x,y,z,size) { // right lower distant coordinate let xs=x+size,ys=y+size,zs=z+size; let v={ // vertices t000: new Point(x,y,z), // top t001: new Point(x,y,zs), // top t010: new Point(x,ys,z), // bottom t011: new Point(x,ys,zs), // bottom t100: new Point(xs,y,z), // top t101: new Point(xs,y,zs), // top t110: new Point(xs,ys,z), // bottom t111: new Point(xs,ys,zs)};// bottom this.vertices=v; this.faces=[ // faces [v.t000,v.t100,v.t110,v.t010], // front [v.t000,v.t010,v.t011,v.t001], // left [v.t000,v.t001,v.t101,v.t100], // upper [v.t001,v.t011,v.t111,v.t101], // rear [v.t100,v.t101,v.t111,v.t110], // right [v.t010,v.t110,v.t111,v.t011]];// lower } // rotate vertices of the cube by an angle (deg) // along axes (x,y,z) relative to the point (t0) rotate(deg, t0) { for (let vertex in this.vertices) this.vertices[vertex].rotate(deg, t0); } // get projections of (type) from a distance (d) // onto the plane of the observer screen (tv) projection(type, tv, d) { let proj = []; for (let face of this.faces) { // face projection, array of vertices let p = []; // cumulative remoteness of vertices p.dist = 0; // bypass the vertices of the face for (let vertex of face) { // obtain the projections of the vertices let proj = vertex.projection(type, tv, d); // accumulate the remoteness of vertices p.dist+=proj.dist; // add to array of vertices p.push(proj); } // calculate face tilt, remoteness from the projection plane p.clock = ((p[1].x-p[0].x)*(p[2].y-p[0].y) -(p[1].y-p[0].y)*(p[2].x-p[0].x))<0; proj.push(p); } return proj; } // compare two projections of faces (f1,f2), vertices // should be equidistant from the center of projection static pEquidistant(f1, f2) { return Math.abs(f1.dist-f2.dist)<0.0001; } // compare two projections of faces (f1,f2), coordinates // of points along the main diagonal (p0,p2) should match static pAdjacent(f1, f2) { return Point.pEquals(f1[0],f2[0]) && Point.pEquals(f1[2],f2[2]); } }; ``` {% endcapture %} {%- include collapsed_block.html summary="class Cube" content=collapsed_md -%}