DGtal 1.4.0
Loading...
Searching...
No Matches
NeighborhoodConvexityAnalyzer.ih
1/**
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.
6 *
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.
11 *
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/>.
14 *
15 **/
16
17/**
18 * @file NeighborhoodConvexityAnalyzer.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
21 *
22 * @date 2021/06/16
23 *
24 * Implementation of inline methods defined in NeighborhoodConvexityAnalyzer.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <cstdlib>
32//////////////////////////////////////////////////////////////////////////////
33
34//-----------------------------------------------------------------------------
35template < typename TKSpace, int K >
36template < typename PointPredicate >
37void
38DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
39setCenter( Point c, const PointPredicate& X )
40{
41 ASSERT( myDomain.isInside( c ) );
42 myCenter = c;
43 myNbInX = 0;
44 myComputations = 0;
45 myResults = 0;
46 Domain local_domain( c - Point::diagonal( radius() ),
47 c + Point::diagonal( radius() ) );
48 Size bit = 0;
49 myCfgX.reset();
50 for ( auto q : local_domain )
51 {
52 if ( q == c )
53 {
54 myCenterInX = X( q );
55 }
56 else if ( myDomain.isInside( q ) )
57 {
58 if ( X( q ) )
59 {
60 myCfgX.set( bit );
61 ++myNbInX;
62 }
63 }
64 bit += 1;
65 }
66 myBasicCfgX.clear();
67 computeBasicConfigurations( myCfgX, myBasicCfgX );
68}
69
70//-----------------------------------------------------------------------------
71template < typename TKSpace, int K >
72void
73DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
74getLocalX( std::vector< Point >& localX, bool with_center ) const
75{
76 Domain local_domain( myCenter - Point::diagonal( radius() ),
77 myCenter + Point::diagonal( radius() ) );
78 Size bit = 0;
79 for ( auto q : local_domain )
80 {
81 if ( q == myCenter ) {
82 if ( with_center )
83 localX.push_back( myCenter );
84 } else if ( myDomain.isInside( q ) ) {
85 if ( myCfgX.test( bit ) )
86 localX.push_back( q );
87 }
88 ++bit;
89 }
90}
91//-----------------------------------------------------------------------------
92template < typename TKSpace, int K >
93void
94DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
95getLocalCompX( std::vector< Point >& localCompX, bool with_center ) const
96{
97 Domain local_domain( myCenter - Point::diagonal( radius() ),
98 myCenter + Point::diagonal( radius() ) );
99 Size bit = 0;
100 for ( auto q : local_domain )
101 {
102 if ( q == myCenter ) {
103 if ( with_center )
104 localCompX.push_back( myCenter );
105 } else if ( myDomain.isInside( q ) ) {
106 if ( ! myCfgX.test( bit ) )
107 localCompX.push_back( q );
108 }
109 ++bit;
110 }
111}
112
113//-----------------------------------------------------------------------------
114template < typename TKSpace, int K >
115bool
116DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
117checkBasicConfigurationsFullConvexity
118( bool compX, bool with_center ) const
119{
120 if ( ! compX )
121 { // shape X
122 const Size mask_center = with_center ? 0x10 : 0;
123 for ( auto cfg : myBasicCfgX )
124 if ( ! myBasicFullConvexityTable[ cfg.to_ulong() | mask_center ] )
125 return false;
126 }
127 else
128 { // complementary of shape X
129 const Size mask_center = with_center ? 0x1ff : 0x1ef;
130 for ( auto cfg : myBasicCfgX )
131 if ( ! myBasicFullConvexityTable[ (~cfg.to_ulong()) & mask_center ] )
132 return false;
133 }
134 return true;
135}
136//-----------------------------------------------------------------------------
137template < typename TKSpace, int K >
138bool
139DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
140checkBasicConfigurations0Convexity
141( bool compX, bool with_center ) const
142{
143 if ( ! compX )
144 { // shape X
145 const Size mask_center = with_center ? 0x10 : 0;
146 for ( auto cfg : myBasicCfgX )
147 if ( ! myBasic0ConvexityTable[ cfg.to_ulong() | mask_center ] )
148 return false;
149 }
150 else
151 { // complementary of shape X
152 const Size mask_center = with_center ? 0x1ff : 0x1ef;
153 for ( auto cfg : myBasicCfgX )
154 if ( ! myBasic0ConvexityTable[ (~cfg.to_ulong()) & mask_center ] )
155 return false;
156 }
157 return true;
158}
159//-----------------------------------------------------------------------------
160template < typename TKSpace, int K >
161void
162DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
163computeBasicConfigurations
164( Configuration cfg, std::vector< BasicConfiguration > & result ) const
165{
166 if ( dimension == 2 ) result.push_back( cfg.to_ulong() );
167 else
168 {
169 for ( Dimension i = 0; i < dimension; i++ )
170 for ( Dimension j = i+1; j < dimension; j++ )
171 result.push_back( computeCentralBasicConfiguration( cfg, i, j ) );
172 }
173}
174
175//-----------------------------------------------------------------------------
176template < typename TKSpace, int K >
177typename DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::BasicConfiguration
178DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
179computeCentralBasicConfiguration
180( Configuration cfg, Dimension i, Dimension j ) const
181{
182 Size incr_i = 1;
183 Size incr_j = 1;
184 for ( Dimension d = 0; d < i; ++d ) { incr_i *= 2*K+1; }
185 for ( Dimension d = 0; d < j; ++d ) { incr_j *= 2*K+1; }
186 BasicConfiguration basic;
187 basic[ 0 ] = cfg[ middle - incr_i - incr_j ];
188 basic[ 1 ] = cfg[ middle - incr_j ];
189 basic[ 2 ] = cfg[ middle + incr_i - incr_j ];
190 basic[ 3 ] = cfg[ middle - incr_i ];
191 basic[ 4 ] = cfg[ middle ];
192 basic[ 5 ] = cfg[ middle + incr_i ];
193 basic[ 6 ] = cfg[ middle - incr_i + incr_j ];
194 basic[ 7 ] = cfg[ middle + incr_j ];
195 basic[ 8 ] = cfg[ middle + incr_i + incr_j ];
196 return basic;
197}
198
199//-----------------------------------------------------------------------------
200template < typename TKSpace, int K >
201void
202DGtal::NeighborhoodConvexityAnalyzer<TKSpace,K>::
203computeBasicFullConvexityTable()
204{
205 typedef KhalimskySpaceND< 2, int > K2;
206 typedef K2::Point Point2;
207 typedef K2::Space Z2;
208 typedef DigitalConvexity< K2 > DigConv2;
209 typedef HyperRectDomain< Z2 > Domain2;
210 DigConv2 dconv2( Point2::diagonal( -2 ), Point2::diagonal( 2 ) );
211 Point2 p1 = Point2::diagonal( -1 );
212 Point2 p2 = Point2::diagonal( 1 );
213 Point2 c = Point2::diagonal( 0 );
214 Domain2 domain( p1, p2 );
215 for ( unsigned int cfg = 0; cfg < 512; cfg++ )
216 {
217 // Building a configuration.
218 std::vector< Point2 > X;
219 unsigned int mask = 1;
220 for ( auto it = domain.begin(); it != domain.end(); ++it )
221 {
222 const Point2 p = *it;
223 if ( cfg & mask ) X.push_back( p );
224 mask <<= 1;
225 }
226 myBasicFullConvexityTable[ cfg ] = dconv2.isFullyConvex( X );
227 myBasic0ConvexityTable [ cfg ] = dconv2.is0Convex ( X );
228 }
229}
230
231///////////////////////////////////////////////////////////////////////////////
232// Implementation of inline functions //
233
234
235// //
236///////////////////////////////////////////////////////////////////////////////