两线段相交计算交点
输入的是两个线段,和一个结果相交点,返回此相交点是否在两条线段的定义域内。
bool VIRCarKeyPoint::has_crspt_2lines(std::vector<cv::Point> &line0, std::vector<cv::Point> &line1, cv::Point &crspt) {
//line0:x0=x00+lamda*(x01-x00) y0=y00+lamda*(y01-y00)
//line1:x1=x10+mu*(x11-x10) y1=y10+mu*(y11-y10)
bool has_crspt_flag = false;
if (line0.size() != 2)
line0.resize(2);
if (line1.size() != 2)
line1.resize(2);
double x0_delta = line0[1].x - line0[0].x;
double y0_delta = line0[1].y - line0[0].y;
double x1_delta = line1[1].x - line1[0].x;
double y1_delta = line1[1].y - line1[0].y;
//lamda*x0_delta-mu*x1_delta=x01_delta
//lamda*y0_delta-mu*y1_delta=y01_delta
double x01_delta = line1[0].x - line0[0].x;
double y01_delta = line1[0].y - line0[0].y;
double delta = x0_delta * (-y1_delta) - y0_delta * (-x1_delta);
if (std::abs(delta) < 1e-6)
{
return false;
}
else
{
}
double lamda = (-x01_delta * y1_delta + y01_delta * x1_delta) / delta;
double mu = (-x01_delta * y0_delta + y01_delta * x0_delta) / delta;
crspt.x = line0[0].x + lamda * x0_delta;
crspt.y = line0[0].y + lamda * y0_delta;
if (lamda >= 0 && lamda <= 1 && mu >= 0 && mu <= 1)
{
has_crspt_flag = true;
}
else
{
}
return has_crspt_flag;
}
两条直线相交
输入的是两条直线的,每条直线含有两个点,输出是两条直线是否有交点,以及交点
bool VIRCarKeyPoint::crspt_two_pointline(std::vector<cv::Point> &line0,std::vector<cv::Point> &line1,cv::Point &crspt)
{
if(line0.size()!=2 || line1.size()!=2)
return false;
float A1=line0[1].x-line0[0].x;
float B1=line0[0].x;
float C1=line1[1].x-line1[0].x;
float D1=line1[0].x;
float A2=line0[1].y-line0[0].y;
float B2=line0[0].y;
float C2=line1[1].y-line1[0].y;
float D2=line1[0].y;
float delta=C1*A2-C2*A1;
if(std::abs(delta)<1e-6)
return false;
float k2=(B1*A2-B2*A1-D1*A2+D2*A1)/delta;
// float k1=(k2*C1+D1-B1)/A1;
crspt.x=(int)(k2*C1+D1);
crspt.y=(int)(k2*C2+D2);
return true;
}
三角形面积计算:
输入的是图片中三角形的三个顶点,返回其面积
double VIRCrossLine::triangle_area(std::vector<cv::Point> &triangle) {
// size_t triangle_size=triangle.size();
// if(triangle_size!=3)
// {
// std::cout<<"error in triangle data!"<<std::endl;
// }
if (triangle.size() != 3)
triangle.resize(3);
double a = std::sqrt(std::pow(triangle[1].x - triangle[0].x, 2) + std::pow(triangle[1].y - triangle[0].y, 2));
double b = std::sqrt(std::pow(triangle[2].x - triangle[1].x, 2) + std::pow(triangle[2].y - triangle[1].y, 2));
double c = std::sqrt(std::pow(triangle[0].x - triangle[2].x, 2) + std::pow(triangle[0].y - triangle[2].y, 2));
double s = 0.5 * (a + b + c);
double area = std::sqrt(s * (s - a) * (s - b) * (s - c));
return area;
}
四边形面积:
输入是四边形的四个顶点,quad.size()=4
double VIRCrossLine::area_quad(std::vector<cv::Point> &quad,) {
//事先判断是否凹四边形 判断方法是对角线是否相交 方法可用has_crspt_2lines判断 但此无必要
bool flag = false;
size_t quad_size = quad.size();
if (quad_size != 4)
{
std::cout << "error in quad data!" << std::endl;
quad.resize(4);
}
else
{
}
std::vector<double> diag1(2);
diag1[0] = quad[2].x - quad[0].x;
diag1[1] = quad[2].y - quad[0].y;
std::vector<double> diag2(2);
diag2[0] = quad[3].x - quad[1].x;
diag2[1] = quad[3].y - quad[1].y;
double diag1_length = std::sqrt(pow(diag1[0], 2) + pow(diag1[1], 2));
double diag2_length = std::sqrt(pow(diag2[0], 2) + pow(diag2[1], 2));
double alpha = std::acos((diag1[0] * diag2[0] + diag1[1] * diag2[1]) / (diag1_length * diag2_length)); //根据前方判断条件 不会发生零除
double quad_area = 0.5 * diag1_length * diag2_length * std::sin(alpha);
return quad_area;
}