project_to_line.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include "project_to_line.h"
  2. #include <cassert>
  3. template <
  4. typename MatP,
  5. typename MatL,
  6. typename Matt,
  7. typename MatsqrD>
  8. inline void igl::project_to_line(
  9. const MatP & P,
  10. const MatL & S,
  11. const MatL & D,
  12. Matt & t,
  13. MatsqrD & sqrD)
  14. {
  15. // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
  16. // number of dimensions
  17. int dim = P.cols();
  18. assert(dim == S.size());
  19. assert(dim == D.size());
  20. // number of points
  21. int np = P.rows();
  22. // vector from source to destination
  23. MatL DmS = D-S;
  24. double v_sqrlen = (double)(DmS.array().pow(2).sum());
  25. assert(v_sqrlen != 0);
  26. // resize output
  27. t.resize(np,1);
  28. sqrD.resize(np,1);
  29. // loop over points
  30. for(int i = 0;i<np;i++)
  31. {
  32. MatL Pi = P.row(i);
  33. // vector from point i to source
  34. MatL SmPi = S-Pi;
  35. t(i) = -(DmS.array()*SmPi.array()).sum() / v_sqrlen;
  36. // P projected onto line
  37. MatL projP = (1-t(i))*S + t(i)*D;
  38. sqrD(i) = (Pi-projP).array().pow(2).sum();
  39. }
  40. }
  41. template <typename Scalar>
  42. inline void igl::project_to_line(
  43. const Scalar px,
  44. const Scalar py,
  45. const Scalar pz,
  46. const Scalar sx,
  47. const Scalar sy,
  48. const Scalar sz,
  49. const Scalar dx,
  50. const Scalar dy,
  51. const Scalar dz,
  52. Scalar & t,
  53. Scalar & sqrd)
  54. {
  55. // vector from source to destination
  56. Scalar dms[3];
  57. dms[0] = dx-sx;
  58. dms[1] = dy-sy;
  59. dms[2] = dz-sz;
  60. Scalar v_sqrlen = dms[0]*dms[0] + dms[1]*dms[1] + dms[2]*dms[2];
  61. // line should have some length
  62. assert(v_sqrlen != 0);
  63. // vector from point to source
  64. Scalar smp[3];
  65. smp[0] = sx-px;
  66. smp[1] = sy-py;
  67. smp[2] = sz-pz;
  68. t = -(dms[0]*smp[0]+dms[1]*smp[1]+dms[2]*smp[2])/v_sqrlen;
  69. // P projectred onto line
  70. Scalar projp[3];
  71. projp[0] = (1.0-t)*sx + t*dx;
  72. projp[1] = (1.0-t)*sy + t*dy;
  73. projp[2] = (1.0-t)*sz + t*dz;
  74. // vector from projected point to p
  75. Scalar pmprojp[3];
  76. pmprojp[0] = px-projp[0];
  77. pmprojp[1] = py-projp[1];
  78. pmprojp[2] = pz-projp[2];
  79. sqrd = pmprojp[0]*pmprojp[0] + pmprojp[1]*pmprojp[1] + pmprojp[2]*pmprojp[2];
  80. }
  81. #ifndef IGL_HEADER_ONLY
  82. // Explicit template specialization
  83. #endif