CoordinateConverter.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. namespace BBIWARG.Utility
  3. {
  4. /// <summary>
  5. /// Converts between 2d and 3d coordinates.
  6. /// </summary>
  7. public class CoordinateConverter
  8. {
  9. /// <summary>
  10. /// the horizontal field of view angle
  11. /// </summary>
  12. private float fieldOfViewHorizontal;
  13. /// <summary>
  14. /// the vertical field of view angle
  15. /// </summary>
  16. private float fieldOfViewVertical;
  17. /// <summary>
  18. /// size of the image the coordinates are from
  19. /// </summary>
  20. private ImageSize imageSize;
  21. /// <summary>
  22. /// horizontal ratio relative to depth
  23. /// </summary>
  24. private float relativeRatioHorizontal;
  25. /// <summary>
  26. /// vertical ratio relative to depth
  27. /// </summary>
  28. private float relativeRatioVertical;
  29. /// <summary>
  30. /// Constructs a CoordinateConverter.
  31. /// </summary>
  32. /// <param name="imageSize">size of the image the coordinates are from</param>
  33. /// <param name="hfov">horizontal field of view angle</param>
  34. /// <param name="vfov">vertical field of view angle</param>
  35. public CoordinateConverter(ImageSize imageSize, float hfov, float vfov)
  36. {
  37. this.imageSize = imageSize;
  38. this.fieldOfViewHorizontal = hfov;
  39. this.fieldOfViewVertical = vfov;
  40. relativeRatioHorizontal = (float)Math.Tan(hfov / 2);
  41. relativeRatioVertical = (float)Math.Tan(vfov / 2);
  42. }
  43. /// <summary>
  44. /// Converts a point with a depth to a 3d position.
  45. /// </summary>
  46. /// <param name="p">the point</param>
  47. /// <param name="depth">the depth</param>
  48. /// <returns>the 3d position</returns>
  49. public Vector3D convertCoordinate2Dto3D(Vector2D p, float depth)
  50. {
  51. return convertCoordinate2Dto3D(p.X, p.Y, depth);
  52. }
  53. /// <summary>
  54. /// Converts a position with a depth to a 3d position.
  55. /// </summary>
  56. /// <param name="x">x coordinate of the position</param>
  57. /// <param name="y">y coordinate of the position</param>
  58. /// <param name="depth">the depth</param>
  59. /// <returns>the 3d position</returns>
  60. public Vector3D convertCoordinate2Dto3D(float x, float y, float depth)
  61. {
  62. float deltaX = 2 * ((x / imageSize.Width) - 0.5f);
  63. float deltaY = -2 * ((y / imageSize.Height) - 0.5f);
  64. float tanX = deltaX * relativeRatioHorizontal;
  65. float tanY = deltaY * relativeRatioVertical;
  66. float a = depth * depth;
  67. float b = (float)(Math.Pow(tanX, 2) + Math.Pow(tanY, 2));
  68. float z3 = (float)Math.Sqrt(0.5f * a + Math.Sqrt(0.25f * Math.Pow(a, 2) - b));
  69. float x3 = tanX * z3;
  70. float y3 = tanY * z3;
  71. return new Vector3D(x3, y3, z3);
  72. }
  73. /// <summary>
  74. /// 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.
  75. /// </summary>
  76. /// <param name="length">3d length of the line segment</param>
  77. /// <param name="depth">depth of the line segment</param>
  78. /// <returns>2d length of the line segment</returns>
  79. public float convertLength3Dto2D(float length, float depth)
  80. {
  81. float fullLengthX = (float)(2 * Math.Cos(fieldOfViewHorizontal / 2) * depth);
  82. float fullLengthY = (float)(2 * Math.Cos(fieldOfViewVertical / 2) * depth);
  83. float fullLengthDiagonal = (float)Math.Sqrt(Math.Pow(fullLengthX, 2) + Math.Pow(fullLengthY, 2));
  84. float ratio = length / fullLengthDiagonal;
  85. return ratio * imageSize.DiagonalLength;
  86. }
  87. }
  88. }