Cone.h
Go to the documentation of this file.
1 #ifndef CONE_HEADER
2 #define CONE_HEADER
3 #ifdef DOPARALLEL
4 #include <omp.h>
5 #endif
6 #include <stdio.h>
7 
8 #include <istream>
9 #include <ostream>
10 #include <stdexcept>
11 
12 #include "LevMarFitting.h"
13 #include "LevMarLSWeight.h"
14 #include "PointCloud.h"
15 #include "basic.h"
17 #include <MiscLib/NoShrinkVector.h>
18 
19 #ifndef DLL_LINKAGE
20 #define DLL_LINKAGE
21 #endif
22 
23 // This implements a one sided cone!
25 {
26 public:
27  struct ParallelPlanesError : public std::runtime_error
28  {
29  ParallelPlanesError() : std::runtime_error("Parallel planes in cone construction")
30  {
31  }
32  };
33 
34  enum
35  {
36  RequiredSamples = 3
37  };
38 
39  Cone();
40  Cone(const Vec3f& center, const Vec3f& axisDir, float angle);
41  Cone(const Vec3f& p1,
42  const Vec3f& p2,
43  const Vec3f& p3,
44  const Vec3f& n1,
45  const Vec3f& n2,
46  const Vec3f& n3);
47  bool Init(const MiscLib::Vector<Vec3f>& samples);
48  bool InitAverage(const MiscLib::Vector<Vec3f>& samples);
49  bool Init(const Vec3f& center, const Vec3f& axisDir, float angle);
50  bool Init(const Vec3f& p1,
51  const Vec3f& p2,
52  const Vec3f& p3,
53  const Vec3f& n1,
54  const Vec3f& n2,
55  const Vec3f& n3);
56  bool Init(bool binary, std::istream* i);
57  void Init(FILE* i);
58  void Init(float* array);
59  inline float Distance(const Vec3f& p) const;
60  inline void Normal(const Vec3f& p, Vec3f* n) const;
61  inline float DistanceAndNormal(const Vec3f& p, Vec3f* n) const;
62  inline float SignedDistance(const Vec3f& p) const;
63  inline float SignedDistanceAndNormal(const Vec3f& p, Vec3f* n) const;
64  void Project(const Vec3f& p, Vec3f* pp) const;
65  // Paramterizes into (length, angle)
66  void Parameters(const Vec3f& p, std::pair<float, float>* param) const;
67  inline float Height(const Vec3f& p) const;
68  inline float Angle() const;
69  inline const Vec3f& Center() const;
70  inline const Vec3f& AxisDirection() const;
71 
72  Vec3f&
74  {
75  return m_axisDir;
76  }
77 
78  inline const Vec3f AngularDirection() const;
79  //void AngularDirection(const Vec3f &angular);
80  void RotateAngularDirection(float radians);
81  inline float RadiusAtLength(float length) const;
82  bool LeastSquaresFit(const PointCloud& pc,
85  template <class IteratorT>
86  bool LeastSquaresFit(IteratorT begin, IteratorT end);
87 
88  bool
89  Fit(const PointCloud& pc,
92  {
93  return LeastSquaresFit(pc, begin, end);
94  }
95 
96  static bool Interpolate(const MiscLib::Vector<Cone>& cones,
97  const MiscLib::Vector<float>& weights,
98  Cone* ic);
99  void Serialize(bool binary, std::ostream* o) const;
100  static size_t SerializedSize();
101  void Serialize(FILE* o) const;
102  void Serialize(float* array) const;
103  static size_t SerializedFloatSize();
104  void Transform(float scale, const Vec3f& translate);
105  void Transform(const GfxTL::MatrixXX<3, 3, float>& rot, const GfxTL::Vector3Df& trans);
106  inline unsigned int
107  Intersect(const Vec3f& p, const Vec3f& r, float lambda[2], Vec3f interPts[2]) const;
108 
109 private:
110  template <class WeightT>
111  class LevMarCone : public WeightT
112  {
113  public:
114  enum
115  {
116  NumParams = 7
117  };
118 
119  typedef float ScalarType;
120 
121  template <class IteratorT>
122  ScalarType
123  Chi(const ScalarType* params,
124  IteratorT begin,
125  IteratorT end,
126  ScalarType* values,
127  ScalarType* temp) const
128  {
129  ScalarType chi = 0;
130  ScalarType cosPhi = std::cos(params[6]);
131  ScalarType sinPhi = std::sin(params[6]);
132  int size = end - begin;
133 #pragma omp parallel for schedule(static) reduction(+ : chi)
134  for (int idx = 0; idx < size; ++idx)
135  {
136  Vec3f s;
137  for (unsigned int j = 0; j < 3; ++j)
138  {
139  s[j] = begin[idx][j] - params[j];
140  }
141  ScalarType g = abs(s[0] * params[3] + s[1] * params[4] + s[2] * params[5]);
142  ScalarType f = s.sqrLength() - (g * g);
143  if (f <= 0)
144  {
145  f = 0;
146  }
147  else
148  {
149  f = std::sqrt(f);
150  }
151  temp[idx] = f;
152  chi += (values[idx] = WeightT::Weigh(cosPhi * f - sinPhi * g)) * values[idx];
153  }
154  return chi;
155  }
156 
157  template <class IteratorT>
158  void
159  Derivatives(const ScalarType* params,
160  IteratorT begin,
161  IteratorT end,
162  const ScalarType* values,
163  const ScalarType* temp,
164  ScalarType* matrix) const
165  {
166  ScalarType sinPhi = -std::sin(params[6]);
167  ScalarType cosPhi = std::cos(params[6]);
168  int size = end - begin;
169 #pragma omp parallel for schedule(static)
170  for (int idx = 0; idx < size; ++idx)
171  {
172  Vec3f s;
173  for (unsigned int j = 0; j < 3; ++j)
174  {
175  s[j] = begin[idx][j] - params[j];
176  }
177  ScalarType g = abs(s[0] * params[3] + s[1] * params[4] + s[2] * params[5]);
178  ScalarType ggradient[6];
179  for (unsigned int j = 0; j < 3; ++j)
180  {
181  ggradient[j] = -params[j + 3];
182  }
183  for (unsigned int j = 0; j < 3; ++j)
184  {
185  ggradient[j + 3] = s[j] - params[j + 3] * g;
186  }
187  ScalarType fgradient[6];
188  if (temp[idx] < 1e-6)
189  {
190  fgradient[0] = std::sqrt(1 - params[3] * params[3]);
191  fgradient[1] = std::sqrt(1 - params[4] * params[4]);
192  fgradient[2] = std::sqrt(1 - params[5] * params[5]);
193  }
194  else
195  {
196  fgradient[0] = (params[3] * g - s[0]) / temp[idx];
197  fgradient[1] = (params[4] * g - s[1]) / temp[idx];
198  fgradient[2] = (params[5] * g - s[2]) / temp[idx];
199  }
200  fgradient[3] = g * fgradient[0];
201  fgradient[4] = g * fgradient[1];
202  fgradient[5] = g * fgradient[2];
203  for (unsigned int j = 0; j < 6; ++j)
204  matrix[idx * NumParams + j] = cosPhi * fgradient[j] + sinPhi * ggradient[j];
205  matrix[idx * NumParams + 6] = temp[idx] * sinPhi - g * cosPhi;
206  WeightT::template DerivWeigh<NumParams>(cosPhi * temp[idx] + sinPhi * g,
207  matrix + idx * NumParams);
208  }
209  }
210 
211  void
212  Normalize(float* params) const
213  {
214  // normalize direction
215  ScalarType l =
216  std::sqrt(params[3] * params[3] + params[4] * params[4] + params[5] * params[5]);
217  for (unsigned int i = 3; i < 6; ++i)
218  {
219  params[i] /= l;
220  }
221  // normalize angle
222  params[6] -= std::floor(params[6] / (2 * ScalarType(M_PI))) *
223  (2 * ScalarType(M_PI)); // params[6] %= 2*M_PI
224  if (params[6] > M_PI)
225  {
226  params[6] -= std::floor(params[6] / ScalarType(M_PI)) *
227  ScalarType(M_PI); // params[6] %= M_PI
228  for (unsigned int i = 3; i < 6; ++i)
229  {
230  params[i] *= -1;
231  }
232  }
233  if (params[6] > ScalarType(M_PI) / 2)
234  {
235  params[6] = ScalarType(M_PI) - params[6];
236  }
237  }
238  };
239 
240 private:
241  Vec3f m_center; // this is the apex of the cone
242  Vec3f m_axisDir; // the axis points into the interior of the cone
243  float m_angle; // the opening angle
244  Vec3f m_normal;
245  Vec3f m_normalY; // precomputed normal part
246  float m_n2d[2];
248  float m_angularRotatedRadians;
249 };
250 
251 inline float
252 Cone::Distance(const Vec3f& p) const
253 {
254  // this is for one sided cone!
255  Vec3f s = p - m_center;
256  float g = s.dot(m_axisDir); // distance to plane orhogonal to
257  // axisdir through center
258  // distance to axis
259  float sqrS = s.sqrLength();
260  float f = sqrS - (g * g);
261  if (f <= 0)
262  {
263  f = 0;
264  }
265  else
266  {
267  f = std::sqrt(f);
268  }
269  float da = m_n2d[0] * f;
270  float db = m_n2d[1] * g;
271  if (g < 0 && da - db < 0) // is inside other side of cone -> disallow
272  {
273  return std::sqrt(sqrS);
274  }
275  return abs(da + db);
276 }
277 
278 inline void
279 Cone::Normal(const Vec3f& p, Vec3f* n) const
280 {
281  Vec3f s = p - m_center;
282  Vec3f pln = s.cross(m_axisDir);
283  Vec3f plx = m_axisDir.cross(pln);
284  plx.normalize();
285  // we are not dealing with two-sided cone
286  *n = m_normal[0] * plx + m_normalY;
287 }
288 
289 inline float
291 {
292  // this is for one-sided cone !!!
293  Vec3f s = p - m_center;
294  float g = s.dot(m_axisDir); // distance to plane orhogonal to
295  // axisdir through center
296  // distance to axis
297  float sqrS = s.sqrLength();
298  float f = sqrS - (g * g);
299  if (f <= 0)
300  {
301  f = 0;
302  }
303  else
304  {
305  f = std::sqrt(f);
306  }
307  float da = m_n2d[0] * f;
308  float db = m_n2d[1] * g;
309  float dist;
310  if (g < 0 && da - db < 0) // is inside other side of cone -> disallow
311  {
312  dist = std::sqrt(sqrS);
313  }
314  else
315  {
316  dist = abs(da + db);
317  }
318  // need normal
319  Vec3f plx = s - g * m_axisDir;
320  plx.normalize();
321  *n = m_normal[0] * plx + m_normalY;
322  return dist;
323 }
324 
325 inline float
327 {
328  // this is for one sided cone!
329  Vec3f s = p - m_center;
330  float g = s.dot(m_axisDir); // distance to plane orhogonal to
331  // axisdir through center
332  // distance to axis
333  float sqrS = s.sqrLength();
334  float f = sqrS - (g * g);
335  if (f <= 0)
336  {
337  f = 0;
338  }
339  else
340  {
341  f = std::sqrt(f);
342  }
343  float da = m_n2d[0] * f;
344  float db = m_n2d[1] * g;
345  if (g < 0 && da - db < 0) // is inside other side of cone -> disallow
346  {
347  return std::sqrt(sqrS);
348  }
349  return da + db;
350 }
351 
352 inline float
354 {
355  // this is for one-sided cone !!!
356  Vec3f s = p - m_center;
357  float g = s.dot(m_axisDir); // distance to plane orhogonal to
358  // axisdir through center
359  // distance to axis
360  float sqrS = s.sqrLength();
361  float f = sqrS - (g * g);
362  if (f <= 0)
363  {
364  f = 0;
365  }
366  else
367  {
368  f = std::sqrt(f);
369  }
370  float da = m_n2d[0] * f;
371  float db = m_n2d[1] * g;
372  float dist;
373  if (g < 0 && da - db < 0) // is inside other side of cone -> disallow
374  {
375  dist = std::sqrt(sqrS);
376  }
377  else
378  {
379  dist = da + db;
380  }
381  // need normal
382  Vec3f plx = s - g * m_axisDir;
383  plx.normalize();
384  *n = m_normal[0] * plx + m_normalY;
385  return dist;
386 }
387 
388 float
389 Cone::Angle() const
390 {
391  return m_angle;
392 }
393 
394 const Vec3f&
396 {
397  return m_center;
398 }
399 
400 const Vec3f&
402 {
403  return m_axisDir;
404 }
405 
406 const Vec3f
408 {
409  return Vec3f(m_hcs[0].Data());
410 }
411 
412 float
413 Cone::RadiusAtLength(float length) const
414 {
415  return std::sin(m_angle) * abs(length);
416 }
417 
418 float
419 Cone::Height(const Vec3f& p) const
420 {
421  Vec3f s = p - m_center;
422  return m_axisDir.dot(s);
423 }
424 
425 template <class IteratorT>
426 bool
427 Cone::LeastSquaresFit(IteratorT begin, IteratorT end)
428 {
429  float param[7];
430  for (unsigned int i = 0; i < 3; ++i)
431  {
432  param[i] = m_center[i];
433  }
434  for (unsigned int i = 0; i < 3; ++i)
435  {
436  param[i + 3] = m_axisDir[i];
437  }
438  param[6] = m_angle;
439  LevMarCone<LevMarLSWeight> levMarCone;
440  if (!LevMar(begin, end, levMarCone, param))
441  {
442  return false;
443  }
444  if (param[6] < 1e-6 || param[6] > float(M_PI) / 2 - 1e-6)
445  {
446  return false;
447  }
448  for (unsigned int i = 0; i < 3; ++i)
449  {
450  m_center[i] = param[i];
451  }
452  for (unsigned int i = 0; i < 3; ++i)
453  {
454  m_axisDir[i] = param[i + 3];
455  }
456  m_angle = param[6];
457  m_normal = Vec3f(std::cos(-m_angle), std::sin(-m_angle), 0);
458  m_normalY = m_normal[1] * m_axisDir;
459  m_n2d[0] = std::cos(m_angle);
460  m_n2d[1] = -std::sin(m_angle);
461  m_hcs.FromNormal(m_axisDir);
462  m_angularRotatedRadians = 0;
463  // it could be that the axis has flipped during fitting
464  // we need to detect such a case
465  // for this we run over all points and compute the sum
466  // of their respective heights. If that sum is negative
467  // the axis needs to be flipped.
468  float heightSum = 0;
469  intptr_t size = end - begin;
470 #ifndef _WIN64 // for some reason the Microsoft x64 compiler crashes at the next line
471 #pragma omp parallel for schedule(static) reduction(+ : heightSum)
472 #endif
473  for (intptr_t i = 0; i < size; ++i)
474  {
475  heightSum += Height(begin[i]);
476  }
477  if (heightSum < 0)
478  {
479  m_axisDir *= -1;
480  m_hcs.FromNormal(m_axisDir);
481  }
482  return true;
483 }
484 
485 inline unsigned int
486 Cone::Intersect(const Vec3f& p, const Vec3f& r, float lambda[2], Vec3f interPts[2]) const
487 {
488  // Set up the quadratic Q(t) = c2*t^2 + 2*c1*t + c0 that corresponds to
489  // the cone. Let the vertex be V, the unit-length direction vector be A,
490  // and the angle measured from the cone axis to the cone wall be Theta,
491  // and define g = cos(Theta). A point X is on the cone wall whenever
492  // Dot(A,(X-V)/|X-V|) = g. Square this equation and factor to obtain
493  // (X-V)^T * (A*A^T - g^2*I) * (X-V) = 0
494  // where the superscript T denotes the transpose operator. This defines
495  // a double-sided cone. The line is L(t) = P + t*D, where P is the line
496  // origin and D is a unit-length direction vector. Substituting
497  // X = L(t) into the cone equation above leads to Q(t) = 0. Since we
498  // want only intersection points on the single-sided cone that lives in
499  // the half-space pointed to by A, any point L(t) generated by a root of
500  // Q(t) = 0 must be tested for Dot(A,L(t)-V) >= 0.
501  using namespace std;
502  float fAdD = m_axisDir.dot(r);
503  float tmp, fCosSqr = (tmp = cos(m_angle)) * tmp;
504  Vec3f kE = p - m_center;
505  float fAdE = m_axisDir.dot(kE);
506  float fDdE = r.dot(kE);
507  float fEdE = kE.dot(kE);
508  float fC2 = fAdD * fAdD - fCosSqr;
509  float fC1 = fAdD * fAdE - fCosSqr * fDdE;
510  float fC0 = fAdE * fAdE - fCosSqr * fEdE;
511  float fdot;
512 
513  // Solve the quadratic. Keep only those X for which Dot(A,X-V) >= 0.
514  unsigned int interCount = 0;
515  if (abs(fC2) >= 1e-7)
516  {
517  // c2 != 0
518  float fDiscr = fC1 * fC1 - fC0 * fC2;
519  if (fDiscr < (float)0.0)
520  {
521  // Q(t) = 0 has no real-valued roots. The line does not
522  // intersect the double-sided cone.
523  return 0;
524  }
525  else if (fDiscr > 1e-7)
526  {
527  // Q(t) = 0 has two distinct real-valued roots. However, one or
528  // both of them might intersect the portion of the double-sided
529  // cone "behind" the vertex. We are interested only in those
530  // intersections "in front" of the vertex.
531  float fRoot = sqrt(fDiscr);
532  float fInvC2 = ((float)1.0) / fC2;
533  interCount = 0;
534 
535  float fT = (-fC1 - fRoot) * fInvC2;
536  if (fT > 0) // intersect only in positive direction of ray
537  {
538  interPts[interCount] = p + fT * r;
539  kE = interPts[interCount] - m_center;
540  fdot = kE.dot(m_axisDir);
541  if (fdot > (float)0.0)
542  {
543  lambda[interCount] = fT;
544  interCount++;
545  }
546  }
547 
548  fT = (-fC1 + fRoot) * fInvC2;
549  if (fT > 0)
550  {
551  interPts[interCount] = p + fT * r;
552  kE = interPts[interCount] - m_center;
553  fdot = kE.dot(m_axisDir);
554  if (fdot > (float)0.0)
555  {
556  lambda[interCount] = fT;
557  interCount++;
558  }
559  }
560  }
561  else if (fC1 / fC2 < 0)
562  {
563  // one repeated real root (line is tangent to the cone)
564  interPts[0] = p - (fC1 / fC2) * r;
565  lambda[0] = -(fC1 / fC2);
566  kE = interPts[0] - m_center;
567  if (kE.dot(m_axisDir) > (float)0.0)
568  {
569  interCount = 1;
570  }
571  else
572  {
573  interCount = 0;
574  }
575  }
576  }
577  else if (abs(fC1) >= 1e-7)
578  {
579  // c2 = 0, c1 != 0 (D is a direction vector on the cone boundary)
580  lambda[0] = -(((float)0.5) * fC0 / fC1);
581  if (lambda[0] < 0)
582  {
583  return 0;
584  }
585  interPts[0] = p + lambda[0] * r;
586  kE = interPts[0] - m_center;
587  fdot = kE.dot(m_axisDir);
588  if (fdot > (float)0.0)
589  {
590  interCount = 1;
591  }
592  else
593  {
594  interCount = 0;
595  }
596  }
597  else if (abs(fC0) >= 1e-7)
598  {
599  // c2 = c1 = 0, c0 != 0
600  interCount = 0;
601  }
602  else
603  {
604  // c2 = c1 = c0 = 0, cone contains ray V+t*D where V is cone vertex
605  // and D is the line direction.
606  interCount = 1;
607  lambda[0] = (m_center - p).dot(r);
608  interPts[0] = m_center;
609  }
610 
611  return interCount;
612 }
613 
614 #endif
GfxTL::HyperplaneCoordinateSystem< float, 3 >
GfxTL::VectorXD
Definition: MatrixXX.h:24
cyberglove_with_calib_22dof.ic
ic
Definition: cyberglove_with_calib_22dof.py:22
GfxTL::Vec3f
VectorXD< 3, float > Vec3f
Definition: VectorXD.h:733
Cone::Intersect
unsigned int Intersect(const Vec3f &p, const Vec3f &r, float lambda[2], Vec3f interPts[2]) const
Definition: Cone.h:486
Vec3f::normalize
float normalize()
Definition: basic.h:141
Vec3f
Definition: basic.h:17
Vec3f::cross
Vec3f cross(const Vec3f &v) const
Definition: basic.h:121
Cone::Distance
float Distance(const Vec3f &p) const
Definition: Cone.h:252
Cone::Normal
void Normal(const Vec3f &p, Vec3f *n) const
Definition: Cone.h:279
armarx::view_selection::skills::direction::state::Center
constexpr std::uint8_t Center
Definition: LookDirection.h:50
Cone::ParallelPlanesError::ParallelPlanesError
ParallelPlanesError()
Definition: Cone.h:29
ProsthesisInterface.values
values
Definition: ProsthesisInterface.py:190
Cone::DistanceAndNormal
float DistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition: Cone.h:290
armarx::skills::gui::Parameters
aron::data::DictPtr Parameters
Definition: SkillManagerWrapper.h:21
GfxTL::MatrixXX
Definition: MatrixXX.h:28
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:418
MiscLib::Vector
Definition: Vector.h:19
LevMarFitting.h
Cone::ParallelPlanesError
Definition: Cone.h:27
NoShrinkVector.h
Cone::Fit
bool Fit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition: Cone.h:89
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
M_PI
#define M_PI
Definition: MathTools.h:17
Cone
Definition: Cone.h:24
Cone::SignedDistance
float SignedDistance(const Vec3f &p) const
Definition: Cone.h:326
HyperplaneCoordinateSystem.h
Cone::Angle
float Angle() const
Definition: Cone.h:389
Cone::Center
const Vec3f & Center() const
Definition: Cone.h:395
Cone::RadiusAtLength
float RadiusAtLength(float length) const
Definition: Cone.h:413
PointCloud
Definition: PointCloud.h:85
Cone::AxisDirection
Vec3f & AxisDirection()
Definition: Cone.h:73
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
Vec3f::dot
float dot(const Vec3f &v) const
Definition: basic.h:104
float
#define float
Definition: 16_Level.h:22
basic.h
std
Definition: Application.h:66
armarx::view_selection::skills::direction::state::center
state::Type center(state::Type previous)
Definition: LookDirection.cpp:233
LevMarLSWeight.h
dot
double dot(const Point &x, const Point &y)
Definition: point.hpp:57
Cone::SignedDistanceAndNormal
float SignedDistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition: Cone.h:353
PointCloud.h
DLL_LINKAGE
#define DLL_LINKAGE
Definition: basic.h:12
angle
double angle(const Point &a, const Point &b, const Point &c)
Definition: point.hpp:109
pc
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics Blackwell June If you use this software you should cite the aforementioned paper in any resulting publication Please send comments or bug reports to Ruwen Roland BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE Example usage This section shows how to use the library to detect the shapes in a point cloud PointCloud pc
Definition: ReadMe.txt:68
Cone::AngularDirection
const Vec3f AngularDirection() const
Definition: Cone.h:407
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
LevMar
bool LevMar(IteratorT begin, IteratorT end, FuncT &func, typename FuncT::ScalarType *param)
Definition: LevMarFitting.h:152
Cone::AxisDirection
const Vec3f & AxisDirection() const
Definition: Cone.h:401
Cone::Height
float Height(const Vec3f &p) const
Definition: Cone.h:419
Cone::LeastSquaresFit
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition: Cone.cpp:699