cross_product.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  3. // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  5. // This file was modified by Oracle on 2016.
  6. // Modifications copyright (c) 2016, Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #ifndef BOOST_GEOMETRY_ARITHMETIC_CROSS_PRODUCT_HPP
  12. #define BOOST_GEOMETRY_ARITHMETIC_CROSS_PRODUCT_HPP
  13. #include <cstddef>
  14. #include <boost/mpl/assert.hpp>
  15. #include <boost/mpl/size_t.hpp>
  16. #include <boost/geometry/core/access.hpp>
  17. #include <boost/geometry/core/coordinate_dimension.hpp>
  18. #include <boost/geometry/geometries/concepts/point_concept.hpp>
  19. namespace boost { namespace geometry
  20. {
  21. #ifndef DOXYGEN_NO_DETAIL
  22. namespace detail
  23. {
  24. template <std::size_t Dimension>
  25. struct cross_product
  26. {
  27. // We define cross product only for 2d (see Wolfram) and 3d.
  28. // In Math, it is also well-defined for 7-dimension.
  29. // Generalisation of cross product to n-dimension is defined as
  30. // wedge product but it is not direct analogue to binary cross product.
  31. BOOST_MPL_ASSERT_MSG((false),
  32. NOT_IMPLEMENTED_FOR_THIS_DIMENSION,
  33. (mpl::size_t<Dimension>));
  34. };
  35. template <>
  36. struct cross_product<2>
  37. {
  38. template <typename P1, typename P2, typename ResultP>
  39. static inline void apply(P1 const& p1, P2 const& p2, ResultP& result)
  40. {
  41. assert_dimension<P1, 2>();
  42. assert_dimension<P2, 2>();
  43. assert_dimension<ResultP, 2>();
  44. // For 2-dimensions, analog of the cross product U(x,y) and V(x,y) is
  45. // Ux * Vy - Uy * Vx
  46. // which is returned as 0-component (or X) of 2d vector, 1-component is undefined.
  47. set<0>(result, get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
  48. }
  49. };
  50. template <>
  51. struct cross_product<3>
  52. {
  53. template <typename P1, typename P2, typename ResultP>
  54. static inline void apply(P1 const& p1, P2 const& p2, ResultP& result)
  55. {
  56. assert_dimension<P1, 3>();
  57. assert_dimension<P2, 3>();
  58. assert_dimension<ResultP, 3>();
  59. set<0>(result, get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2));
  60. set<1>(result, get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2));
  61. set<2>(result, get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
  62. }
  63. };
  64. } // namespace detail
  65. #endif // DOXYGEN_NO_DETAIL
  66. /*!
  67. \brief Computes the cross product of two vectors.
  68. \details All vectors should have the same dimension, 3 or 2.
  69. \ingroup arithmetic
  70. \param p1 first vector
  71. \param p2 second vector
  72. \return the cross product vector
  73. */
  74. template <typename ResultP, typename P1, typename P2>
  75. inline ResultP cross_product(P1 const& p1, P2 const& p2)
  76. {
  77. BOOST_CONCEPT_ASSERT( (concepts::Point<ResultP>) );
  78. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<P1>) );
  79. BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<P2>) );
  80. ResultP result;
  81. detail::cross_product<dimension<ResultP>::value>::apply(p1, p2, result);
  82. return result;
  83. }
  84. /*!
  85. \brief Computes the cross product of two vectors.
  86. \details All vectors should have the same dimension, 3 or 2.
  87. \ingroup arithmetic
  88. \param p1 first vector
  89. \param p2 second vector
  90. \return the cross product vector
  91. */
  92. template <typename P>
  93. inline P cross_product(P const& p1, P const& p2)
  94. {
  95. BOOST_CONCEPT_ASSERT((concepts::Point<P>));
  96. BOOST_CONCEPT_ASSERT((concepts::ConstPoint<P>));
  97. P result;
  98. detail::cross_product<dimension<P>::value>::apply(p1, p2, result);
  99. return result;
  100. }
  101. }} // namespace boost::geometry
  102. #endif // BOOST_GEOMETRY_ARITHMETIC_CROSS_PRODUCT_HPP