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/>.
18 * @file MetricAdjacency.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in MetricAdjacency.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 #include "DGtal/kernel/domains/HyperRectDomain.h"
33 #include <boost/math/special_functions/binomial.hpp>
34 //////////////////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////////////////
37 // IMPLEMENTATION of inline methods.
38 ///////////////////////////////////////////////////////////////////////////////
39 #include "DGtal/topology/MetricAdjacency.h"
40 ///////////////////////////////////////////////////////////////////////////////
41 // ----------------------- Standard services ------------------------------
46 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
48 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::~MetricAdjacency()
53 * Constructor. Does nothing. Due to the symmetry and translation
54 * invariance of this digital topology, all methods are static.
56 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
58 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::MetricAdjacency()
62 ///////////////////////////////////////////////////////////////////////////////
63 // ----------------------- Adjacency services -----------------------------
67 * @param p1 any point in this space.
68 * @param p2 any point in this space.
70 * @return 'true' iff p1 is adjacent to p2 according to this
73 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
76 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::isAdjacentTo
77 ( const Point & p1, const Point & p2 )
80 return ( v.normInfinity() <= 1 ) && ( v.norm1() <= maxNorm1 );
84 * @param p1 any point in this space.
85 * @param p2 any point in this space.
87 * @return 'true' iff p1 is adjacent to p2 according to this
88 * adjacency relation and p1 != p2.
90 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
93 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::isProperlyAdjacentTo
94 ( const Point & p1, const Point & p2 )
97 if ( v.normInfinity() <= 1 )
99 typename Vector::UnsignedComponent n1 = v.norm1();
100 return ( n1 <= maxNorm1 ) && ( n1 != 0 );
105 ///////////////////////////////////////////////////////////////////////////////
106 // ----------------------- Local graph services -----------------------------
111 * @return maximum number of neighbors for this adjacency
113 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
115 typename DGtal::MetricAdjacency<TSpace, maxNorm1, dimension>::Size
116 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::bestCapacity()
118 static Size myCapacity = computeCapacity();
124 * @return the number of neighbors of this vertex
126 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
128 typename DGtal::MetricAdjacency<TSpace, maxNorm1, dimension>::Size
129 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::degree
130 ( const Vertex & /* v */ )
132 return bestCapacity();
136 * Writes the neighbors of a vertex using an output iterator
139 * @tparam OutputIterator the type of an output iterator writing
140 * in a container of vertices.
142 * @param it the output iterator
144 * @param v the vertex whose neighbors will be written
146 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
147 template <typename OutputIterator>
150 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::writeNeighbors
151 ( OutputIterator &it, const Vertex & v )
154 for ( typename Point::Iterator iter = p1.begin(); iter != p1.end(); ++iter )
157 for ( typename Point::Iterator iter = p2.begin(); iter != p2.end(); ++iter )
159 typedef HyperRectDomain<Space> LocalDomain;
160 LocalDomain domain( p1, p2 );
161 for ( typename LocalDomain::ConstIterator iter = domain.begin();
162 iter != domain.end();
165 Vector vect( v - *iter );
166 typename Vector::UnsignedComponent n1 = vect.norm1();
167 if ( ( n1 <= maxNorm1 ) && ( n1 != 0 ) )
173 * Writes the neighbors of a vertex which satisfy a predicate using an
177 * @tparam OutputIterator the type of an output iterator writing
178 * in a container of vertices.
180 * @tparam VertexPredicate the type of the predicate
182 * @param it the output iterator
184 * @param v the vertex whose neighbors will be written
186 * @param pred the predicate that must be satisfied
188 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
189 template <typename OutputIterator, typename VertexPredicate>
191 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::writeNeighbors
192 ( OutputIterator &it, const Vertex & v, const VertexPredicate & pred)
195 for ( typename Point::Iterator iter = p1.begin(); iter != p1.end(); ++iter )
198 for ( typename Point::Iterator iter = p2.begin(); iter != p2.end(); ++iter )
200 typedef HyperRectDomain<Space> LocalDomain;
201 LocalDomain domain( p1, p2 );
202 for ( typename LocalDomain::ConstIterator iter = domain.begin();
203 iter != domain.end();
206 Vector vect( v - *iter );
207 typename Vector::UnsignedComponent n1 = vect.norm1();
208 if ( ( n1 <= maxNorm1 ) && ( n1 != 0 ) && (pred(*iter)) )
213 ///////////////////////////////////////////////////////////////////////////////
214 // Interface - public :
217 * Writes/Displays the object on an output stream.
218 * @param out the output stream where the object is written.
220 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
223 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::selfDisplay
224 ( std::ostream & out )
226 out << "[MetricAdjacency Z" << Space::dimension
227 << " n1<=" << maxNorm1 << " ]";
231 * Checks the validity/consistency of the object.
232 * @return 'true' if the object is valid, 'false' otherwise.
234 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
237 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::isValid()
244 ///////////////////////////////////////////////////////////////////////////////
245 // Implementation of inline functions //
247 template <typename TSpace, DGtal::Dimension maxNorm1>
250 DGtal::operator<< ( std::ostream & out,
251 const MetricAdjacency<TSpace,maxNorm1,
252 TSpace::dimension> & object )
254 object.selfDisplay( out );
259 ///////////////////////////////////////////////////////////////////////////////
260 // Implementation of hidden services //
261 template <typename TSpace, DGtal::Dimension maxNorm1, DGtal::Dimension dimension>
263 typename DGtal::MetricAdjacency<TSpace, maxNorm1, dimension>::Size
264 DGtal::MetricAdjacency<TSpace,maxNorm1,dimension>::computeCapacity()
266 DGtal::Dimension result = 0;
267 for( DGtal::Dimension m = dimension - 1; m > dimension - maxNorm1 - 1; m-- )
269 result += ( (dimension - m) << 1 ) * static_cast<DGtal::Dimension>( boost::math::binomial_coefficient<float>(dimension, m) );
275 ///////////////////////////////////////////////////////////////////////////////
279 template <typename TSpace>
280 class MetricAdjacency<TSpace, 2, 2>
282 BOOST_CONCEPT_ASSERT(( concepts::CSpace<TSpace> ));
283 // ----------------------- public types ------------------------------
285 // Required by CAdjacency
286 typedef TSpace Space;
287 typedef typename Space::Point Point;
288 typedef MetricAdjacency<Space, 2, 2> Adjacency;
290 typedef typename Space::Integer Integer;
291 typedef typename Space::Vector Vector;
293 // Required by CUndirectedSimpleLocalGraph
294 typedef Point Vertex;
295 typedef typename Space::Size Size;
296 typedef std::set<Vertex> VertexSet; // DigitalSet doesn't seem to fit (MetricAdjacency has no domain)
297 template <typename Value> struct VertexMap {
298 typedef typename std::map<Vertex, Value> Type;
301 // ----------------------- Standard services ------------------------------
305 ~MetricAdjacency() {}
307 // ----------------------- Adjacency services -----------------------------
312 bool isAdjacentTo( const Point & p1, const Point & p2 )
315 return ( v.normInfinity() <= 1 ) && ( v.norm1() <= 2 );
320 bool isProperlyAdjacentTo( const Point & p1, const Point & p2 )
323 if ( v.normInfinity() <= 1 )
325 typename Vector::UnsignedComponent n1 = v.norm1();
326 return ( n1 <= 2 ) && ( n1 != 0 );
331 // ---------------------- Local graph services ----------------------------
344 degree( const Vertex & /* v */ )
349 template <typename OutputIterator>
352 void writeNeighbors( OutputIterator &it, const Vertex & v )
356 *it++ = Vertex( x-1, y-1 );
357 *it++ = Vertex( x , y-1 );
358 *it++ = Vertex( x+1, y-1 );
359 *it++ = Vertex( x-1, y );
360 *it++ = Vertex( x+1, y );
361 *it++ = Vertex( x-1, y+1 );
362 *it++ = Vertex( x , y+1 );
363 *it++ = Vertex( x+1, y+1 );
366 template <typename OutputIterator, typename VertexPredicate>
369 void writeNeighbors( OutputIterator &it, const Vertex & v, const VertexPredicate & pred)
371 Vertex q( v[ 0 ] - 1, v[ 1 ] - 1 );
372 if ( pred( q ) ) *it++ = q;
373 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
374 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
375 q[ 0 ] -= 2; ++q[ 1 ];
376 if ( pred( q ) ) *it++ = q;
377 q[ 0 ] += 2; if ( pred( q ) ) *it++ = q;
378 q[ 0 ] -= 2; ++q[ 1 ];
379 if ( pred( q ) ) *it++ = q;
380 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
381 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
384 // ----------------------- Interface --------------------------------------
388 void selfDisplay ( std::ostream & out )
390 out << "[MetricAdjacency Z2*"
391 << " n1<=2*" << " ]";
395 bool isValid() { return true; }
398 MetricAdjacency ( const MetricAdjacency & other );
399 MetricAdjacency & operator= ( const MetricAdjacency & other );
401 // ------------------------- Internals ------------------------------------
404 }; // end of class MetricAdjacency
407 template <typename TSpace>
408 class MetricAdjacency<TSpace, 1, 2>
410 BOOST_CONCEPT_ASSERT(( concepts::CSpace<TSpace> ));
411 // ----------------------- public types ------------------------------
413 // Required by CAdjacency
414 typedef TSpace Space;
415 typedef typename Space::Point Point;
416 typedef MetricAdjacency<Space, 1, 2> Adjacency;
418 typedef typename Space::Integer Integer;
419 typedef typename Space::Vector Vector;
421 // Required by CUndirectedSimpleLocalGraph
422 typedef Point Vertex;
423 typedef typename Space::Size Size;
424 typedef std::set<Vertex> VertexSet; // DigitalSet doesn't seem to fit (MetricAdjacency has no domain)
425 template <typename Value> struct VertexMap {
426 typedef typename std::map<Vertex, Value> Type;
429 // ----------------------- Standard services ------------------------------
433 ~MetricAdjacency() {}
435 // ----------------------- Adjacency services -----------------------------
440 bool isAdjacentTo( const Point & p1, const Point & p2 )
443 return ( v.norm1() <= 1 );
448 bool isProperlyAdjacentTo( const Point & p1, const Point & p2 )
451 return v.norm1() == 1;
454 // ---------------------- Local graph services ----------------------------
466 degree( const Vertex & /* v */ )
471 template <typename OutputIterator>
474 void writeNeighbors( OutputIterator &it, const Vertex & v )
478 *it++ = Vertex( x , y-1 );
479 *it++ = Vertex( x-1, y );
480 *it++ = Vertex( x+1, y );
481 *it++ = Vertex( x , y+1 );
484 template <typename OutputIterator, typename VertexPredicate>
487 void writeNeighbors( OutputIterator &it, const Vertex & v, const VertexPredicate & pred)
489 Vertex q( v[ 0 ], v[ 1 ] - 1 );
490 if ( pred( q ) ) *it++ = q;
492 if ( pred( q ) ) *it++ = q;
493 q[ 0 ] += 2; if ( pred( q ) ) *it++ = q;
495 if ( pred( q ) ) *it++ = q;
498 // ----------------------- Interface --------------------------------------
502 void selfDisplay ( std::ostream & out )
504 out << "[MetricAdjacency Z2*"
505 << " n1<=2*" << " ]";
509 bool isValid() { return true; }
512 MetricAdjacency ( const MetricAdjacency & other );
513 MetricAdjacency & operator= ( const MetricAdjacency & other );
515 // ------------------------- Internals ------------------------------------
519 }; // end of class MetricAdjacency
521 /** Specialize 26-adjacency. */
522 template <typename TSpace>
523 class MetricAdjacency<TSpace, 3, 3>
525 BOOST_CONCEPT_ASSERT(( concepts::CSpace<TSpace> ));
526 // ----------------------- public types ------------------------------
528 // Required by CAdjacency
529 typedef TSpace Space;
530 typedef typename Space::Point Point;
531 typedef MetricAdjacency<Space, 3, 3> Adjacency;
533 typedef typename Space::Integer Integer;
534 typedef typename Space::Vector Vector;
536 // Required by CUndirectedSimpleLocalGraph
537 typedef Point Vertex;
538 typedef typename Space::Size Size;
539 typedef std::set<Vertex> VertexSet; // DigitalSet doesn't seem to fit (MetricAdjacency has no domain)
540 template <typename Value> struct VertexMap {
541 typedef typename std::map<Vertex, Value> Type;
544 // ----------------------- Standard services ------------------------------
548 ~MetricAdjacency() {}
550 // ----------------------- Adjacency services -----------------------------
555 bool isAdjacentTo( const Point & p1, const Point & p2 )
558 return ( v.normInfinity() <= 1 ) && ( v.norm1() <= 3 );
563 bool isProperlyAdjacentTo( const Point & p1, const Point & p2 )
566 if ( v.normInfinity() <= 1 )
568 typename Vector::UnsignedComponent n1 = v.norm1();
569 return ( n1 <= 3 ) && ( n1 != 0 );
574 // ---------------------- Local graph services ----------------------------
587 degree( const Vertex & /* v */ )
592 template <typename OutputIterator>
595 void writeNeighbors( OutputIterator &it, const Vertex & v )
601 *it++ = Vertex( x-1, y-1, z-1 );
602 *it++ = Vertex( x , y-1, z-1 );
603 *it++ = Vertex( x+1, y-1, z-1 );
604 *it++ = Vertex( x-1, y-1, z );
605 *it++ = Vertex( x , y-1, z );
606 *it++ = Vertex( x+1, y-1, z );
607 *it++ = Vertex( x-1, y-1, z+1 );
608 *it++ = Vertex( x , y-1, z+1 );
609 *it++ = Vertex( x+1, y-1, z+1 );
610 *it++ = Vertex( x-1, y , z-1 );
611 *it++ = Vertex( x , y , z-1 );
612 *it++ = Vertex( x+1, y , z-1 );
613 *it++ = Vertex( x-1, y , z );
614 //*it++ = Vertex( x , y , z );
615 *it++ = Vertex( x+1, y , z );
616 *it++ = Vertex( x-1, y , z+1 );
617 *it++ = Vertex( x , y , z+1 );
618 *it++ = Vertex( x+1, y , z+1 );
619 *it++ = Vertex( x-1, y+1, z-1 );
620 *it++ = Vertex( x , y+1, z-1 );
621 *it++ = Vertex( x+1, y+1, z-1 );
622 *it++ = Vertex( x-1, y+1, z );
623 *it++ = Vertex( x , y+1, z );
624 *it++ = Vertex( x+1, y+1, z );
625 *it++ = Vertex( x-1, y+1, z+1 );
626 *it++ = Vertex( x , y+1, z+1 );
627 *it++ = Vertex( x+1, y+1, z+1 );
630 template <typename OutputIterator, typename VertexPredicate>
633 void writeNeighbors( OutputIterator &it, const Vertex & v, const VertexPredicate & pred)
635 Vertex q( v[ 0 ] - 1, v[ 1 ] - 1, v[ 2 ] - 1 );
637 if ( pred( q ) ) *it++ = q;
638 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
639 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
640 q[ 0 ] -= 2; ++q[ 1 ];
641 if ( pred( q ) ) *it++ = q;
642 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
643 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
644 q[ 0 ] -= 2; ++q[ 1 ];
645 if ( pred( q ) ) *it++ = q;
646 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
647 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
649 q[ 0 ] -= 2; q[ 1 ] -= 2; ++q[ 2 ];
650 if ( pred( q ) ) *it++ = q;
651 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
652 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
653 q[ 0 ] -= 2; ++q[ 1 ];
654 if ( pred( q ) ) *it++ = q;
655 q[ 0 ] += 2; if ( pred( q ) ) *it++ = q; // skip (x,y,z)
656 q[ 0 ] -= 2; ++q[ 1 ];
657 if ( pred( q ) ) *it++ = q;
658 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
659 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
661 q[ 0 ] -= 2; q[ 1 ] -= 2; ++q[ 2 ];
662 if ( pred( q ) ) *it++ = q;
663 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
664 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
665 q[ 0 ] -= 2; ++q[ 1 ];
666 if ( pred( q ) ) *it++ = q;
667 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
668 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
669 q[ 0 ] -= 2; ++q[ 1 ];
670 if ( pred( q ) ) *it++ = q;
671 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
672 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
675 // ----------------------- Interface --------------------------------------
679 void selfDisplay ( std::ostream & out )
681 out << "[MetricAdjacency Z3*"
682 << " n1<=3*" << " ]";
686 bool isValid() { return true; }
689 MetricAdjacency ( const MetricAdjacency & other );
690 MetricAdjacency & operator= ( const MetricAdjacency & other );
692 // ------------------------- Internals ------------------------------------
695 }; // end of class MetricAdjacency
698 /** Specialize 18-adjacency. */
699 template <typename TSpace>
700 class MetricAdjacency<TSpace, 2, 3>
702 BOOST_CONCEPT_ASSERT(( concepts::CSpace<TSpace> ));
703 // ----------------------- public types ------------------------------
705 // Required by CAdjacency
706 typedef TSpace Space;
707 typedef typename Space::Point Point;
708 typedef MetricAdjacency<Space, 2, 3> Adjacency;
710 typedef typename Space::Integer Integer;
711 typedef typename Space::Vector Vector;
713 // Required by CUndirectedSimpleLocalGraph
714 typedef Point Vertex;
715 typedef typename Space::Size Size;
716 typedef std::set<Vertex> VertexSet; // DigitalSet doesn't seem to fit (MetricAdjacency has no domain)
717 template <typename Value> struct VertexMap {
718 typedef typename std::map<Vertex, Value> Type;
721 // ----------------------- Standard services ------------------------------
725 ~MetricAdjacency() {}
727 // ----------------------- Adjacency services -----------------------------
732 bool isAdjacentTo( const Point & p1, const Point & p2 )
735 return ( v.normInfinity() <= 1 ) && ( v.norm1() <= 2 );
740 bool isProperlyAdjacentTo( const Point & p1, const Point & p2 )
743 if ( v.normInfinity() <= 1 )
745 typename Vector::UnsignedComponent n1 = v.norm1();
746 return ( n1 <= 2 ) && ( n1 != 0 );
751 // ---------------------- Local graph services ----------------------------
764 degree( const Vertex & /* v */ )
769 template <typename OutputIterator>
772 void writeNeighbors( OutputIterator &it, const Vertex & v )
778 *it++ = Vertex( x , y-1, z-1 );
779 *it++ = Vertex( x-1, y-1, z );
780 *it++ = Vertex( x , y-1, z );
781 *it++ = Vertex( x+1, y-1, z );
782 *it++ = Vertex( x , y-1, z+1 );
783 *it++ = Vertex( x-1, y , z-1 );
784 *it++ = Vertex( x , y , z-1 );
785 *it++ = Vertex( x+1, y , z-1 );
786 *it++ = Vertex( x-1, y , z );
787 //*it++ = Vertex( x , y , z );
788 *it++ = Vertex( x+1, y , z );
789 *it++ = Vertex( x-1, y , z+1 );
790 *it++ = Vertex( x , y , z+1 );
791 *it++ = Vertex( x+1, y , z+1 );
792 *it++ = Vertex( x , y+1, z-1 );
793 *it++ = Vertex( x-1, y+1, z );
794 *it++ = Vertex( x , y+1, z );
795 *it++ = Vertex( x+1, y+1, z );
796 *it++ = Vertex( x , y+1, z+1 );
799 template <typename OutputIterator, typename VertexPredicate>
802 void writeNeighbors( OutputIterator &it, const Vertex & v, const VertexPredicate & pred)
804 Vertex q( v[ 0 ], v[ 1 ] - 1, v[ 2 ] - 1 );
806 if ( pred( q ) ) *it++ = q; // x , y-1, z-1
807 --q[ 0 ], ++q[ 1 ]; if ( pred( q ) ) *it++ = q; // x-1, y , z-1
808 ++q[ 0 ]; if ( pred( q ) ) *it++ = q; // x , y , z-1
809 ++q[ 0 ]; if ( pred( q ) ) *it++ = q; // x+1, y , z-1
810 --q[ 0 ], ++q[ 1 ]; if ( pred( q ) ) *it++ = q; // x , y+1, z-1
812 --q[ 0 ], q[ 1 ] -= 2, ++q[ 2 ];
813 if ( pred( q ) ) *it++ = q;
814 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
815 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
816 q[ 0 ] -= 2; ++q[ 1 ];
817 if ( pred( q ) ) *it++ = q;
818 q[ 0 ] += 2; if ( pred( q ) ) *it++ = q; // skip (x,y,z)
819 q[ 0 ] -= 2; ++q[ 1 ];
820 if ( pred( q ) ) *it++ = q;
821 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
822 ++q[ 0 ]; if ( pred( q ) ) *it++ = q;
824 --q[ 0 ], q[ 1 ] -= 2; ++q[ 2 ];
825 if ( pred( q ) ) *it++ = q; // x , y-1, z+1
826 --q[ 0 ], ++q[ 1 ]; if ( pred( q ) ) *it++ = q; // x-1, y , z+1
827 ++q[ 0 ]; if ( pred( q ) ) *it++ = q; // x , y , z+1
828 ++q[ 0 ]; if ( pred( q ) ) *it++ = q; // x+1, y , z+1
829 --q[ 0 ], ++q[ 1 ]; if ( pred( q ) ) *it++ = q; // x , y+1, z+1
832 // ----------------------- Interface --------------------------------------
836 void selfDisplay ( std::ostream & out )
838 out << "[MetricAdjacency Z3*"
839 << " n1<=2*" << " ]";
843 bool isValid() { return true; }
846 MetricAdjacency ( const MetricAdjacency & other );
847 MetricAdjacency & operator= ( const MetricAdjacency & other );
849 // ------------------------- Internals ------------------------------------
852 }; // end of class MetricAdjacency
855 /** Specialize 6-adjacency. */
856 template <typename TSpace>
857 class MetricAdjacency<TSpace, 1, 3>
859 BOOST_CONCEPT_ASSERT(( concepts::CSpace<TSpace> ));
860 // ----------------------- public types ------------------------------
862 // Required by CAdjacency
863 typedef TSpace Space;
864 typedef typename Space::Point Point;
865 typedef MetricAdjacency<Space, 1, 3> Adjacency;
867 typedef typename Space::Integer Integer;
868 typedef typename Space::Vector Vector;
870 // Required by CUndirectedSimpleLocalGraph
871 typedef Point Vertex;
872 typedef typename Space::Size Size;
873 typedef std::set<Vertex> VertexSet; // DigitalSet doesn't seem to fit (MetricAdjacency has no domain)
874 template <typename Value> struct VertexMap {
875 typedef typename std::map<Vertex, Value> Type;
878 // ----------------------- Standard services ------------------------------
882 ~MetricAdjacency() {}
884 // ----------------------- Adjacency services -----------------------------
889 bool isAdjacentTo( const Point & p1, const Point & p2 )
892 return ( v.normInfinity() <= 1 ) && ( v.norm1() <= 1 );
897 bool isProperlyAdjacentTo( const Point & p1, const Point & p2 )
900 if ( v.normInfinity() <= 1 )
902 typename Vector::UnsignedComponent n1 = v.norm1();
908 // ---------------------- Local graph services ----------------------------
921 degree( const Vertex & /* v */ )
926 template <typename OutputIterator>
929 void writeNeighbors( OutputIterator &it, const Vertex & v )
935 *it++ = Vertex( x , y-1, z );
936 *it++ = Vertex( x , y , z-1 );
937 *it++ = Vertex( x-1, y , z );
938 //*it++ = Vertex( x , y , z );
939 *it++ = Vertex( x+1, y , z );
940 *it++ = Vertex( x , y , z+1 );
941 *it++ = Vertex( x , y+1, z );
944 template <typename OutputIterator, typename VertexPredicate>
947 void writeNeighbors( OutputIterator &it, const Vertex & v, const VertexPredicate & pred)
949 Vertex q( v[ 0 ], v[ 1 ], v[ 2 ] - 1 );
950 if ( pred( q ) ) *it++ = q; // x , y , z-1
951 q[ 2 ] += 2; if ( pred( q ) ) *it++ = q; // x , y , z+1
952 --q[ 0 ], --q[ 2 ]; if ( pred( q ) ) *it++ = q; // x-1, y , z
953 q[ 0 ] += 2; if ( pred( q ) ) *it++ = q; // x+1, y , z
954 --q[ 0 ], --q[ 1 ]; if ( pred( q ) ) *it++ = q; // x , y-1, z
955 q[ 1 ] += 2; if ( pred( q ) ) *it++ = q; // x , y+1, z
958 // ----------------------- Interface --------------------------------------
962 void selfDisplay ( std::ostream & out )
964 out << "[MetricAdjacency Z3*"
965 << " n1<=1*" << " ]";
969 bool isValid() { return true; }
972 MetricAdjacency ( const MetricAdjacency & other );
973 MetricAdjacency & operator= ( const MetricAdjacency & other );
975 // ------------------------- Internals ------------------------------------
978 }; // end of class MetricAdjacency