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;
好资源#include #include #include using namespace std; //表结点 typedef struct ArcNode{ int adjvex;//该弧所指向的顶点的位置 ArcNode *nextarc;//指向下一条弧的指针 }ArcNode; //头结点 typedef struct VNode{ string data;//顶点信息 ArcNode* firstarc;//第一个表结点的地址,指向第一条依附该顶点的弧的指针 }VNode, AdjList[10]; typedef struct{ AdjList vertices; int vexnum, arcnum;//图的顶点数和弧数 }ALGraph; int LocateVex(ALGraph G, string u)//返回顶点u在图的位置 { for(int i=0; i<G.vexnum; i++) if(G.vertices[i].data==u) return i; return -1; } void CreateUDG(ALGraph &G)//构造无向图 { string v1, v2; int i, j, k; cout<>G.vexnum>>G.arcnum; cout<<"请输入顶点:"; for(i=0; i>G.vertices[i].data; G.vertices[i].firstarc=NULL; } cout<<"请输入边:"; cout<<endl; for(k=0; k>v1>>v2; i=LocateVex(G, v1); j=LocateVex(G, v2); //插入v1的邻接表,为了提高效率,总在表头插入结点。 ArcNode *arc=new ArcNode; arc->adjvex=j; arc->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=arc; //插入v2的邻接表,为了提高效率,总在表头插入结点。 arc=new ArcNode; arc->adjvex=i; arc->nextarc=G.vertices[j].firstarc; G.vertices[j].firstarc=arc; } } void Print(ALGraph G)//打印邻接表 { cout<<"打印邻接表如下:"; cout<<endl; for(int i=0; i<G.vexnum; i++)//遍历每个顶点的邻接表 { cout<<G.vertices[i].data; ArcNode *p=G.vertices[i].firstarc; while(p) { cout<"<adjvex].data; p=p->nextarc; } cout<adjvex; else return -1; } int NextAdjVex(ALGraph G, int v, int w)//返回顶点v的相对于w的下一个邻接点序号 { ArcNode* p=G.vertices[v].firstarc; while(p) { if(p->adjvex==w) break; p=p->nextarc; } if(p->adjvex!=w || !p->nextarc)//如果没找到w或者w是最后一个邻接点 return -1; return p->nextarc->adjvex; } bool visited[10]; void DFS(ALGraph G, int v) { visited[v]=true; cout<<G.vertices[v].data<=0; w=NextAdjVex(G, v, w) ) if(!visited[w]) DFS(G, w); } void DFSTraverse(ALGraph G)//深搜 { for(int i=0; i<G.vexnum; i++) visited[i]=false; for(i=0; i<G.vexnum; i++) if(!visited[i]) DFS(G, i); } void BFSTraverse(ALGraph G)//广搜 { queue q; for(int i=0; i<G.vexnum; i++) visited[i]=false; for(i=0; i<G.vexnum; i++) { if(!visited[i]) { q.push(i); visited[i]=true; while(!q.empty()) { int v=q.front(); q.pop(); cout<<G.vertices[v].data<=0; w=NextAdjVex(G, v, w)) { if (!visited[w]) { q.push(w); visited[w]=true; } } } } } } void main() { ALGraph G; CreateUDG(G); Print(G); cout<<"深搜:"; DFSTraverse(G); cout<<endl; cout<<"广搜:"; BFSTraverse(G); cout<<endl; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值