/// <summary> /// Convert the world coordinates to pixel coordinates. /// </summary> /// <remarks> /// TODO: There is conversion between Point3D and Vector3D because /// matrix multiplication doesn't work nicely with the Vector3D class. /// http://stackoverflow.com/questions/34097628/use-of-offsets-for-translation-in-matrix3d /// </remarks> /// <param name="worldCoords">The world coordinates.</param> /// <returns>A list of pixel coords.</returns> private List <Point> GetRasterPoints(List <Point3D> worldCoords) { // Setup camera position in the world. // The camera will look down the negative z axis. Matrix3D cameraToWorld = new Matrix3D(); cameraToWorld.Rotate(new Quaternion(new Vector3D(0, 1, 0), 180)); cameraToWorld.Translate(new Vector3D(0, 2, 0.5)); // Create the world to camera coordinates matrix. cameraToWorld.Invert(); Matrix3D worldToCamera = cameraToWorld; // Convert the Point3D to Vector3D so the spline can do vector operations. List <Vector3D> quadCoords = new List <Vector3D>(); foreach (Point3D point in worldCoords) { quadCoords.Add((Vector3D)point); } NaturalSpline airfoilSpline = new NaturalSpline(quadCoords); // Convert the Vector3D back to Point3D. worldCoords.Clear(); foreach (Vector3D point in airfoilSpline.Points) { worldCoords.Add((Point3D)point); } // Compute the final pixel coordinates. List <Point> rasterCoords = new List <Point>(); foreach (Point3D worldCoord in worldCoords) { Point3D raster = worldToCamera.ComputePixelCoordinates( worldCoord, canvasWidth, canvasHeight, DrawRegion.Width, DrawRegion.Height); rasterCoords.Add(new Point((int)raster.X, (int)raster.Y)); } return(rasterCoords); }