using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bbiwarg.Utility
{
///
/// Converts between 2d and 3d coordinates.
///
public class CoordinateConverter
{
///
/// size of the image the coordinates are from
///
private ImageSize imageSize;
///
/// the horizontal field of view angle
///
private float hfov;
///
/// the vertical field of view angle
///
private float vfov;
///
/// tangens of hfov / 2
///
private float hRatio;
///
/// tanges of vfov / 2
///
private float vRatio;
///
/// 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.hfov = hfov;
this.vfov = vfov;
hRatio = (float)Math.Tan(hfov / 2);
vRatio = (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 * hRatio;
float tanY = deltaY * vRatio;
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(hfov / 2) * depth);
float fullLengthY = (float)(2 * Math.Cos(vfov / 2) * depth);
float fullLengthDiagonal = (float)Math.Sqrt(Math.Pow(fullLengthX, 2) + Math.Pow(fullLengthY, 2));
float ratio = length / fullLengthDiagonal;
return ratio * imageSize.DiagonalLength;
}
}
}