💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.0 KiB

  1. /*
  2. * Copyright (C) 2020 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_PLANE_HPP
  20. #define ANTKEEPER_PLANE_HPP
  21. #include <vmq/vmq.hpp>
  22. using vmq::vector;
  23. using namespace vmq::operators;
  24. template <class T>
  25. struct plane
  26. {
  27. vector<T, 3> normal;
  28. T distance;
  29. /**
  30. * Creates a plane given a normal vector and distance.
  31. */
  32. plane(const vector<T, 3>& normal, T distance);
  33. /**
  34. * Creates a plane given a normal vector and offset vector.
  35. */
  36. plane(const vector<T, 3>& normal, const vector<T, 3>& offset);
  37. /**
  38. * Creates a plane given three points.
  39. */
  40. plane(const vector<T, 3>& a, const vector<T, 3>& b, const vector<T, 3>& c);
  41. /**
  42. * Creates a plane given its coefficients.
  43. *
  44. * @param coefficients Vector containing the plane coefficients, A, B, C and D, as x, y, z, and w, respectively.
  45. */
  46. plane(const vector<T, 4>& coefficients);
  47. /// Creates an uninitialized plane.
  48. plane() = default;
  49. };
  50. template <class T>
  51. inline plane<T>::plane(const vector<T, 3>& normal, T distance):
  52. normal(normal),
  53. distance(distance)
  54. {}
  55. template <class T>
  56. plane<T>::plane(const vector<T, 3>& normal, const vector<T, 3>& offset):
  57. normal(normal),
  58. distance(-vmq::dot(normal, offset))
  59. {}
  60. template <class T>
  61. plane<T>::plane(const vector<T, 3>& a, const vector<T, 3>& b, const vector<T, 3>& c)
  62. {
  63. normal = vmq::normalize(vmq::cross(c - b, a - b));
  64. distance = -(vmq::dot(normal, b));
  65. }
  66. template <class T>
  67. plane<T>::plane(const vector<T, 4>& coefficients)
  68. {
  69. const vector<T, 3> abc = vmq::resize<3>(coefficients);
  70. const float inverse_length = T(1) / vmq::length(abc);
  71. normal = abc * inverse_length;
  72. distance = coefficients[3] * inverse_length;
  73. }
  74. /**
  75. * Calculates the signed distance between a plane and a vector.
  76. *
  77. * @param p Plane.
  78. * @param v Vector.
  79. * @return Signed distance between the plane and a vector.
  80. */
  81. template <class T>
  82. inline T signed_distance(const plane<T>& p, const vector<T, 3>& v)
  83. {
  84. return p.distance + vmq::dot(p.normal, v);
  85. }
  86. /**
  87. * Calculates the point of intersection between three planes.
  88. */
  89. template <class T>
  90. vector<T, 3> intersection(const plane<T>& p0, const plane<T>& p1, const plane<T>& p2)
  91. {
  92. return -(p0.distance * vmq::cross(p1.normal, p2.normal) + p1.distance * vmq::cross(p2.normal, p0.normal) + p2.distance * vmq::cross(p0.normal, p1.normal)) / vmq::dot(p0.normal, vmq::cross(p1.normal, p2.normal));
  93. }
  94. #endif // ANTKEEPER_PLANE_HPP