c++图片中集合图形运算方法

两线段相交计算交点

输入的是两个线段,和一个结果相交点,返回此相交点是否在两条线段的定义域内。

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;
发布了8 篇原创文章 · 获赞 2 · 访问量 694

猜你喜欢

转载自blog.csdn.net/ZXF_1991/article/details/100727877