由空间中的两条异面直线间的距离公式:
d
=
(
e
1
⃗
×
e
2
⃗
)
⋅
M
1
M
2
→
∣
e
1
⃗
×
e
2
⃗
∣
d = \frac{(\vec{e_{1}} \times \vec{e_{2}} ) \cdot \overrightarrow{M_{1}M_{2}}}{ |\vec{e_{1}} \times \vec{e_{2}}|}
d=∣e1×e2∣(e1×e2)⋅M1M2
式中,
e
1
⃗
e
2
⃗
\vec{e_{1}} \quad \vec{e_{2}}
e1e2 为方向向量,
M
1
M
2
→
\overrightarrow{M_{1}M_{2}}
M1M2为直线上两定点确定的向量。
理解为:两个方向向量的叉乘确定与与这两个方向向量垂直的法向量,由直线上两定点所构成的向量到该向量上的投影即为两直线间的距离。
运用OpenCV中Viz进行可视化可以看到:
程序代码为(需要OpenCV中Viz模块的支持):
#include <iostream>
#include <vector>
#include <string>
// OpenCV
#include "opencv2/core.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/viz.hpp"
using namespace std;
using namespace cv;
int main(int argc, char **argv) {
// 建立窗口 显示坐标系 R G B 分别代表X Y Z三轴
viz::Viz3d myWindow("Main_Window");
myWindow.showWidget("Coordinate", viz::WCoordinateSystem(), Affine3f::Identity());
// 两条直线上的定点
Point3f A, B, C, D;
A = Point3f(1, 0, 1), B = Point3f(1, 0, -1), C = Point3f(1, 1, 1), D = Point3f(-1, 1, -1);
// 创建直线
viz::WLine FirstLine(A, B, viz::Color::black());
viz::WLine SecondLine(C, D, viz::Color::brown());
// 计算方向向量
// 第一条直线 第二条直线的方向向量为
Vec3f VecFirstLine = (B - A), VecSecondLine = (C - D);
Point3f PointFirst = A, PointSecond = C;
// 依据异面直线公式
Vec3f VecCross = VecFirstLine.cross(VecSecondLine);
VecCross = normalize(VecCross);
Vec3f VecPoint(PointSecond.x - PointFirst.x, PointSecond.y - PointFirst.y, PointSecond.z - PointFirst.z);
float Distance = abs((VecCross.dot(VecPoint)));
cout << "Distance:\t" << Distance << endl;
// 可视化
myWindow.showWidget("FirstLine", FirstLine, Affine3d::Identity());
myWindow.showWidget("SecondLine", SecondLine, Affine3d::Identity());
myWindow.setRenderingProperty("FirstLine", viz::LINE_WIDTH, 2);
myWindow.setRenderingProperty("SecondLine", viz::LINE_WIDTH, 2);
myWindow.spin();
std::cout << "Hello, World!" << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(SkewLineDistance)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenCV 4 REQUIRED)
message(STATUS "OpenCV library status:")
message(STATUS " OpenCV Version: ${OpenCV_VERSION}" )
include_directories(${OpenCV_INCLUDES})
add_executable(SkewLineDistance_Version1 main.cpp)
target_link_libraries(SkewLineDistance_Version1 ${OpenCV_LIBS} )