You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

line2line.cpp 3.6 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. float DistanceLineToLine(const osg::Vec3d& p1, const osg::Vec3d& p2,
  2. const osg::Vec3d& p3, const osg::Vec3d& p4)
  3. {
  4. float distance;
  5. float x1 = p1.x(); // A点坐标(x1,y1,z1)
  6. float y1 = p1.y();
  7. float z1 = p1.z();
  8. float x2 = p2.x(); // B点坐标(x2,y2,z2)
  9. float y2 = p2.y();
  10. float z2 = p2.z();
  11. float x3 = p3.x(); // C点坐标(x3,y3,z3)
  12. float y3 = p3.y();
  13. float z3 = p3.z();
  14. float x4 = p4.x(); // D点坐标(x4,y4,z4)
  15. float y4 = p4.y();
  16. float z4 = p4.z();
  17. float a =
  18. (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1);
  19. float b = -((x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3) +
  20. (z2 - z1) * (z4 - z3));
  21. float c = -((x1 - x2) * (x1 - x3) + (y1 - y2) * (y1 - y3) +
  22. (z1 - z2) * (z1 - z3));
  23. float d = -((x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3) +
  24. (z2 - z1) * (z4 - z3));
  25. float e =
  26. (x4 - x3) * (x4 - x3) + (y4 - y3) * (y4 - y3) + (z4 - z3) * (z4 - z3);
  27. float f = -((x1 - x3) * (x4 - x3) + (y1 - y3) * (y4 - y3) +
  28. (z1 - z3) * (z4 - z3));
  29. if ((a * e - b * d) == 0 && (b * d - a * e) == 0) //平行
  30. {
  31. float d1 = (p1 - p3).length();
  32. float d2 = (p1 - p4).length();
  33. distance = (d1 < d2) ? d1 : d2;
  34. return distance;
  35. }
  36. float s = (b * f - e * c) / (a * e - b * d);
  37. float t = (a * f - d * c) / (b * d - a * e);
  38. if (0 <= s && s <= 1 && 0 <= t &&
  39. t <= 1) //说明P点落在线段AB上,Q点落在线段CD上
  40. {
  41. // 2条线段的公垂线段PQ;
  42. // P点坐标
  43. float X = x1 + s * (x2 - x1);
  44. float Y = y1 + s * (y2 - y1);
  45. float Z = z1 + s * (z2 - z1);
  46. // Q点坐标
  47. float U = x3 + t * (x4 - x3);
  48. float V = y3 + t * (y4 - y3);
  49. float W = z3 + t * (z4 - z3);
  50. osg::Vec3d P(X, Y, Z);
  51. osg::Vec3d Q(U, V, W);
  52. distance = (P - Q).length();
  53. }
  54. else
  55. {
  56. float d1 = DistancePointToLine(p3, p4, p1);
  57. float d2 = DistancePointToLine(p3, p4, p2);
  58. float d3 = DistancePointToLine(p1, p2, p3);
  59. float d4 = DistancePointToLine(p1, p2, p4);
  60. distance = (d1 < d2) ? d1 : d2;
  61. distance = (distance < d3) ? distance : d3;
  62. distance = (distance < d4) ? distance : d4;
  63. }
  64. return distance;
  65. }
  66. float DistancePointToLine(const osg::Vec3d& star, const osg::Vec3d& end,
  67. const osg::Vec3d& center)
  68. {
  69. float distance;
  70. float x0 = center.x(); // P点坐标(x0,y0,z0)
  71. float y0 = center.y();
  72. float z0 = center.z();
  73. float x1 = star.x(); // A点坐标(x1,y1,z1)
  74. float y1 = star.y();
  75. float z1 = star.z();
  76. float x2 = end.x(); // B点坐标(x2,y2,z2)
  77. float y2 = end.y();
  78. float z2 = end.z();
  79. float t =
  80. ((x1 - x0) * (x1 - x2) + (y1 - y0) * (y1 - y2) +
  81. (z1 - z0) * (z1 - z2)) /
  82. ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
  83. if (0 <= t && t <= 1) //垂足Q点落在线段AB上
  84. {
  85. float X = x1 + t * (x2 - x1);
  86. float Y = y1 + t * (y2 - y1);
  87. float Z = z1 + t * (z2 - z1);
  88. osg::Vec3d Q(X, Y, Z);
  89. distance = (Q - center).length();
  90. }
  91. if (t < 0) //垂足Q点不落在线段AB上,而是落在BA的延长线上
  92. {
  93. distance = (star - center).length();
  94. }
  95. if (t > 1) //垂足Q点不落在线段AB上,而是落在AB的延长线上
  96. {
  97. distance = (end - center).length();
  98. }
  99. return distance;
  100. }