|
- float DistanceLineToLine(const osg::Vec3d& p1, const osg::Vec3d& p2,
- const osg::Vec3d& p3, const osg::Vec3d& p4)
- {
- float distance;
- float x1 = p1.x(); // A点坐标(x1,y1,z1)
- float y1 = p1.y();
- float z1 = p1.z();
- float x2 = p2.x(); // B点坐标(x2,y2,z2)
- float y2 = p2.y();
- float z2 = p2.z();
- float x3 = p3.x(); // C点坐标(x3,y3,z3)
- float y3 = p3.y();
- float z3 = p3.z();
- float x4 = p4.x(); // D点坐标(x4,y4,z4)
- float y4 = p4.y();
- float z4 = p4.z();
-
- float a =
- (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1);
- float b = -((x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3) +
- (z2 - z1) * (z4 - z3));
- float c = -((x1 - x2) * (x1 - x3) + (y1 - y2) * (y1 - y3) +
- (z1 - z2) * (z1 - z3));
-
- float d = -((x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3) +
- (z2 - z1) * (z4 - z3));
- float e =
- (x4 - x3) * (x4 - x3) + (y4 - y3) * (y4 - y3) + (z4 - z3) * (z4 - z3);
- float f = -((x1 - x3) * (x4 - x3) + (y1 - y3) * (y4 - y3) +
- (z1 - z3) * (z4 - z3));
-
- if ((a * e - b * d) == 0 && (b * d - a * e) == 0) //平行
- {
- float d1 = (p1 - p3).length();
- float d2 = (p1 - p4).length();
- distance = (d1 < d2) ? d1 : d2;
- return distance;
- }
-
- float s = (b * f - e * c) / (a * e - b * d);
- float t = (a * f - d * c) / (b * d - a * e);
-
- if (0 <= s && s <= 1 && 0 <= t &&
- t <= 1) //说明P点落在线段AB上,Q点落在线段CD上
- {
- // 2条线段的公垂线段PQ;
- // P点坐标
- float X = x1 + s * (x2 - x1);
- float Y = y1 + s * (y2 - y1);
- float Z = z1 + s * (z2 - z1);
- // Q点坐标
- float U = x3 + t * (x4 - x3);
- float V = y3 + t * (y4 - y3);
- float W = z3 + t * (z4 - z3);
- osg::Vec3d P(X, Y, Z);
- osg::Vec3d Q(U, V, W);
- distance = (P - Q).length();
- }
- else
- {
- float d1 = DistancePointToLine(p3, p4, p1);
- float d2 = DistancePointToLine(p3, p4, p2);
- float d3 = DistancePointToLine(p1, p2, p3);
- float d4 = DistancePointToLine(p1, p2, p4);
- distance = (d1 < d2) ? d1 : d2;
- distance = (distance < d3) ? distance : d3;
- distance = (distance < d4) ? distance : d4;
- }
- return distance;
- }
-
- float DistancePointToLine(const osg::Vec3d& star, const osg::Vec3d& end,
- const osg::Vec3d& center)
- {
- float distance;
- float x0 = center.x(); // P点坐标(x0,y0,z0)
- float y0 = center.y();
- float z0 = center.z();
- float x1 = star.x(); // A点坐标(x1,y1,z1)
- float y1 = star.y();
- float z1 = star.z();
- float x2 = end.x(); // B点坐标(x2,y2,z2)
- float y2 = end.y();
- float z2 = end.z();
- float t =
- ((x1 - x0) * (x1 - x2) + (y1 - y0) * (y1 - y2) +
- (z1 - z0) * (z1 - z2)) /
- ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
- if (0 <= t && t <= 1) //垂足Q点落在线段AB上
- {
- float X = x1 + t * (x2 - x1);
- float Y = y1 + t * (y2 - y1);
- float Z = z1 + t * (z2 - z1);
- osg::Vec3d Q(X, Y, Z);
- distance = (Q - center).length();
- }
- if (t < 0) //垂足Q点不落在线段AB上,而是落在BA的延长线上
- {
- distance = (star - center).length();
- }
- if (t > 1) //垂足Q点不落在线段AB上,而是落在AB的延长线上
- {
- distance = (end - center).length();
- }
- return distance;
- }
|