예제 #1
0
        /// <summary>
        /// Calculates the triangles position on the screen and adds them to the screens collection of triangles.
        /// </summary>
        public void ProjectToScreen()
        {
            screen.ClearTriangles();

            //Used for angle calculation.
            Vect3D toPointVector;
            Vect3D toPointVerticalPlaneNormalVector;
            Vect3D toPointHorizontalPlaneNormalVector;

            //Angles.
            double angleLeft;
            double angleTop;

            //Position on screen: 0 = left/top, 1 = right/bottom.
            double screenScalar;

            Point[] triangleCoordinatesOnScreen;
            BackFaceCulling();
            foreach (int triangleIndex in trianglesOnScreenIndex)
            {
                triangleCoordinatesOnScreen = new Point[3];
                for (int i = 0; i < 3; i++)
                {
                    toPointVector = new Vect3D(CameraPosition, triangles[triangleIndex].coordinates[i]);

                    toPointVerticalPlaneNormalVector   = Vect3D.VectorProduct(toPointVector, cameraVerticalUnitVector);
                    toPointHorizontalPlaneNormalVector = Vect3D.VectorProduct(toPointVector, cameraHorizontalUnitVector);
                    angleLeft = Relation3D.AngleBetween(toPointVerticalPlaneNormalVector, cameraLeftPlaneNormalVector);
                    angleTop  = Relation3D.AngleBetween(toPointHorizontalPlaneNormalVector, cameraTopPlaneNormalVector);

                    toPointVerticalPlaneNormalVector.SwitchOrientation();
                    toPointHorizontalPlaneNormalVector.SwitchOrientation();

                    screenScalar = widthScalar * Math.Sin(angleLeft) / Math.Sin(Math.PI - angleLeft - (Math.PI - CameraFieldOfView) / 2);
                    if (Relation3D.AngleBetween(toPointVerticalPlaneNormalVector, cameraRightPlaneNormalVector) > CameraFieldOfView)
                    {
                        screenScalar *= -1;
                    }
                    triangleCoordinatesOnScreen[i].X = Math.Round(screenScalar * screen.Width, 0);

                    screenScalar = heightScalar * Math.Sin(angleTop) / Math.Sin(Math.PI - angleTop - (Math.PI - (CameraFieldOfView / AspectRatio)) / 2);
                    if (Relation3D.AngleBetween(toPointHorizontalPlaneNormalVector, cameraBottomPlaneNormalVector) > CameraFieldOfView / AspectRatio)
                    {
                        screenScalar *= -1;
                    }
                    triangleCoordinatesOnScreen[i].Y = Math.Round(screenScalar * screen.Height, 0);
                }
                screen.AddTriangleToScreen(triangleCoordinatesOnScreen);
            }
        }
예제 #2
0
        public void BackFaceCulling()
        {
            Stack <int> trianglesIndex = new Stack <int>();
            Vect3D      camToCorner;
            Vect3D      cornerVector1;
            Vect3D      cornerVector2;

            foreach (int index in trianglesOnScreenIndex)
            {
                cornerVector1 = new Vect3D(triangles[index].coordinates[0], triangles[index].coordinates[1]);
                cornerVector2 = new Vect3D(triangles[index].coordinates[0], triangles[index].coordinates[2]);
                camToCorner   = new Vect3D(CameraPosition, triangles[index].coordinates[0]);
                if (Vect3D.VectorProduct(cornerVector1, cornerVector2) * camToCorner >= 0.0)
                {
                    trianglesIndex.Push(index);
                }
            }
            trianglesOnScreenIndex = trianglesIndex.ToArray();
        }