File indexing completed on 2025-01-18 09:35:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
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
0041
0042
0043
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
0060
0061
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 }
0096 #endif
0097
0098
0099
0100
0101
0102
0103
0104
0105
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
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
0155
0156
0157
0158
0159
0160
0161
0162
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
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 }}
0209
0210 #endif