using System; using BBIWARG.Input.InputProviding; namespace BBIWARG.Utility { /// /// Converts between 2d and 3d coordinates. /// public class CoordinateConverter { private IInputProvider inputProvider; /// /// Constructs a CoordinateConverter. /// /// size of the image the coordinates are from /// horizontal field of view angle /// vertical field of view angle public CoordinateConverter(IInputProvider inputProvider) { this.inputProvider = inputProvider; } /// /// Converts a point with a depth to a 3d position. /// /// the point /// the depth /// the 3d position public Vector3D convertCoordinate2Dto3D(Vector2D p, float depth) { return convertCoordinate2Dto3D(p.X, p.Y, depth); } /// /// Converts a position with a depth to a 3d position. /// /// x coordinate of the position /// y coordinate of the position /// the depth /// the 3d position public Vector3D convertCoordinate2Dto3D(float x, float y, float depth) { float deltaX = 2 * ((x / inputProvider.ImageWidth) - 0.5f); float deltaY = -2 * ((y / inputProvider.ImageHeight) - 0.5f); float tanX = deltaX * (float)Math.Tan(inputProvider.FieldOfViewHorizontal / 2); float tanY = deltaY * (float)Math.Tan(inputProvider.FieldOfViewVertical / 2); float a = depth * depth; float b = (float)(Math.Pow(tanX, 2) + Math.Pow(tanY, 2)); float z3 = (float)Math.Sqrt(0.5f * a + Math.Sqrt(0.25f * Math.Pow(a, 2) - b)); float x3 = tanX * z3; float y3 = tanY * z3; return new Vector3D(x3, y3, z3); } /// /// Converts the length of a 3d line segment parallel to the camera at the given depth to the length of the line segment in 2d. /// /// 3d length of the line segment /// depth of the line segment /// 2d length of the line segment public float convertLength3Dto2D(float length, float depth) { float fullLengthX = (float)(2 * Math.Cos(inputProvider.FieldOfViewHorizontal / 2) * depth); float fullLengthY = (float)(2 * Math.Cos(inputProvider.FieldOfViewVertical / 2) * depth); float fullLengthDiagonal = (float)Math.Sqrt(Math.Pow(fullLengthX, 2) + Math.Pow(fullLengthY, 2)); float ratio = length / fullLengthDiagonal; float imageSizeDiagonalLength = (float)Math.Sqrt(inputProvider.ImageWidth * inputProvider.ImageWidth + inputProvider.ImageHeight * inputProvider.ImageHeight); return ratio * imageSizeDiagonalLength; } } }