//一个细微的模块,干脆放在这里备忘
//顺便,喜迎十九大,233
计算出点1,2形成直线与点3,4形成直线的交点
如果有无穷多个或者平行,那么返回2和3的中间点
下面就是简单粗暴的功能函数
cv::Point 交点(cv::Point 点1, cv::Point 点2, cv::Point 点3, cv::Point 点4) {
//计算点1,2形成直线与点3,4形成直线交点
//如果平行或有无穷个交点就取点2和3的中间点
int x, y;
int X1 = 点1.x - 点2.x, Y1 = 点1.y - 点2.y, X2 = 点3.x - 点4.x, Y2 = 点3.y - 点4.y;
//(点1.x-x)/(点1.y-y)=X1/Y1
//(点1.x-x)Y1=X1(点1.y-y)
//X1*y=(Y1*x+X1*点1.y-Y1*点1.x)
//X2*y=(Y2*x+X2*点3.y-Y2*点3.x)
if (X1*Y2 == X2*Y1)return cv::Point((点2.x+点3.x)/2,(点2.y+点3.y)/2);
int A = X1*点1.y - Y1*点1.x,B= X2*点3.y - Y2*点3.x;
//X1*y=(Y1*x+A)
//X2*y=(Y2*x+B)
y = (A*Y2 - B*Y1) / (X1*Y2 - X2*Y1);
x = (B*X1-A*X2) / (Y1*X2 - Y2*X1);
return cv::Point(x, y);
}
以及完整测试:
#include<opencv2/opencv.hpp>
using namespace cv;
cv::Point 交点(cv::Point 点1, cv::Point 点2, cv::Point 点3, cv::Point 点4) {
//计算点1,2形成直线与点3,4形成直线交点
//如果平行或有无穷个交点就取点2和3的中间点
int x, y;
int X1 = 点1.x - 点2.x, Y1 = 点1.y - 点2.y, X2 = 点3.x - 点4.x, Y2 = 点3.y - 点4.y;
//(点1.x-x)/(点1.y-y)=X1/Y1
//(点1.x-x)Y1=X1(点1.y-y)
//X1*y=(Y1*x+X1*点1.y-Y1*点1.x)
//X2*y=(Y2*x+X2*点3.y-Y2*点3.x)
if (X1*Y2 == X2*Y1)return cv::Point((点2.x + 点3.x) / 2, (点2.y + 点3.y) / 2);
int A = X1*点1.y - Y1*点1.x, B = X2*点3.y - Y2*点3.x;
//X1*y=(Y1*x+A)
//X2*y=(Y2*x+B)
y = (A*Y2 - B*Y1) / (X1*Y2 - X2*Y1);
x = (B*X1 - A*X2) / (Y1*X2 - Y2*X1);
return cv::Point(x, y);
}
int main() {
cv::Mat 画布(500, 500, CV_8UC3);
画布 = cv::Scalar(255,255,255);
cv::Point 点1(200, 100), 点2(100, 50), 点3(400, 50), 点4(100, 380);
cv::circle(画布, 点1, 5, cv::Scalar(255, 0, 0), -1);
cv::circle(画布, 点2, 5, cv::Scalar(255, 0, 0), -1);
cv::circle(画布, 点3, 5, cv::Scalar(255, 0, 0), -1);
cv::circle(画布, 点4, 5, cv::Scalar(255, 0, 0), -1);
line(画布, 点2 - 点1, 3*(点2 + 点1), Scalar(111, 111, 255));
line(画布, 点3+2*(点4 - 点3), 点3 -3 * (点4 - 点3), Scalar(111, 111, 255));
cv::Point 结果 = 交点(点1, 点2, 点3, 点4);
cv::circle(画布, 结果, 5, cv::Scalar(0, 255, 0), -1);
std::cout << "最终坐标为" << 结果;
cv::imshow("计算交点", 画布);
cv::waitKey(-1);
return 0;
}
以后可以叫我老中医……