C#CAD 读取DXF坐标并输出为CSV文件

目录

项目要求:

项目环境:

项目实现:

DXF文件

读取DXF文件

解析文件内容

显示DXF文件

CSV文件

读取CSV文件

将csv文件保存为datatable

添加数据

导出CSV文件

注意事项:

成果展示


项目要求:

        输入DXF文件、CSV文件,将DXF读取到的数据覆盖到CSV文件。内容包含直线、弧线、圆等图形坐标数据,并以三个数据为一组的形式输出。数据格式如下:设置数据“1”代表直线,“0”代表圆弧和圆。直线数据格式为:起始坐标X,起始坐标Y,图形类型;终点坐标X,终点坐标Y,图形类型。圆弧数据格式为:起始角度,终止角度,图形类型;中心点坐标X,Y,图形类型;半径,图形类型,图形类型。圆的数据格式表示为拆分成两段圆弧来表示。

项目环境:

        C#、WinForm

项目实现:

DXF文件

读取DXF文件

        打开文件夹,读取文件

private void bnreaddxf_Click(object sender, EventArgs e)
{
    OpenFileDialog openFile = new OpenFileDialog();
    openFile.Filter = "DXF Files (*.dxf)|*.dxf|All Files (*.*)|*.*";
    openFile.Title = "Load DXF File";
    if (DialogResult.OK == openFile.ShowDialog())
    {
        MessageBox.Show("成功打开dxf文件");
        //获取文件路径
        dxffilepath = openFile.FileName;
        //显示文件内容
        myDXF.ShowDXF(dxffilepath, pictureBox1);
        //解析文件内容
        outputdxf();
    }
}

解析文件内容

解析格式根据AutoCAD DXF参考格式

        1.直线Line

DataLineStruct item = default(DataLineStruct);
do
{
    GetLineCouple(sr, out text, out value);
    if (text == "10")
    {
        fX1Pos = (float)Convert.ToDouble(value);
    }

    if (text == "20")
    {
        fY1Pos = (float)Convert.ToDouble(value);
    }

    if (text == "30")
    {
        num2 = (float)Convert.ToDouble(value);
    }

    if (text == "11")
    {
        fX2Pos = (float)Convert.ToDouble(value);
    }

    if (text == "21")
    {
        fY2Pos = (float)Convert.ToDouble(value);
    }

    if (text == "31")
    {
        num = (float)Convert.ToDouble(value);
    }
}
while (text != "31");
item.fX1Pos = fX1Pos;
item.fY1Pos = fY1Pos;
item.fX2Pos = fX2Pos;
item.fY2Pos = fY2Pos;
listLineArray.Add(item);

        2.圆弧Arc

do
{
    GetLineCouple(sr, out text, out value);
    if (text == "10")
    {
        num11 = (float)Convert.ToDouble(value);
    }

    if (text == "20")
    {
        num10 = (float)Convert.ToDouble(value);
    }

    if (text == "40")
    {
        num5 = (float)Convert.ToDouble(value);
    }

    if (text == "50")
    {
        num4 = (float)Convert.ToDouble(value);
    }

    if (text == "51")
    {
        num3 = (float)Convert.ToDouble(value);
    }
}
while (text != "51");
num9 = num11 + (float)Math.Cos((double)num4 / 180.0 * Math.PI) * num5;
num8 = num10 + (float)Math.Sin((double)num4 / 180.0 * Math.PI) * num5;
num7 = num11 + (float)Math.Cos((double)num3 / 180.0 * Math.PI) * num5;
num6 = num10 + (float)Math.Sin((double)num3 / 180.0 * Math.PI) * num5;
num2 = num11 - num9;
num = num10 - num8;
DataArcStruct item = default(DataArcStruct);
item.fXPos = num9;
item.fYPos = num8;
item.fX1Pos = num7;
item.fY1Pos = num6;
item.fIPos = num2;
item.fJPos = num;
item.fRPos = num5;
item.fptXPos = num11;
item.fptYPos = num10;
item.fAngle1Pos = num4;
item.fAngle2Pos = num3;
listArcArray.Add(item);

        3. 圆Circle

do
{
    GetLineCouple(sr, out text, out value);
    if (text == "10")
    {
        fXPos = (float)Convert.ToDouble(value);
    }

    if (text == "20")
    {
        fYPos = (float)Convert.ToDouble(value);
    }

    if (text == "30")
    {
        num = (float)Convert.ToDouble(value);
    }

    if (text == "40")
    {
        fRPos = (float)Convert.ToDouble(value);
    }
}
while (text != "40");
DataCircleStruct item = default(DataCircleStruct);
item.fXPos = fXPos;
item.fYPos = fYPos;
item.fRPos = fRPos;
listCircleArray.Add(item);

         最终汇总,输出为所需要的格式。

private void outputdxf()
{
    int count = 0;//坐标数据
    data = new float[150]; //新配方数据(列)         

    for (int i = 0; i < myDXF.listLineArray.Count; i++)
    {
        data[count++] = myDXF.listLineArray[i].fX1Pos;//起始坐标
        data[count++] = myDXF.listLineArray[i].fY1Pos;
        data[count++] = (float)0;                    //类型

        data[count++] = myDXF.listLineArray[i].fX2Pos;//终点坐标
        data[count++] = myDXF.listLineArray[i].fY2Pos;
        data[count++] = (float)0;
    }

    for (int j = 0; j < myDXF.listArcArray.Count; j++)
    {
        PointF center = default(PointF);
        float starangle = myDXF.listArcArray[j].fAngle1Pos;
        float endangle = myDXF.listArcArray[j].fAngle2Pos;
        float radius = myDXF.listArcArray[j].fRPos;
        center.X = myDXF.listArcArray[j].fptXPos;
        center.Y = myDXF.listArcArray[j].fptYPos;

        data[count++] = starangle;//起始角度
        data[count++] = endangle;//终止角度
        data[count++] = (float)1;               //类型

        data[count++] = center.X;               //中心点X
        data[count++] = center.Y;               //中心点Y
        data[count++] = (float)1;               //类型

        data[count++] = radius;                 //半径
        data[count++] = (float)1;
        data[count++] = (float)1;               //类型
    }

    for (int z = 0; z < myDXF.listCircleArray.Count; z++)
    {
        PointF center = default(PointF);
        float starangle1 = 0;
        float endangle1 = 180;
        float starangle2 = 180;
        float endangle2 = 360;
        float radius = myDXF.listCircleArray[z].fRPos;
        center.X = myDXF.listCircleArray[z].fXPos;
        center.Y = myDXF.listCircleArray[z].fYPos;

        data[count++] = starangle1;
        data[count++] = endangle1;
        data[count++] = (float)1;

        data[count++] = center.X;               //中心点X
        data[count++] = center.Y;               //中心点Y
        data[count++] = (float)1;               //类型

        data[count++] = radius;                 //半径
        data[count++] = (float)1;
        data[count++] = (float)1;               //类型

        data[count++] = starangle2;
        data[count++] = endangle2;
        data[count++] = (float)1;

        data[count++] = center.X;               //中心点X
        data[count++] = center.Y;               //中心点Y
        data[count++] = (float)1;               //类型

        data[count++] = radius;                 //半径
        data[count++] = (float)1;
        data[count++] = (float)1;               //类型
    }
}

显示DXF文件

        1.将DXF显示在picturebox上

public Bitmap PaintDXF(PictureBox myPicBox)
{
    Rectangle displayRectangle = myPicBox.DisplayRectangle;
    Bitmap bitmap = new Bitmap(displayRectangle.Width, displayRectangle.Height);
    Graphics graphics = Graphics.FromImage(bitmap);
    SolidBrush solidBrush = new SolidBrush(Color.Black);
    graphics.FillRectangle(solidBrush, displayRectangle);
    Pen pen = new Pen(Color.Blue, 2f);
    Pen pen2 = new Pen(Color.Blue, 200f);
    Pen pen3 = new Pen(Color.FromArgb(50, 50, 50), 1f);
    RectangleF rect = default(RectangleF);
    PointF pt = default(PointF);
    PointF pt2 = default(PointF);
    PointF pointF = default(PointF);
    PointF pointF2 = default(PointF);
    PointF pointF3 = default(PointF);
    double num = 0.0;
    PointF CenterPoint = default(PointF);
    PointF pointF4 = default(PointF);
    PointF pointF5 = default(PointF);
    double sweepAngle = 0.0;
    double startAngle = 0.0;
    double num2 = 0.0;
    for (int i = 1; i * 40 < displayRectangle.Height; i++)
    {
        graphics.DrawLine(pen3, 0, 40 * i, displayRectangle.Width, 40 * i);
    }

    for (int i = 1; i * 40 < displayRectangle.Width; i++)
    {
        graphics.DrawLine(pen3, 40 * i, 0, 40 * i, displayRectangle.Height);
    }

    for (int j = 0; j < listLineArray.Count; j++)
    {
        pt.X = listLineArray[j].fX1Pos;
        pt.Y = listLineArray[j].fY1Pos;
        pt2.X = listLineArray[j].fX2Pos;
        pt2.Y = listLineArray[j].fY2Pos;
        pt.X *= m_fratio;
        pt.Y *= m_fratio;
        pt2.X *= m_fratio;
        pt2.Y *= m_fratio;
        pt.X = pt.X * m11 + pt.Y * m12 + m13;
        pt.Y = pt.X * m21 + pt.Y * m22 + m23;
        pt2.X = pt2.X * m11 + pt2.Y * m12 + m13;
        pt2.Y = pt2.X * m21 + pt2.Y * m22 + m23;
        graphics.DrawLine(pen, pt, pt2);
    }

    for (int j = 0; j < listCircleArray.Count; j++)
    {
        float num4 = listCircleArray[j].fRPos * m_fratio;
        pt.X = listCircleArray[j].fXPos;
        pt.Y = listCircleArray[j].fYPos;
        pt.X *= m_fratio;
        pt.Y *= m_fratio;
        pt.X = pt.X * m11 + pt.Y * m12 + m13;
        pt.Y = pt.X * m21 + pt.Y * m22 + m23;
        rect.X = pt.X - num4;
        rect.Y = pt.Y - num4;
        rect.Width = 2f * num4;
        rect.Height = 2f * num4;
        graphics.DrawEllipse(pen, rect);
    }

    for (int j = 0; j < listArcArray.Count; j++)
    {
        RectangleF rectangleF = default(RectangleF);
        pt.X = listArcArray[j].fXPos;
        pt.Y = listArcArray[j].fYPos;
        pt2.X = listArcArray[j].fX1Pos;
        pt2.Y = listArcArray[j].fY1Pos;
        pointF.X = listArcArray[j].fIPos;
        pointF.Y = listArcArray[j].fJPos;
        pointF3.X = listArcArray[j].fptXPos;
        pointF3.Y = listArcArray[j].fptYPos;
        pt.X *= m_fratio;
        pt.Y *= m_fratio;
        pt2.X *= m_fratio;
        pt2.Y *= m_fratio;
        pointF.X *= m_fratio;
        pointF.Y *= m_fratio;
        pt.X = pt.X * m11 + pt.Y * m12 + m13;
        pt.Y = pt.X * m21 + pt.Y * m22 + m23;
        pt2.X = pt2.X * m11 + pt2.Y * m12 + m13;
        pt2.Y = pt2.X * m21 + pt2.Y * m22 + m23;
        float num4 = (float)Math.Pow(pointF.X * pointF.X + pointF.Y * pointF.Y, 0.5);
        rectangleF = new RectangleF(pt.X + pointF.X - num4, pt.Y + pointF.Y - num4, 2f * num4, 2f * num4);
        pointF2.X = (float)(Math.Atan2(Convert.ToDouble(0f - pointF.Y), Convert.ToDouble(0f - pointF.X)) / 3.14 * 180.0);
        pointF2.Y = (float)(Math.Atan2(Convert.ToDouble(pt2.Y - pointF.Y - pt.Y), Convert.ToDouble(pt2.X - pointF.X - pt.X)) / 3.14 * 180.0);
        if (pointF2.X < 0f)
        {
            pointF2.X = 360f + pointF2.X;
        }

        if (pointF2.Y < 0f)
        {
            pointF2.Y = 360f + pointF2.Y;
        }

        float num5 = pointF2.Y - pointF2.X;
        if (num5 < 0f)
        {
            num5 += 360f;
        }

        graphics.DrawArc(pen, rectangleF, pointF2.X, num5);
    }

    graphics.TranslateTransform(0f, -displayRectangle.Height);
    graphics.Dispose();
    solidBrush.Dispose();
    pen.Dispose();
    pen3.Dispose();
    return bitmap;
}

        2.DXF图形的平移缩放

#region 鼠标控制平移缩放
private void picBox_MouseWheel(object sender, MouseEventArgs e)
{
    if (e.Delta < 0)
        myDXF.Ratio -= 0.1f;
    else
        myDXF.Ratio += 0.1f;

    if (myDXF.Ratio >= 10)
        myDXF.Ratio = 10;
    if (myDXF.Ratio <= 0.1)
        myDXF.Ratio = 0.1f;

    pictureBox1.Image = myDXF.PaintDXF(pictureBox1);
}

private void picBox_ShowDXF_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
        isLeftButton = true;
    xStart = e.X;
    yStart = e.Y;
}

private void picBox_ShowDXF_MouseUp(object sender, MouseEventArgs e)
{
    isLeftButton = false;
    oldM13 = myDXF.M13;
    oldM23 = myDXF.M23;
}

private void picBox_ShowDXF_MouseMove(object sender, MouseEventArgs e)
{
    if (isLeftButton == true)
    {
        xEnd = e.X;
        yEnd = e.Y;
        myDXF.M13 = oldM13 + xEnd - xStart;
        myDXF.M23 = oldM23 + yEnd - yStart;
        pictureBox1.Image = myDXF.PaintDXF(pictureBox1);
    }
}
#endregion

CSV文件

读取CSV文件

private void readcsv()
{
    try
    {
        DataTable datatable = new DataTable();
        int index = 0, index_ok = 0;             //替换csv文件列索引、标志位

        //打开csv文件
        OpenFileDialog openFile = new OpenFileDialog();
        openFile.Filter = ".xls|*.csv|All File(*.*)|*.*";
        openFile.Title = "Load CSV File";

        if (DialogResult.OK == openFile.ShowDialog())
        {
            csvfilepath = openFile.FileName;
            MessageBox.Show("成功打开csv文件");
        }

        //分析文件

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

将csv文件保存为datatable

        在读取CSV文件时就可以保存为datatable格式,以便后期添加数据。

        //读取csv文件
        StreamReader sr = new StreamReader(csvfilepath);
        int csvline = 0;
        datatable.Clear();

        //将csv文件数据添加到 datatable datatable中
        while (!sr.EndOfStream)
        {
            string line = sr.ReadLine();
            string[] values = line.Split(',');

            if (csvline == 0)     //首行为列名
            {
                for (int i = 0; i < values.Length; i++)
                {
                    DataColumn column = new DataColumn(values[i]);
                    datatable.Columns.Add(column);
                }
            }
            else
            {
                DataRow dr = datatable.NewRow();
                for (int i = 0; i < values.Length; i++)
                {
                    String stringdr = values[i];
                    dr[i] = stringdr;
                    if (csvline == 1 && index_ok == 0)
                    {
                        if (values[i] == "0" || values[i] == null)
                        {
                            index = i;
                            index_ok = 1;
                        }
                        else if (i == values.Length - 1)
                        {
                            datatable.Columns.Add("组" + (i - 1));
                            index = i + 1;
                            index_ok = 1;
                        }
                    }
                }
                datatable.Rows.Add(dr);
            }
            csvline++;
        }
        sr.Close();

添加数据

private DataTable addnewdata(int insert, DataTable dt)
{
    try
    {
        if (insert != 0)
        {
            for (int i = 0; i < data.Length; i++)
            {
                if (dt.Rows.Count < i + 1)
                {
                    dt.Rows.Add(dt.NewRow());
                    dt.Rows[i][0] = "成分" + i + 1;
                    dt.Rows[i][1] = "Modbus_1.变量" + i + 1;
                    dt.Rows[i][2] = "FLOAT";
                }
                dt.Rows[i][insert] = data[i];
            }
            MessageBox.Show("添加成功");
        }
    }
    catch
    {
        MessageBox.Show("添加失败");
    }
    return dt;
}

导出CSV文件

        将成功添加数据的datatable输出为新的CSV文件,覆盖路径下的原文件。

private void outputcsv(DataTable dt)
{
    try
    {
        // 创建一个StringBuilder来存储CSV内容
        StringBuilder csvContent = new StringBuilder();

        // 添加表头
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            csvContent.Append(dt.Columns[i].ColumnName.ToString().Trim());
            csvContent.Append(i == dt.Columns.Count - 1 ? "\r\n" : ",");
        }

        // 添加数据行
        foreach (DataRow row in dt.Rows)
        {
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                csvContent.Append(row[i].ToString().Trim());
                csvContent.Append(i == dt.Columns.Count - 1 ? "\r\n" : ",");
            }
        }

        // 将CSV内容写入文件
        File.WriteAllText(csvfilepath, csvContent.ToString(), Encoding.Default);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

注意事项:

        CSV文件列名不能重复。

        如果CSV文件打开出现乱码,解决方法:用记事本打开,重新保存为“带有BOM的UTF-8”。

成果展示

        图像缩放平移后

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值