Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:23

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0004 // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
0005 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0006 
0007 // This file was modified by Oracle on 2016-2020.
0008 // Modifications copyright (c) 2016-2020, Oracle and/or its affiliates.
0009 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0010 
0011 // Use, modification and distribution is subject to the Boost Software License,
0012 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0013 // http://www.boost.org/LICENSE_1_0.txt)
0014 
0015 #ifndef BOOST_GEOMETRY_ARITHMETIC_CROSS_PRODUCT_HPP
0016 #define BOOST_GEOMETRY_ARITHMETIC_CROSS_PRODUCT_HPP
0017 
0018 
0019 #include <cstddef>
0020 #include <type_traits>
0021 
0022 #include <boost/geometry/core/access.hpp>
0023 #include <boost/geometry/core/make.hpp>
0024 #include <boost/geometry/core/coordinate_dimension.hpp>
0025 #include <boost/geometry/core/static_assert.hpp>
0026 
0027 #include <boost/geometry/geometries/concepts/point_concept.hpp>
0028 
0029 
0030 namespace boost { namespace geometry
0031 {
0032 
0033 #ifndef DOXYGEN_NO_DETAIL
0034 namespace detail
0035 {
0036 
0037 template <std::size_t Dimension>
0038 struct cross_product
0039 {
0040     // We define cross product only for 2d (see Wolfram) and 3d.
0041     // In Math, it is also well-defined for 7-dimension.
0042     // Generalisation of cross product to n-dimension is defined as
0043     // wedge product but it is not direct analogue to binary cross product.
0044     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0045         "Not implemented for this Dimension.",
0046         std::integral_constant<std::size_t, Dimension>);
0047 };
0048 
0049 template <>
0050 struct cross_product<2>
0051 {
0052     template <typename P1, typename P2, typename ResultP>
0053     static void apply(P1 const& p1, P2 const& p2, ResultP& result)
0054     {
0055         assert_dimension<P1, 2>();
0056         assert_dimension<P2, 2>();
0057         assert_dimension<ResultP, 2>();
0058 
0059         // For 2-dimensions, analog of the cross product U(x,y) and V(x,y) is
0060         // Ux * Vy - Uy * Vx
0061         // which is returned as 0-component (or X) of 2d vector, 1-component is undefined.
0062         set<0>(result, get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
0063     }
0064 };
0065 
0066 template <>
0067 struct cross_product<3>
0068 {
0069     template <typename P1, typename P2, typename ResultP>
0070     static void apply(P1 const& p1, P2 const& p2, ResultP& result)
0071     {
0072         assert_dimension<P1, 3>();
0073         assert_dimension<P2, 3>();
0074         assert_dimension<ResultP, 3>();
0075 
0076         set<0>(result, get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2));
0077         set<1>(result, get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2));
0078         set<2>(result, get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
0079     }
0080 
0081     template <typename ResultP, typename P1, typename P2>
0082     static constexpr ResultP apply(P1 const& p1, P2 const& p2)
0083     {
0084         assert_dimension<P1, 3>();
0085         assert_dimension<P2, 3>();
0086         assert_dimension<ResultP, 3>();
0087 
0088         return traits::make<ResultP>::apply(
0089                 get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2),
0090                 get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2),
0091                 get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
0092     }
0093 };
0094 
0095 } // namespace detail
0096 #endif // DOXYGEN_NO_DETAIL
0097 
0098 
0099 /*!
0100 \brief Computes the cross product of two vectors.
0101 \details All vectors should have the same dimension, 3 or 2.
0102 \ingroup arithmetic
0103 \param p1 first vector
0104 \param p2 second vector
0105 \return the cross product vector
0106 
0107 */
0108 
0109 template
0110 <
0111     typename ResultP, typename P1, typename P2,
0112     std::enable_if_t
0113         <
0114             dimension<ResultP>::value != 3
0115          || ! traits::make<ResultP>::is_specialized,
0116             int
0117         > = 0
0118 >
0119 inline ResultP cross_product(P1 const& p1, P2 const& p2)
0120 {
0121     BOOST_CONCEPT_ASSERT( (concepts::Point<ResultP>) );
0122     BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<P1>) );
0123     BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<P2>) );
0124 
0125     ResultP result;
0126     detail::cross_product<dimension<ResultP>::value>::apply(p1, p2, result);
0127     return result;
0128 }
0129 
0130 template
0131 <
0132     typename ResultP, typename P1, typename P2,
0133     std::enable_if_t
0134         <
0135             dimension<ResultP>::value == 3
0136          && traits::make<ResultP>::is_specialized,
0137             int
0138         > = 0
0139 >
0140 // workaround for VS2015
0141 #if !defined(_MSC_VER) || (_MSC_VER >= 1910)
0142 constexpr
0143 #endif
0144 inline ResultP cross_product(P1 const& p1, P2 const& p2)
0145 {
0146     BOOST_CONCEPT_ASSERT((concepts::Point<ResultP>));
0147     BOOST_CONCEPT_ASSERT((concepts::ConstPoint<P1>));
0148     BOOST_CONCEPT_ASSERT((concepts::ConstPoint<P2>));
0149 
0150     return detail::cross_product<3>::apply<ResultP>(p1, p2);
0151 }
0152 
0153 /*!
0154 \brief Computes the cross product of two vectors.
0155 \details All vectors should have the same dimension, 3 or 2.
0156 \ingroup arithmetic
0157 \param p1 first vector
0158 \param p2 second vector
0159 \return the cross product vector
0160 
0161 \qbk{[heading Examples]}
0162 \qbk{[cross_product] [cross_product_output]}
0163 */
0164 template
0165 <
0166     typename P,
0167     std::enable_if_t
0168         <
0169             dimension<P>::value != 3
0170          || ! traits::make<P>::is_specialized,
0171             int
0172         > = 0
0173 >
0174 inline P cross_product(P const& p1, P const& p2)
0175 {
0176     BOOST_CONCEPT_ASSERT((concepts::Point<P>));
0177     BOOST_CONCEPT_ASSERT((concepts::ConstPoint<P>));
0178 
0179     P result;
0180     detail::cross_product<dimension<P>::value>::apply(p1, p2, result);
0181     return result;
0182 }
0183 
0184 
0185 template
0186 <
0187     typename P,
0188     std::enable_if_t
0189         <
0190             dimension<P>::value == 3
0191          && traits::make<P>::is_specialized,
0192             int
0193         > = 0
0194 >
0195 // workaround for VS2015
0196 #if !defined(_MSC_VER) || (_MSC_VER >= 1910)
0197 constexpr
0198 #endif
0199 inline P cross_product(P const& p1, P const& p2)
0200 {
0201     BOOST_CONCEPT_ASSERT((concepts::Point<P>));
0202     BOOST_CONCEPT_ASSERT((concepts::ConstPoint<P>));
0203 
0204     return detail::cross_product<3>::apply<P>(p1, p2);
0205 }
0206 
0207 
0208 }} // namespace boost::geometry
0209 
0210 #endif // BOOST_GEOMETRY_ARITHMETIC_CROSS_PRODUCT_HPP