2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * @author Roland Denis (\c roland.denis@univ-smb.fr )
20 * LAboratory of MAthematics - LAMA (CNRS, UMR 5127), University of Savoie, France
24 * This file is part of the DGtal library.
28 //////////////////////////////////////////////////////////////////////////////
30 //////////////////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////////////////
33 // IMPLEMENTATION of inline methods.
34 ///////////////////////////////////////////////////////////////////////////////
43 /** Helper that calculates the dimension index given the current linearization step.
45 * The step I is always decrementing from N-1 to 0.
47 * @tparam TStorageOrder Storage order (RowMajorStorage of ColMajorStorage).
48 * @tparam N Dimension of the space.
49 * @tparam I Current step.
51 template < typename TStorageOrder, std::size_t N, std::size_t I >
52 struct linearizer_helper;
54 template < std::size_t N, std::size_t I >
55 struct linearizer_helper< RowMajorStorage, N, I >
57 enum { dim = I }; ///< Dimension index related to the step I.
60 template < std::size_t N, std::size_t I >
61 struct linearizer_helper< ColMajorStorage, N, I >
63 enum { dim = N-1 - I }; ///< Dimension index related to the step I.
66 /** Templated static structure for linearization of the coordinates of a point.
68 * @tparam TSize Type of the linearizared index.
69 * @tparam TStorageOrder Storage order (RowMajorStorage of ColMajorStorage).
70 * @tparam N Dimension of the space.
71 * @tparam I Current step.
73 template < typename TSize, typename TStorageOrder, std::size_t N, std::size_t I = N-1 >
74 struct linearizer_impl
78 * Return the linearized index from the coordinates of a point.
80 * @tparam TPoint Type of the point.
81 * @tparam TExtent Type of the domain's extent.
82 * @param[in] aPoint The point to linearize.
83 * @param[in] anExtent The extent of the domain.
84 * @return the linearized index of the point.
86 template < typename TPoint, typename TExtent >
88 TSize apply( TPoint const& aPoint, TExtent const& anExtent )
91 aPoint[ linearizer_helper<TStorageOrder, N, I>::dim ]
92 + anExtent[ linearizer_helper<TStorageOrder, N, I>::dim ] * linearizer_impl< TSize, TStorageOrder, N, I-1 >::apply( aPoint, anExtent );
97 * Specialization of the structure linearizer_impl for the last step.
99 * It is actually used as a terminate condition of the recursive process.
101 template < typename TSize, typename TStorageOrder, std::size_t N >
102 struct linearizer_impl< TSize, TStorageOrder, N, 0 >
104 template < typename TPoint, typename TExtent >
106 TSize apply( TPoint const& aPoint, TExtent const& /* anExtent */ )
108 return aPoint[ linearizer_helper<TStorageOrder, N, 0>::dim ];
112 /** Templated static structure for de-linearization of a point index.
114 * @tparam TStorageOrder Storage order (RowMajorStorage of ColMajorStorage).
115 * @tparam N Dimension of the space.
116 * @tparam I Current step.
118 template < typename TStorageOrder, std::size_t N, std::size_t I = N-1 >
119 struct delinearizer_impl
123 * Return the de-linearized point from the linearized index of the point.
125 * @tparam TPoint Type of the point.
126 * @tparam TExtent Type of the domain's extent.
127 * @tparam TSize Type of the linearized index.
128 * @param[out] aPoint The point after de-linearization.
129 * @param[in] anExtent The extent of the domain.
130 * @param[in] anIndex The linearized index of the point.
132 template < typename TPoint, typename TExtent, typename TSize >
134 void apply( TPoint& aPoint, TExtent const& anExtent, TSize anIndex )
136 typename TExtent::Scalar const dim_extent = anExtent[ linearizer_helper<TStorageOrder, N, I>::dim ];
137 aPoint[ linearizer_helper<TStorageOrder, N, I>::dim ] = anIndex % dim_extent;
138 delinearizer_impl< TStorageOrder, N, I-1 >::apply( aPoint, anExtent, anIndex / dim_extent );
143 * Specialization of the structure delinearizer_impl for the last step.
145 * It is actually used as a terminate condition of the recursive process.
147 template < typename TStorageOrder, std::size_t N >
148 struct delinearizer_impl< TStorageOrder, N, 0 >
150 template < typename TPoint, typename TExtent, typename TSize >
152 void apply( TPoint& aPoint, TExtent const& /* anExtent */, TSize anIndex )
154 aPoint[ linearizer_helper<TStorageOrder, N, 0>::dim ] = anIndex;
158 } // anonymous namespace
160 /// Linearized index of a point, given the domain lower-bound and extent.
161 template <typename TSpace, typename TStorageOrder>
162 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Size
163 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
164 getIndex( Point aPoint, Point const& aLowerBound, Extent const& anExtent )
166 aPoint -= aLowerBound;
167 return linearizer_impl<Size, TStorageOrder, Domain::dimension>::apply(aPoint, anExtent);
170 /// Linearized index of a point, given the domain extent.
171 template <typename TSpace, typename TStorageOrder>
172 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Size
173 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
174 getIndex( Point aPoint, Extent const& anExtent )
176 return linearizer_impl<Size, TStorageOrder, Domain::dimension>::apply(aPoint, anExtent);
179 /// Linearized index of a point, given a domain.
180 template <typename TSpace, typename TStorageOrder>
181 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Size
182 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
183 getIndex( Point aPoint, Domain const& aDomain )
185 return linearizer_impl<Size, TStorageOrder, Domain::dimension>::apply(aPoint - aDomain.lowerBound(), aDomain.upperBound()-aDomain.lowerBound()+Point::diagonal(1));
188 /// De-linearization of an index, given the domain lower-bound and extent.
189 template <typename TSpace, typename TStorageOrder>
190 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Point
191 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
192 getPoint( Size anIndex, Point const& aLowerBound, Extent const& anExtent )
195 delinearizer_impl<TStorageOrder, Domain::dimension>::apply(point, anExtent, anIndex);
196 return point + aLowerBound;
199 /// De-linearization of an index, given the domain extent.
200 template <typename TSpace, typename TStorageOrder>
201 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Point
202 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
203 getPoint( Size anIndex, Extent const& anExtent )
206 delinearizer_impl<TStorageOrder, Domain::dimension>::apply(point, anExtent, anIndex);
210 /// De-linearization of an index, given a domain.
211 template <typename TSpace, typename TStorageOrder>
212 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Point
213 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
214 getPoint( Size anIndex, Domain const& aDomain )
217 delinearizer_impl<TStorageOrder, Domain::dimension>::apply(point, aDomain.upperBound()-aDomain.lowerBound()+Point::diagonal(1), anIndex);
218 return point + aDomain.lowerBound();