DGtal  1.5.beta
testVoronoiMap.cpp
Go to the documentation of this file.
1 
30 #include <iostream>
31 #include <array>
32 #include <algorithm>
33 
34 #include "DGtal/base/Common.h"
35 #include "DGtal/helpers/StdDefs.h"
36 #include "DGtal/images/CConstImage.h"
37 #include "DGtal/geometry/volumes/distance/VoronoiMap.h"
38 #include "DGtal/geometry/volumes/distance/ExactPredicateLpSeparableMetric.h"
39 #include "DGtal/geometry/volumes/distance/InexactPredicateLpSeparableMetric.h"
40 #include "DGtal/geometry/volumes/distance/DistanceTransformation.h"
41 #include "DGtal/kernel/BasicPointPredicates.h"
42 #include "DGtal/io/boards/Board2D.h"
43 #include "DGtal/io/colormaps/HueShadeColorMap.h"
45 
46 using namespace std;
47 using namespace DGtal;
49 // Functions for testing class VoronoiMap.
51 
52 
53 template<typename Point>
54 double mynorm(const Point &point, const double p)
55 {
56  double res=0.0;
57  for(unsigned int i=0; i< Point::dimension; i++)
58  res += std::pow ( (double)abs(point[i]) , p);
59 
60  return std::pow(res, 1.0/p);
61 }
62 
63 template <typename VoroMap>
64 void saveVoroMap(const std::string &filename,const VoroMap &output,const double p)
65 {
66  typedef HueShadeColorMap<double,2> Hue;
67 
68  const double maxdt = mynorm( output.domain().upperBound() - output.domain().lowerBound(), p );
69 
70  Board2D board;
71  Hue hue(0, maxdt);
72 
73  for(typename VoroMap::Domain::ConstIterator it = output.domain().begin(),
74  itend = output.domain().end();
75  it != itend; ++it)
76  {
77  typename VoroMap::Value point = output(*it);
78  board << CustomStyle( (*it).className(), new CustomColors( hue(mynorm(point- (*it),p)),
79  hue(mynorm(point- (*it),p))))
80  << (*it);
81  }
82 
83  board.saveSVG(filename.c_str());
84 }
85 
94 template < typename Point, typename Domain >
96 {
97  auto const & lowerBound = aDomain.lowerBound();
98  auto const & upperBound = aDomain.upperBound();
99 
100  for ( typename Domain::Dimension i = 0; i < Domain::dimension; ++i )
101  aPoint[i] = ( aPoint[i] - 2*lowerBound[i] + upperBound[i] + 1 ) % ( upperBound[i] - lowerBound[i] + 1 ) + lowerBound[i];
102 
103  return aPoint;
104 }
105 
116 template < std::size_t N >
117 std::array<bool, N> getPeriodicityFromInteger( std::size_t anInteger )
118 {
119  std::array<bool, N> periodicity;
120  for ( std::size_t i = 0, mask = 1 ; i < N ; ++i, mask *= 2 )
121  periodicity[i] = anInteger & mask;
122 
123  return periodicity;
124 }
125 
132 template < std::size_t N >
133 std::string formatPeriodicity( std::array<bool, N> const& aPeriodicity )
134 {
135  std::string str;
136  for ( std::size_t i = 0; i < N; ++i )
137  str += aPeriodicity[i] ? '1' : '0';
138 
139  return str;
140 }
141 
144 template < typename Set, typename Voro>
145 bool checkVoronoi(const Set &aSet, const Voro & voro)
146 {
147  typedef typename Voro::Point Point;
148 
149  // Domain extent
150  Point const extent = voro.domain().upperBound() - voro.domain().lowerBound() + Point::diagonal();
151 
152  // Site shifting depending on the periodicity.
153  std::vector< typename Voro::PeriodicitySpec > periodicShift;
154  for ( std::size_t i = 0; i < ( 1u << Voro::Space::dimension ); ++i )
155  {
156  const auto periodicity = getPeriodicityFromInteger< Voro::Space::dimension >( i );
157 
158  // Checking if this periodicity possibility is valid.
159  bool isValid = true;
160  for ( typename Voro::Space::Dimension j = 0; j < periodicity.size(); ++j )
161  if ( periodicity[j] && ! voro.isPeriodic(j) )
162  {
163  isValid = false;
164  break;
165  }
166 
167  if ( isValid )
168  periodicShift.push_back( periodicity );
169  }
170 
171  // Checking site for all domain points.
172  for ( auto const& pt : voro.domain() )
173  {
174  // Calculating reference (raw-)distance.
175  const Point psite = voro(pt);
176  const auto dist = voro.metric()->rawDistance( pt, psite );
177 
178  // Checking that the reference site is actually a given site.
179  // Also testing projectPoint method.
180  if ( std::find( aSet.begin(), aSet.end(), voro.projectPoint( psite ) ) == aSet.end() )
181  {
182  trace.error() << "The Voro point " << psite
183  << " projected to " << voro.projectPoint( psite )
184  << " is not a valid site." << std::endl;
185  return false;
186  }
187 
188  // Checking if we can found a better site.
189  for ( auto site : aSet )
190  {
191  // Trying all shifting possibilities of the site depending on the domain periodicity.
192  for ( auto const & periodicity : periodicShift )
193  {
194  auto currSite = site;
195 
196  // Shifting site.
197  for ( typename Voro::Space::Dimension dim = 0; dim < Voro::Space::dimension ; ++dim )
198  if ( periodicity[dim] )
199  currSite[dim] += ( pt[dim] < currSite[dim] ? -1 : 1 ) * extent[dim];
200 
201  // Checking raw-distance.
202  const auto dbis = voro.metric()->rawDistance( pt, currSite );
203  if ( dbis < dist )
204  {
205  trace.error() << "DT Error at " << pt
206  << " Voro:" << psite << " (" << dist << ")"
207  << " from set:" << site << "(" << dbis << ")"
208  << " projected from " << currSite << "." << std::endl;
209  return false;
210  }
211  }
212  }
213  }
214 
215  return true;
216 }
217 
218 
220 {
223 
224  return true;
225 }
226 
231 bool testVoronoiMap( std::array<bool, 2> const& periodicity = { {false, false} } )
232 {
233  unsigned int nbok = 0;
234  unsigned int nb = 0;
235 
236  trace.beginBlock ( "Testing VoronoiMap2D with periodicity " + formatPeriodicity(periodicity) );
237 
238  Z2i::Point a(-10,-10);
239  Z2i::Point b(10,10);
240  Z2i::Domain domain(a,b);
241 
242  Z2i::DigitalSet mySet(domain);
243 
244  for(Z2i::Domain::ConstIterator it = domain.begin(), itend = domain.end();
245  it != itend;
246  ++it)
247  mySet.insertNew( *it );
248 
249 
250  Z2i::DigitalSet sites(domain);
251 
252  sites.insertNew( Z2i::Point(3,-6));
253  sites.insertNew( Z2i::Point(9,0));
254  sites.insertNew( Z2i::Point(-2,0));
255 
256  for(Z2i::DigitalSet::ConstIterator it = sites.begin(), itend = sites.end();
257  it != itend; ++it)
258  mySet.erase (*it);
259 
260 
261 
264  L2Metric l2;
265  Voro2 voro(&domain, &mySet, &l2, periodicity);
266 
267  for(int j=-10; j <= 10; j++)
268  {
269  for(int i=-10; i<=10; i++)
270  trace.info() << "("<<voro( Z2i::Point(i,j))[0]<<","<< voro( Z2i::Point(i,j))[1]<<") ";
271  trace.info()<<std::endl;
272  }
273 
274  trace.info()<<"Exporting to SVG"<<std::endl;
275 
276  Board2D board;
277  for(Voro2::OutputImage::Domain::ConstIterator it = voro.domain().begin(),
278  itend = voro.domain().end();
279  it != itend; ++it)
280  {
281  const auto p = calcPointModuloDomain( voro(*it), voro.domain() );
282  const unsigned char c = ( p[1]*13 + p[0] * 7) % 256;
283  board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
284  << (*it);
285  }
286 
287  board.saveSVG( ( "Voromap." + formatPeriodicity(periodicity) + ".svg" ).c_str() );
288 
289  trace.beginBlock("Validating the Voronoi Map");
290  nbok += checkVoronoi(sites,voro) ? 1 : 0;
291  nb++;
292  trace.endBlock();
293 
294  trace.endBlock();
295 
296  return nbok == nb;
297 }
298 
299 
300 
305 template<typename Set>
306 bool testVoronoiMapFromSites2D( const Set &aSet,
307  const std::string &name,
308  std::array<bool, 2> const& periodicity = { {false, false} } )
309 {
310  unsigned int nbok = 0;
311  unsigned int nb = 0;
312 
313  Set mySet(aSet.domain());
314 
315  for(typename Set::Domain::ConstIterator it = aSet.domain().begin(), itend = aSet.domain().end();
316  it != itend;
317  ++it)
318  mySet.insertNew( *it );
319 
320 
321  for(typename Set::ConstIterator it = aSet.begin(), itend = aSet.end();
322  it != itend; ++it)
323  mySet.erase (*it);
324 
325 
326  trace.beginBlock(" Voro computation");
329  L2Metric l2;
330  Voro2 voro(aSet.domain(), mySet, l2, periodicity );
331 
332  trace.endBlock();
333 
334  trace.beginBlock(" Voronoi computation l_6");
336  L6Metric l6;
338  Voro6 voro6( aSet.domain(), mySet, l6, periodicity );
339  trace.endBlock();
340 
341 
342 
343  trace.beginBlock(" DT computation");
345  DT dt( aSet.domain(), mySet, l2, periodicity );
346  trace.endBlock();
347 
348 
349  if ( (aSet.domain().upperBound()[1] - aSet.domain().lowerBound()[1]) <20)
350  {
351  for(int j= aSet.domain().lowerBound()[1]; j <= aSet.domain().upperBound()[1]; j++)
352  {
353  for(int i=aSet.domain().lowerBound()[0]; i<=aSet.domain().upperBound()[0]; i++)
354  if ( aSet.find( Z2i::Point(i,j) ) != aSet.end() )
355  std::cout <<"X ";
356  else
357  std::cout<<"0 ";
358  trace.info()<<std::endl;
359  }
360 
361  trace.info() << std::endl;
362 
363  for(int j= aSet.domain().lowerBound()[1]; j <= aSet.domain().upperBound()[1]; j++)
364  {
365  for(int i=aSet.domain().lowerBound()[0]; i<=aSet.domain().upperBound()[0]; i++)
366  trace.info() << "("<<voro( Z2i::Point(i,j))[0]<<","<< voro( Z2i::Point(i,j))[1]<<") ";
367  trace.info()<<std::endl;
368  }
369  }
370 
371  Board2D board;
372  board << voro.domain();
373  for(typename Voro2::OutputImage::Domain::ConstIterator it = voro.domain().begin(), itend = voro.domain().end();
374  it != itend; ++it)
375  {
376  if (!mySet(*it))
377  board << (*it);
378  }
379  std::string filename = "Voromap-" + name + "-orig." + formatPeriodicity(periodicity) + ".svg";
380  board.saveSVG(filename.c_str());
381 
382  board.clear();
383  board << voro.domain();
384  board.setPenColor(Color(0,0,0));
385  for(typename Voro2::OutputImage::Domain::ConstIterator it = voro.domain().begin(), itend = voro.domain().end();
386  it != itend; ++it)
387  {
388  Z2i::Point p = voro(*it);
389  if ((p != (*it)) && (p != voro.domain().upperBound() + Z2i::Point::diagonal(1))
390  && (p != voro.domain().lowerBound()))
391  Display2DFactory::draw( board, p - (*it), (*it));
392  }
393 
394  filename = "Voromap-" + name + "-diag." + formatPeriodicity(periodicity) + ".svg";
395  board.saveSVG(filename.c_str());
396 
397 
398  board.clear();
399  board << voro.domain();
400  for(typename Voro2::OutputImage::Domain::ConstIterator it = voro.domain().begin(), itend = voro.domain().end();
401  it != itend; ++it)
402  {
403  const auto p = calcPointModuloDomain( voro(*it), voro.domain() );
404  unsigned char c = (p[1]*13 + p[0] * 7) % 256;
405  board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
406  << (*it);
407  }
408 
409  filename = "Voromap-" + name + "." + formatPeriodicity(periodicity) + ".svg";
410  board.saveSVG(filename.c_str());
411 
412  filename = "Voromap-" + name + "-hue." + formatPeriodicity(periodicity) + ".svg";
413  saveVoroMap(filename.c_str(),voro,2);
414 
415 
416  board.clear();
417  for(typename Voro6::OutputImage::Domain::ConstIterator it = voro6.domain().begin(),
418  itend = voro6.domain().end();
419  it != itend; ++it)
420  {
421  Z2i::Point p = voro6(*it);
422  if (p != (*it))
423  Display2DFactory::draw( board, p - (*it), (*it));
424  }
425 
426  filename = "Voromap-diag-l6-" + name + "." + formatPeriodicity(periodicity) + ".svg";
427  board.saveSVG(filename.c_str());
428 
429  board.clear();
430  for(typename Voro6::OutputImage::Domain::ConstIterator it = voro6.domain().begin(), itend = voro6.domain().end();
431  it != itend; ++it)
432  {
433  const auto p = calcPointModuloDomain( voro6(*it), voro6.domain() );
434  unsigned char c = (p[1]*13 + p[0] * 7) % 256;
435  board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
436  << (*it);;
437  }
438 
439  filename = "Voromap-l6" + name + "." + formatPeriodicity(periodicity) + ".svg";
440  board.saveSVG(filename.c_str());
441 
442  filename = "Voromap-hue-l6-" + name + "." + formatPeriodicity(periodicity) + ".svg";
443  saveVoroMap(filename.c_str(),voro6,3);
444 
445 
446  trace.beginBlock("Validating the Voronoi Map");
447  nbok += checkVoronoi(aSet, voro) ? 1 : 0;
448  nb++;
449  trace.endBlock();
450 
451  trace.beginBlock("Validating the Voronoi Map l_6");
452  nbok += checkVoronoi(aSet, voro6) ? 1 : 0;
453  nb++;
454  trace.endBlock();
455 
456  return nbok == nb;
457 }
458 
463 template<typename Set>
464 bool testVoronoiMapFromSites( const Set &aSet )
465 {
466  std::array<bool, Set::dimension> periodicity;
467  periodicity.fill( false );
468  return testVoronoiMapFromSites( aSet, periodicity );
469 }
470 
471 template<typename Set>
472 bool testVoronoiMapFromSites( const Set &aSet, std::array<bool, Set::Space::dimension> const & periodicity )
473 {
474  unsigned int nbok = 0;
475  unsigned int nb = 0;
476 
477  Set mySet(aSet.domain());
478 
479  for(typename Set::Domain::ConstIterator it = aSet.domain().begin(),
480  itend = aSet.domain().end();
481  it != itend;
482  ++it)
483  mySet.insertNew( *it );
484 
485 
486  for(typename Set::ConstIterator it = aSet.begin(), itend = aSet.end();
487  it != itend; ++it)
488  mySet.erase (*it);
489 
490 
491 
492  trace.beginBlock(" Voronoi computation l_2");
495  L2Metric l2;
496  Voro2 voro(aSet.domain(), mySet, l2, periodicity);
497  trace.endBlock();
498 
499  trace.beginBlock("Validating the Voronoi Map");
500  nbok += checkVoronoi(aSet, voro) ? 1 : 0;
501  nb++;
502  trace.endBlock();
503 
504  trace.beginBlock(" Voronoi computation l_3");
507  L3Metric l3;
508  Voro3 voro3(aSet.domain(), mySet, l3, periodicity);
509  trace.endBlock();
510 
511  trace.beginBlock("Validating the Voronoi Map l_3");
512  nbok += checkVoronoi(aSet, voro3) ? 1 : 0;
513  nb++;
514  trace.endBlock();
515 
516  trace.beginBlock(" DT computation");
518  DT dt(aSet.domain(), mySet, l2, periodicity);
519  trace.endBlock();
520 
521  return nbok == nb;
522 }
523 
524 
526 {
527 
528  Z2i::Point a(-10,-10);
529  Z2i::Point b(10,10);
530  Z2i::Domain domain(a,b);
531 
532  Z2i::DigitalSet sites(domain);
533  bool ok = true;
534 
535  sites.insertNew( Z2i::Point(3,-6));
536  sites.insertNew( Z2i::Point(9,0));
537  sites.insertNew( Z2i::Point(-3,0));
538 
539  for ( std::size_t i = 0; i < 4; ++i )
540  {
541  auto const periodicity = getPeriodicityFromInteger<2>(i);
542  trace.beginBlock( "Simple2D with periodicity " + formatPeriodicity(periodicity) );
543  ok = ok && testVoronoiMapFromSites2D( sites, "simple", periodicity );
544  trace.endBlock();
545  }
546 
547  return ok;
548 
549 }
550 
552 {
553  unsigned size=16;
554  Z2i::Point a(0,0);
555  Z2i::Point b(size,size);
556  Z2i::Domain domain(a,b);
557 
558  Z2i::DigitalSet sites(domain);
559  bool ok = true;
560 
561  for(unsigned int i = 0 ; i < size; ++i)
562  {
563  Z2i::Point p( rand() % (b[0]) - a[0], rand() % (b[1]) + a[1] );
564  sites.insert( p );
565  }
566 
567  for ( std::size_t i = 0; i < 4; ++i )
568  {
569  auto const periodicity = getPeriodicityFromInteger<2>(i);
570  trace.beginBlock( "Random 2D with periodicity " + formatPeriodicity(periodicity) );
571  ok = ok && testVoronoiMapFromSites2D( sites, "random", periodicity );
572  trace.endBlock();
573  }
574 
575  for(unsigned int i = 0 ; i < size*size-size; ++i)
576  {
577  Z2i::Point p( rand() % (b[0]) - a[0], rand() % (b[1]) + a[1] );
578  sites.insert( p );
579  }
580 
581  for ( std::size_t i = 0; i < 4; ++i )
582  {
583  auto const periodicity = getPeriodicityFromInteger<2>(i);
584  trace.beginBlock( "Random 2D (dense) with periodicity " + formatPeriodicity(periodicity) );
585  ok = ok && testVoronoiMapFromSites2D( sites, "random-dense", periodicity );
586  trace.endBlock();
587  }
588 
589  return ok;
590 }
591 
592 
594 {
595 
596  Z3i::Point a(-10,-10,-10);
597  Z3i::Point b(10,10,10);
598  Z3i::Domain domain(a,b);
599 
600  Z3i::DigitalSet sites(domain);
601  bool ok = true;
602 
603  sites.insertNew( Z3i::Point(0,0,-6));
604  sites.insertNew( Z3i::Point(6,0,0));
605  sites.insertNew( Z3i::Point(-6,0,3));
606 
607  for ( auto i = 0; i < 8; ++i )
608  {
609  auto const periodicity = getPeriodicityFromInteger<3>(i);
610  trace.beginBlock( "Simple3D with periodicity " + formatPeriodicity(periodicity) );
611  ok = ok && testVoronoiMapFromSites( sites, periodicity );
612  trace.endBlock();
613  }
614 
615  return ok;
616 }
617 
619 {
620  std::size_t const N = 16;
621 
622  Z3i::Point a(0, 0, 0);
623  Z3i::Point b(N, N, N);
624  Z3i::Domain domain(a,b);
625 
626  Z3i::DigitalSet sites(domain);
627  bool ok = true;
628 
629  for(unsigned int i = 0 ; i < N; ++i)
630  {
631  Z3i::Point p( rand() % (b[0]) - a[0],
632  rand() % (b[1]) + a[1],
633  rand() % (b[2]) + a[2] );
634  sites.insert( p );
635  }
636 
637  for ( std::size_t i = 0; i < 8; ++i )
638  {
639  auto const periodicity = getPeriodicityFromInteger<3>(i);
640  trace.beginBlock( "Random 3D with periodicity " + formatPeriodicity(periodicity) );
641  ok = ok && testVoronoiMapFromSites( sites, periodicity );
642  trace.endBlock();
643  }
644 
645  return ok;
646 }
647 
648 
649 
651 {
652 
653  typedef SpaceND<4> Space4;
654  Space4::Point a(0,0,0,0);
655  Space4::Point b(5,5,5,5);
657 
659  bool ok = true;
660 
661  sites.insertNew( Space4::Point(1,4,1,1));
662  sites.insertNew( Space4::Point(3,1,3,1));
663  sites.insertNew( Space4::Point(0,0,0,0));
664 
665  for ( std::size_t i = 0; i < 16; ++i )
666  {
667  auto const periodicity = getPeriodicityFromInteger<4>(i);
668  trace.beginBlock( "Simple4D with periodicity " + formatPeriodicity(periodicity) );
669  ok = ok && testVoronoiMapFromSites( sites, periodicity );
670  trace.endBlock();
671  }
672 
673  return ok;
674 }
675 
676 
678 // Standard services - public :
679 
680 int main( int argc, char** argv )
681 {
682  trace.beginBlock ( "Testing class VoronoiMap" );
683  trace.info() << "Args:";
684  for ( int i = 0; i < argc; ++i )
685  trace.info() << " " << argv[ i ];
686  trace.info() << endl;
687 
688  bool res = testCheckConcept()
689  && testVoronoiMap()
690  && testVoronoiMap( { {true, false} } )
691  && testVoronoiMap( { {false, true} } )
692  && testVoronoiMap( { {true, true} } )
693  && testSimple2D()
694  && testSimpleRandom2D()
695  && testSimple3D()
696  && testSimpleRandom3D()
697  && testSimple4D()
698  ; // && ... other tests
699 
700  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
701  trace.endBlock();
702  return res ? 0 : 1;
703 }
704 // //
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Definition: Board2D.h:71
Structure representing an RGB triple with alpha component.
Definition: Color.h:68
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Container::const_iterator ConstIterator
ConstIterator type of the container;.
Aim: A container class for storing sets of digital points within some given domain.
void insertNew(const Point &p)
Aim: Implementation of the linear in time distance transformation for separable metrics.
Aim: implements separable l_p metrics with exact predicates.
Aim: This class template may be used to (linearly) convert scalar values in a given range into a colo...
Iterator for HyperRectDomain.
const ConstIterator & end() const
const ConstIterator & begin() const
const Point & lowerBound() const
const Point & upperBound() const
std::ostream & error()
void beginBlock(const std::string &keyword="")
std::ostream & emphase()
std::ostream & info()
double endBlock()
Aim: Implementation of the linear in time Voronoi map construction.
Definition: VoronoiMap.h:127
Board & setPenColor(const DGtal::Color &color)
Definition: Board.cpp:297
void clear(const DGtal::Color &color=DGtal::Color::None)
Definition: Board.cpp:151
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1011
MyDigitalSurface::ConstIterator ConstIterator
ExactPredicateLpSeparableMetric< Space, 2 > L2Metric
Definition: StdDefs.h:118
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:153
Custom style class redefining the pen color and the fill color. You may use Board2D::Color::None for ...
Definition: Board2D.h:279
Aim: Defines the concept describing a read-only image, which is a refinement of CPointFunctor.
Definition: CConstImage.h:95
MyPointD Point
Definition: testClone2.cpp:383
Domain domain
void draw(const Iterator &itb, const Iterator &ite, Board &aBoard)
const Point aPoint(3, 4)
double mynorm(const Point &point, const double p)
bool testSimple2D()
Point calcPointModuloDomain(Point aPoint, Domain const &aDomain)
int main(int argc, char **argv)
bool testSimple3D()
bool testCheckConcept()
bool testVoronoiMap(std::array< bool, 2 > const &periodicity={ {false, false} })
bool testSimpleRandom3D()
std::string formatPeriodicity(std::array< bool, N > const &aPeriodicity)
void saveVoroMap(const std::string &filename, const VoroMap &output, const double p)
bool testVoronoiMapFromSites(const Set &aSet)
bool testSimple4D()
std::array< bool, N > getPeriodicityFromInteger(std::size_t anInteger)
bool testVoronoiMapFromSites2D(const Set &aSet, const std::string &name, std::array< bool, 2 > const &periodicity={ {false, false} })
bool testSimpleRandom2D()
bool checkVoronoi(const Set &aSet, const Voro &voro)
unsigned int dim(const Vector &z)