partition.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "partition.h"
  9. #include "mat_min.h"
  10. IGL_INLINE void igl::partition(
  11. const Eigen::MatrixXd & W,
  12. const int k,
  13. Eigen::Matrix<int,Eigen::Dynamic,1> & G,
  14. Eigen::Matrix<int,Eigen::Dynamic,1> & S,
  15. Eigen::Matrix<double,Eigen::Dynamic,1> & D)
  16. {
  17. // number of mesh vertices
  18. int n = W.rows();
  19. // Resize output
  20. G.resize(n);
  21. S.resize(k);
  22. // "Randomly" choose first seed
  23. // Pick a vertex farthest from 0
  24. int s;
  25. (W.array().square().matrix()).rowwise().sum().maxCoeff(&s);
  26. S(0) = s;
  27. // Initialize distance to closest seed
  28. D = ((W.rowwise() - W.row(s)).array().square()).matrix().rowwise().sum();
  29. G.setZero();
  30. // greedily choose the remaining k-1 seeds
  31. for(int i = 1;i<k;i++)
  32. {
  33. // Find maximum in D
  34. D.maxCoeff(&s);
  35. S(i) = s;
  36. // distance to this seed
  37. Eigen::Matrix<double,Eigen::Dynamic,1> Ds =
  38. ((W.rowwise() - W.row(s)).array().square()).matrix().rowwise().sum();
  39. // Concatenation of D and Ds: DDs = [D Ds];
  40. Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> DDs;
  41. // Make space for two columns
  42. DDs.resize(D.rows(),2);
  43. DDs.col(0) = D;
  44. DDs.col(1) = Ds;
  45. // Update D
  46. // get minimum of old D and distance to this seed, C == 1 if new distance
  47. // was smaller
  48. Eigen::Matrix<int,Eigen::Dynamic,1> C;
  49. igl::mat_min(DDs,2,D,C);
  50. G = (C.array() ==0).select(G,i);
  51. }
  52. }