DXF图纸的C++解析

该代码段展示了如何使用C++和OpenCV库解析DXF文件中的线型,并在图像上绘制直线、圆、圆弧和多线实体。通过块容器迭代器遍历数据结构,转换坐标并调用OpenCV函数进行绘制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dxf的线型有很多种,至于解析方式,废话不多说直接上代码!

void drawdxfimg(Mat* img, Test_CreationClass* creationClass, CvPoint2D32f coordinatemove_img) {
    vector<BlockObj> ::iterator blockItor;//块容器迭代器
    blockItor = creationClass->m_myblock.begin();
    int cols = img->cols, rows = img->rows;

    int thick = 1;
    while (blockItor != creationClass->m_myblock.end()) {
        if (blockItor->drawflag == false) {
            blockItor++;
            continue;
        }
        //绘制直线
        vector<DXFLine> ::iterator lineItor;//块容器迭代器
        lineItor = blockItor->line.begin();
        while (lineItor != blockItor->line.end()) {
            //cout << "***draw line" << endl;
            CvPoint2D32f bpoint = setWorldCoordinate((*img).rows, blockItor, lineItor->beginpoint, coordinatemove_img);
            CvPoint2D32f epoint = setWorldCoordinate((*img).rows, blockItor, lineItor->endpoint, coordinatemove_img);
            line(*img, bpoint, epoint, Scalar(255, 255, 255), thick);
            lineItor++;
        }
        //绘制圆
        vector<DXFCircle> ::iterator circleItor;//块容器迭代器
        circleItor = blockItor->circle.begin();
        while (circleItor != blockItor->circle.end()) {
            //cout << "***draw circle" << endl;
            CvPoint2D32f cpoint = setWorldCoordinate((*img).rows, blockItor, circleItor->centerpoint, coordinatemove_img);
            float radius = circleItor->radius * blockItor->sx * zoom_img;
            circle(*img, cpoint, (int)radius, Scalar(255, 255, 255), thick);
            circleItor++;
        }
        //绘制圆弧
        vector<DXFArc> ::iterator arcItor;//块容器迭代器
        arcItor = blockItor->arc.begin();
        while (arcItor != blockItor->arc.end()) {
            //cout << "***draw arc" << endl;
            CvPoint2D32f cpoint = setWorldCoordinate((*img).rows, blockItor, arcItor->centerpoint, coordinatemove_img);
            float radius = arcItor->radius * blockItor->sx * zoom_img;
            //生成点位坐标


            if (arcItor->bangle < arcItor->eangle) {//逆时针圆弧

                //ellipse(*img, cpoint, cvSize((int)radius, (int)radius), 0, arcItor->bangle, arcItor->eangle, cvScalar(255, 255, 255), thick);

                ellipse(*img, cpoint, cvSize((int)radius, (int)radius), 0, (360 - arcItor->eangle), (360 - arcItor->bangle), cvScalar(255, 255, 255), thick);


            }
            else {//顺时针画圆弧

                double bangle, eangle;
                bangle = 360 - arcItor->bangle;
                eangle = -arcItor->eangle;
                /*cv::Point StartPoint = Point(cpoint.x + radius * cos(arcItor->bangle), cpoint.y + radius * sin(arcItor->bangle));
                cv::Point EndPoint = Point(cpoint.x + radius * cos(arcItor->eangle), cpoint.y + radius * sin(arcItor->eangle));
                DrawArc(img, cpoint, StartPoint, EndPoint, 1);*/

                ellipse(*img, cpoint, cvSize((int)radius, (int)radius), 0, bangle, eangle, cvScalar(255, 255, 255), thick);
            }
            arcItor++;
        }
        //绘制多线实体
        vector<DXFPolyLineEntities> ::iterator polylineentitiesItor;//多线实体容器迭代器
        polylineentitiesItor = blockItor->polylineentities.begin();
        while (polylineentitiesItor != blockItor->polylineentities.end()) {
            CvPoint2D32f beforpoint;
            for (size_t i = 0; i < polylineentitiesItor->vertex.size(); i++) {
                int nextvertex = i + 1;
                if (nextvertex == polylineentitiesItor->vertex.size()) //如果是最后一个点的情况
                {

                    if (polylineentitiesItor->isclose == true)//闭合则画终点到起点的线
                        nextvertex = 0;
                    else
                        break;

                }
                //cout << " bulge : " << polylineentitiesItor->vertex[i].z <<  " " << polylineentitiesItor->vertex[nextvertex].z << endl;
                // beforpoint = setWorldCoordinate((*img).rows, blockItor, polylineentitiesItor->vertex[nextvertex], coordinatemove_img);
                CvPoint2D32f bpoint = setWorldCoordinate((*img).rows, blockItor, polylineentitiesItor->vertex[i], coordinatemove_img);
                CvPoint2D32f epoint = setWorldCoordinate((*img).rows, blockItor, polylineentitiesItor->vertex[nextvertex], coordinatemove_img);


                beforpoint = epoint;
                //cout << bpoint.x << " " << bpoint.y << " " << epoint.x << " " << epoint.y << endl;
                if (polylineentitiesItor->vertex[i].z == 0)
                {
                    line(*img, bpoint, epoint, Scalar(255, 255, 255), thick);
                }
                else {
                    double bulge = polylineentitiesItor->vertex[i].z, start_angle = 0, end_angle = 0, radius = 0;
                    CvPoint2D32f center(0, 0);
                    createFrom2PBulge(bpoint, epoint, -bulge, center, start_angle, end_angle, radius);
                    //cout << "---- r: " << radius << " " << start_angle << " " << end_angle << endl;
                    double sx = center.x + radius * cos(start_angle / 180.0 * M_PI), sy = center.y + radius * sin(start_angle / 180.0 * M_PI);
                    double ex = center.x + radius * cos(end_angle / 180.0 * M_PI), ey = center.y + radius * sin(end_angle / 180.0 * M_PI);
                    //cout << "after: " <<sx << " " << sy << " " << ex << " " << ey << endl;
                    //ellipse(*img, center, cvSize(radius, radius), 0, start_angle, end_angle, cvScalar(255, 255, 255), thick);
                    double sa = min(start_angle, end_angle), ea = max(start_angle, end_angle);
                    double arc_len = (ea - sa) / 180 * M_PI * radius;
                    int len = ceil(arc_len);
                    double step = (ea - sa) / double(len);
                    // fix ellipse round 
                    for (double angle = sa; angle < ea; angle += step)
                    {
                        int x = int(center.x + radius * cos(angle / 180 * M_PI));
                        int y = int(center.y + radius * sin(angle / 180 * M_PI));
                        img->at<uchar>(y, x) = 255;
                    }
                }

            }
            polylineentitiesItor++;
        }
        blockItor++;
    }
}
 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值