/// <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); } }
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(); }