project_to_line.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  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 "project_to_line.h"
  9. #include "parallel_for.h"
  10. #include "PlainMatrix.h"
  11. #include <cassert>
  12. #include <Eigen/Core>
  13. template <
  14. typename DerivedP,
  15. typename DerivedS,
  16. typename DerivedD,
  17. typename Derivedt,
  18. typename DerivedsqrD>
  19. IGL_INLINE void igl::project_to_line(
  20. const Eigen::MatrixBase<DerivedP> & P,
  21. const Eigen::MatrixBase<DerivedS> & S,
  22. const Eigen::MatrixBase<DerivedD> & D,
  23. Eigen::PlainObjectBase<Derivedt> & t,
  24. Eigen::PlainObjectBase<DerivedsqrD> & sqrD)
  25. {
  26. // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
  27. // number of dimensions
  28. #ifndef NDEBUG
  29. int dim = P.cols();
  30. assert(dim == S.size());
  31. assert(dim == D.size());
  32. #endif
  33. // number of points
  34. int np = P.rows();
  35. // vector from source to destination
  36. PlainMatrix<DerivedD> DmS = D-S;
  37. double v_sqrlen = (double)(DmS.squaredNorm());
  38. assert(v_sqrlen != 0);
  39. // resize output
  40. t.resize(np,1);
  41. sqrD.resize(np,1);
  42. // loop over points
  43. parallel_for(np,[&](const int i)
  44. {
  45. const typename DerivedP::ConstRowXpr Pi = P.row(i);
  46. // vector from point i to source
  47. const DerivedD SmPi = S-Pi;
  48. t(i) = -(DmS.array()*SmPi.array()).sum() / v_sqrlen;
  49. // P projected onto line
  50. const DerivedD projP = (1-t(i))*S + t(i)*D;
  51. sqrD(i) = (Pi-projP).squaredNorm();
  52. },10000);
  53. }
  54. template <typename Scalar>
  55. IGL_INLINE void igl::project_to_line(
  56. const Scalar px,
  57. const Scalar py,
  58. const Scalar pz,
  59. const Scalar sx,
  60. const Scalar sy,
  61. const Scalar sz,
  62. const Scalar dx,
  63. const Scalar dy,
  64. const Scalar dz,
  65. Scalar & projpx,
  66. Scalar & projpy,
  67. Scalar & projpz,
  68. Scalar & t,
  69. Scalar & sqrd)
  70. {
  71. // vector from source to destination
  72. Scalar dms[3];
  73. dms[0] = dx-sx;
  74. dms[1] = dy-sy;
  75. dms[2] = dz-sz;
  76. Scalar v_sqrlen = dms[0]*dms[0] + dms[1]*dms[1] + dms[2]*dms[2];
  77. // line should have some length
  78. assert(v_sqrlen != 0);
  79. // vector from point to source
  80. Scalar smp[3];
  81. smp[0] = sx-px;
  82. smp[1] = sy-py;
  83. smp[2] = sz-pz;
  84. t = -(dms[0]*smp[0]+dms[1]*smp[1]+dms[2]*smp[2])/v_sqrlen;
  85. // P projectred onto line
  86. projpx = (1.0-t)*sx + t*dx;
  87. projpy = (1.0-t)*sy + t*dy;
  88. projpz = (1.0-t)*sz + t*dz;
  89. // vector from projected point to p
  90. Scalar pmprojp[3];
  91. pmprojp[0] = px-projpx;
  92. pmprojp[1] = py-projpy;
  93. pmprojp[2] = pz-projpz;
  94. sqrd = pmprojp[0]*pmprojp[0] + pmprojp[1]*pmprojp[1] + pmprojp[2]*pmprojp[2];
  95. }
  96. template <typename Scalar>
  97. IGL_INLINE void igl::project_to_line(
  98. const Scalar px,
  99. const Scalar py,
  100. const Scalar pz,
  101. const Scalar sx,
  102. const Scalar sy,
  103. const Scalar sz,
  104. const Scalar dx,
  105. const Scalar dy,
  106. const Scalar dz,
  107. Scalar & t,
  108. Scalar & sqrd)
  109. {
  110. Scalar projpx;
  111. Scalar projpy;
  112. Scalar projpz;
  113. return igl::project_to_line(
  114. px, py, pz, sx, sy, sz, dx, dy, dz,
  115. projpx, projpy, projpz, t, sqrd);
  116. }
  117. #ifdef IGL_STATIC_LIBRARY
  118. // Explicit template instantiation
  119. // generated by autoexplicit.sh
  120. template void igl::project_to_line<Eigen::Matrix<float, 1, -1, 1, 1, -1>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
  121. // generated by autoexplicit.sh
  122. template void igl::project_to_line<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
  123. // generated by autoexplicit.sh
  124. template void igl::project_to_line<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
  125. // generated by autoexplicit.sh
  126. template void igl::project_to_line<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  127. // generated by autoexplicit.sh
  128. template void igl::project_to_line<Eigen::Block<Eigen::Matrix<double, -1, 2, 0, -1, 2> const, -1, -1, false>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, 2, 0, -1, 2> const, -1, -1, false> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  129. // generated by autoexplicit.sh
  130. template void igl::project_to_line<Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
  131. template void igl::project_to_line<double>(double, double, double, double, double, double, double, double, double, double&, double&);
  132. template void igl::project_to_line<double>(double, double, double, double, double, double, double, double, double, double&, double&,double&,double&, double&);
  133. template void igl::project_to_line<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 1, 0, 1, 1>, Eigen::Matrix<double, 1, 1, 0, 1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 1, 0, 1, 1> >&);
  134. template void igl::project_to_line<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  135. #endif