using System; namespace bbiwarg.Utility { /// /// Converts between 2d and 3d coordinates. /// public class CoordinateConverter { /// /// the horizontal field of view angle /// private float fieldOfViewHorizontal; /// /// the vertical field of view angle /// private float fieldOfViewVertical; /// /// size of the image the coordinates are from /// private ImageSize imageSize; /// /// tangens of fieldOfViewHorizontal / 2 /// private float relativeRatioHorizontal; /// /// tanges of fieldOfViewVertical / 2 /// private float relativeRatioVertical; /// /// Constructs a CoordinateConverter. /// /// size of the image the coordinates are from /// horizontal field of view angle /// vertical field of view angle public CoordinateConverter(ImageSize imageSize, float hfov, float vfov) { this.imageSize = imageSize; this.fieldOfViewHorizontal = hfov; this.fieldOfViewVertical = vfov; relativeRatioHorizontal = (float)Math.Tan(hfov / 2); relativeRatioVertical = (float)Math.Tan(vfov / 2); } /// /// 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 cooridnate of the position /// the depth /// the 3d position public Vector3D convertCoordinate2Dto3D(float x, float y, float depth) { float deltaX = 2 * ((x / imageSize.Width) - 0.5f); float deltaY = -2 * ((y / imageSize.Height) - 0.5f); float tanX = deltaX * relativeRatioHorizontal; float tanY = deltaY * relativeRatioVertical; 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 linesegment parallel to the camera at the given depth to the length of the linesegment in 2d. /// /// 3d length of the linesegment /// depth of the linesegment /// 2d length of the linesegment public float convertLength3Dto2D(float length, float depth) { float fullLengthX = (float)(2 * Math.Cos(fieldOfViewHorizontal / 2) * depth); float fullLengthY = (float)(2 * Math.Cos(fieldOfViewVertical / 2) * depth); float fullLengthDiagonal = (float)Math.Sqrt(Math.Pow(fullLengthX, 2) + Math.Pow(fullLengthY, 2)); float ratio = length / fullLengthDiagonal; return ratio * imageSize.DiagonalLength; } } }