private void AddCube(Point coordinates, int index)
        {
            var l = new List<Solid>();
            var k = new Solid();
            //MathOperations.DebugMatrix(k.Points);
            switch (index) {
                case 0:
                    k.Points = MathOperations.MatrixMultiplication(
                        MathOperations.Translation(coordinates.X, 0, coordinates.Y), k.Points);
                    k.ComputeVisibility(new Vector(0, 1, 0));
                    break;
                case 1:
                    k.Points = MathOperations.MatrixMultiplication(
                        MathOperations.Translation(0, coordinates.Y, coordinates.X), k.Points);
                    k.ComputeVisibility(new Vector(1, 0, 0));
                    break;
                case 2:
                    k.Points = MathOperations.MatrixMultiplication(
                        MathOperations.Translation(coordinates.X, coordinates.Y, 0), k.Points);
                    k.ComputeVisibility(new Vector(0, 0, 1));
                    break;
            }

            //MathOperations.DebugMatrix(k.Points);
            l.Add(k);

            solidsList.Add(l);
            //Console.WriteLine(l[0]);
        }
        public void DrawSelectedSolid(Solid solid, Solid perspectiveSolid,Pen pen = null)
        {
            DrawSolidFaces(solid, topView, 0, pen);

            DrawSolidFaces(solid, frontView, 1, pen);

            DrawSolidFaces(solid, leftView, 2, pen);

            DrawSolidFaces(perspectiveSolid, perspectiveBox, 3, pen ?? new Pen(Color.Black, 1));
        }
        private void FlatPaint(PictureBox pc, Solid solid, int x, int y)
        {
            var g = Graphics.FromImage(pc.Image);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            for (var i = 0; i < 6; i++) {
                if (solid.FlatColor[i] == null) continue;
                var face = new Point[4];
                face[0] = new Point((int)solid.Points[x, solid.Faces[i, 0]], (int)solid.Points[y, solid.Faces[i, 0]]);
                face[1] = new Point((int)solid.Points[x, solid.Faces[i, 1]], (int)solid.Points[y, solid.Faces[i, 1]]);
                face[2] = new Point((int)solid.Points[x, solid.Faces[i, 2]], (int)solid.Points[y, solid.Faces[i, 2]]);
                face[3] = new Point((int)solid.Points[x, solid.Faces[i, 3]], (int)solid.Points[y, solid.Faces[i, 3]]);

                g.FillPolygon(new SolidBrush(Color.FromArgb((int)solid.FlatColor[i].X, (int)solid.FlatColor[i].Y, (int)solid.FlatColor[i].Z)), face);
            }
        }
        private void DrawSolidFaces(Solid solid, PictureBox pc, int ipc, Pen myPen = null)
        {
            var x = 0;
            var y = 0;
            switch (ipc) {
                case 0:        //Top View
                    x = 0;
                    y = 2;
                    solid.ComputeVisibility(new Vector(solid.Points[0, 8], 1, solid.Points[2, 8]));
                    break;
                case 1:       //Front View
                    x = 0;
                    y = 1;
                    solid.ComputeVisibility(new Vector(solid.Points[0, 8], solid.Points[1, 8], 1));
                    break;
                case 2:       //Left View
                    x = 2;
                    y = 1;
                    solid.ComputeVisibility(new Vector(1, solid.Points[1, 8], solid.Points[2, 8]));
                    break;
                case 3:     //Perspective
                    x = 0;
                    y = 1;
                    if (isometricCheckBox.Checked) {
                        solid.ComputeVisibility(new Vector(0, 0, 1), new Vector(0, 0, 0));
                    } else {
                        solid.ComputeVisibility(VRP, P);
                    }

                    break;

            }
            var g = Graphics.FromImage(pc.Image);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            if (myPen == null) {
                myPen = new Pen(Color.Black, 1);
            }

            var matrix = solid.Points;
            for (var i = 0; i < 6; i++) {
                if (!solid.VisibleFaces[i] && hideFacesBox.Checked) continue;
                for (int j = 0; j < 3; j++) {
                    g.DrawLine(myPen, (float)matrix[x, solid.Faces[i, j]],
                        (float)matrix[y, solid.Faces[i, j]],
                        (float)matrix[x, solid.Faces[i, j + 1]],
                        (float)matrix[y, solid.Faces[i, j + 1]]);
                }
                g.DrawLine(myPen, (float)matrix[x, solid.Faces[i, 3]],
                    (float)matrix[y, solid.Faces[i, 3]],
                    (float)matrix[x, solid.Faces[i, 0]],
                    (float)matrix[y, solid.Faces[i, 0]]);
            }
            pc.Invalidate();
        }
        public void FlatShading(Solid solid, PictureBox pc) {
            Vector iT;
            Vector iA;
            Vector iD;
            Vector iS;
            Vector R;
            Vector S;
            Vector Pm;


            for (int i = 0; i < 6; i++) {

                iA = new Vector();
                iA.X = iLa.X * solid.Ka.X;
                iA.Y = iLa.Y * solid.Ka.Y;
                iA.Z = iLa.Z * solid.Ka.Z;

                if (solid.VisibleFaces[i] == false) {
                    solid.FlatColor[i] = null;
                    continue;
                }


                iD = new Vector(0, 0, 0);
                iS = new Vector(0, 0, 0);
                Vector N = solid.NormalFaces[i];
                Pm = new Vector();
                Pm.X = (solid.Points[0, solid.Faces[i, 0]] + solid.Points[0, solid.Faces[i, 2]]) / 2;
                Pm.Y = (solid.Points[1, solid.Faces[i, 0]] + solid.Points[1, solid.Faces[i, 2]]) / 2;
                Pm.Z = (solid.Points[2, solid.Faces[i, 0]] + solid.Points[2, solid.Faces[i, 2]]) / 2;
                L = new Vector(L.X - Pm.X, L.Y - Pm.Y, L.Z - Pm.Z);
                L = MathOperations.NormalizeVector(L);
                double value = MathOperations.DotProduct(N, L);

                if (value > 0) {
                    iD.X = iL.X * solid.Kd.X * value;
                    iD.Y = iL.Y * solid.Kd.Y * value;
                    iD.Z = iL.Z * solid.Kd.Z * value;

                    R = new Vector();
                    R.X = (2 * value * N.X) - L.X;
                    R.Y = (2 * value * N.Y) - L.Y;
                    R.Z = (2 * value * N.Z) - L.Z;

                    S = new Vector();

                    S.X = VRP.X - Pm.X;
                    S.Y = VRP.Y - Pm.Y;
                    S.Z = VRP.Z - Pm.Z;
                    S = MathOperations.NormalizeVector(S);

                    double value2 = Math.Pow(MathOperations.DotProduct(R, S), solid.N);
                    iS.X = iL.X * solid.Ks.X * value2;
                    iS.Y = iL.Y * solid.Ks.Y * value2;
                    iS.Z = iL.Z * solid.Ks.Z * value2;
                }

                iT = new Vector();
                iT.X = iA.X + iD.X + iS.X;
                iT.Y = iA.Y + iD.Y + iS.Y;
                iT.Z = iA.Z + iD.Z + iS.Z;


                solid.FlatColor[i] = new Vector(iT.X, iT.Y, iT.Z);
            }
        }