C# 学习中,想尝试着做一个工控方面的上位机,可以读取CAD绘制的图形,然后把它显示出来,后面让运动控制器去走CAD里面的轨迹。

一、用netDXF 开源包,对DXF文件进行解析。解析后的直线、圆、圆弧、椭圆、多段线、曲线等图纸,分别用List存起来。

   /// <summary>
/// 打开DXF文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Open_Click(object sender, EventArgs e)
{ using (OpenFileDialog openFile = new OpenFileDialog())
{
openFile.Title = "加载DXF文件";
openFile.Filter = "dxf File(*.dxf)|*.dxf|ALL File(*.*)|*.*";
if (openFile.ShowDialog() == DialogResult.OK)
{
//获得文件路径
file = openFile.FileName;
//加载文件
dxf = DxfDocument.Load(file);
//解析文件
ImPort(file);
//生成绘制路径
BuildPath();
//绘制图形
this.MainPic.Image = PaintDXF(this.MainPic);
}
}
}
 /// <summary>
/// 解析DXF文件
/// </summary>
/// <param name="fileName">要解析的文件名</param>
public void ImPort(string fileName)
{
lineList.Clear();
arcList.Clear();
cirList.Clear();
polylineList.Clear();
polylines.Clear(); // 解析多段线
foreach (LwPolyline lwPolyline in dxf.LwPolylines)
{
bool isHaveArc = false;
lwPolylineVertices.Clear();
lwPolylineVertices.AddRange(lwPolyline.Vertexes);
foreach (LwPolylineVertex lwPolylineVertex in lwPolylineVertices)
{
if (lwPolylineVertex.Bulge != 0)
{
isHaveArc = true;
break;
}
}
if (isHaveArc)
{
entityObjList.Clear();
//将LwPolyline实体炸开
entityObjList.AddRange(lwPolyline.Explode());
//分解多段线集合
foreach (EntityObject entityObject in entityObjList)
{
//如果是直线,就填加到直线集合
Line line_Tmp = entityObject as Line;
if (line_Tmp != null)
{
lineList.Add(line_Tmp);
}
//如果是圆弧,就填加到圆弧集合
Arc arc_Tmp = entityObject as Arc;
if (arc_Tmp != null)
{
arcList.Add(arc_Tmp);
}
}
}
else //多段线中没有圆弧,就把这个多段线添加到多段线List中
{
polylineList.Add(lwPolyline);
}
}
//解析直线
foreach (Line ln in dxf.Lines)
{
lineList.Add(ln);
}
//解析圆弧
foreach (Arc arc in dxf.Arcs)
{
arcList.Add(arc);
}
//解析圆
foreach (Circle cir in dxf.Circles)
{
cirList.Add(cir);
}
//解析椭圆
foreach (Ellipse elp in dxf.Ellipses)
{
//把椭圆转换成多段线
int precision = GetEllipseToPolylinesPercision(elp, 0.5);
polylineList.Add(elp.ToPolyline(precision));
}
//解析样条曲线
foreach (Spline spline in dxf.Splines)
{
//将样条曲线转换成多段线 (用绘制多段线的方式绘制)
int precision = GetSplineToPolylinesPrecision(spline, 0.5);
polylines.Add(spline.ToPolyline(precision));
}
//视窗中心坐标
viewcCenterX = dxf.Viewport.ViewCenter.X;
viewcCenterY = dxf.Viewport.ViewCenter.Y;
//视窗高度
viewcCenterH = dxf.Viewport.ViewHeight;
//根据视窗高度和显示框高度调整图形显示比例
m_fratio = (float)(MainPic.Size.Height / viewcCenterH); //显示数据
this.uiDataGridView1.DataSource = lineList;
this.dataGridView2.DataSource = arcList;
this.dataGridView3.DataSource = cirList;
this.dataGridView4.DataSource = polylines;
}

二、 把所有需要绘制图形(直线、圆弧、圆、椭圆、多段线、曲线、等)都添加到GraphicsPath 对象里面去

/// <summary>
/// 生成绘制路径
/// </summary>
private void BuildPath()
{
//清空之前存在的路径轨迹
graphicsPath.Reset();
// 直线 添加到绘制路径中
foreach (Line line in lineList)
{
PointF tf = Vector2PointF(line.StartPoint);
PointF tf2 = Vector2PointF(line.EndPoint);
//将线段添加到绘制路径对象
graphicsPath_tmp.AddLine(tf, tf2);
graphicsPath.AddPath(graphicsPath_tmp, false);
graphicsPath_tmp.Reset();
}
// 圆弧 添加到绘制路径中
foreach (Arc arc in arcList)
{
RectangleF ef3 = new RectangleF();
//半径
float r = Convert.ToSingle(arc.Radius);//* m_fratio;
//圆心坐标转换
PointF pf = Vector2PointF(arc.Center);
ef3.X = pf.X - r;
ef3.Y = pf.Y - r;
ef3.Width = 2f * r;
ef3.Height = 2f * r;
//起始角度
starAg = Convert.ToSingle(arc.StartAngle);
//扫描角度
sweepAg = Convert.ToSingle((360 - arc.StartAngle + arc.EndAngle) % 360);
graphicsPath_tmp.AddArc(ef3, starAg, sweepAg);
graphicsPath.AddPath(graphicsPath_tmp, false);
graphicsPath_tmp.Reset();
}
// 圆 添加到绘制路径中
foreach (Circle circle in cirList)
{
RectangleF rect = new RectangleF();
float r = Convert.ToSingle(circle.Radius);
//显示坐标转换
PointF pf = Vector2PointF(circle.Center); rect.X = pf.X - r;
rect.Y = pf.Y - r;
rect.Width = 2f * r;
rect.Height = 2f * r;
graphicsPath_tmp.AddEllipse(rect);
graphicsPath.AddPath(graphicsPath_tmp, false);
graphicsPath_tmp.Reset();
}
// 样条曲线转成的多段线添加到绘制路径中
foreach (Polyline polyline in polylines)
{
pointFs.Clear();
foreach (PolylineVertex vertex in polyline.Vertexes)
{
PointF pf = Vector2PointF(vertex.Position);
pointFs.Add(pf);
}
PointF[] potFs = pointFs.ToArray();
graphicsPath_tmp.AddLines(potFs);
if (polyline.IsClosed)
{
graphicsPath_tmp.CloseFigure();
}
graphicsPath.AddPath(graphicsPath_tmp, false);
graphicsPath_tmp.Reset();
}
// 轻量多段线 添加到绘制路径中
foreach (LwPolyline lwPolyline in polylineList)
{
pointFs.Clear();
foreach (LwPolylineVertex vertex in lwPolyline.Vertexes)
{
PointF pf = Vector2PointF(vertex.Position);
pointFs.Add(pf);
}
PointF[] potFs = pointFs.ToArray();
graphicsPath_tmp.AddLines(potFs);
if (lwPolyline.IsClosed)
{
graphicsPath_tmp.CloseFigure();
}
graphicsPath.AddPath(graphicsPath_tmp, false);
graphicsPath_tmp.Reset();
}
//定义一个矩阵,把纵坐标翻转
Matrix matrix = new Matrix(1, 0, 0, -1, 0, 0);
//定义矩阵的缩放向量
matrix.Scale(m_fratio, m_fratio);
//定义矩阵偏移向量 dxf文件的视窗中心放到显示的中心
matrix.Translate((float)viewcCenterX * -1, (float)viewcCenterY * -1);
//对路径进行矩阵转换
graphicsPath.Transform(matrix);
}

三、绘制路径(显示图形)

 //新一个Matrix矩阵对象
Matrix translateMatrix = new Matrix(); /// <summary>
/// 图形绘制
/// </summary>
/// <param name="picture">绘制图形的控件</param>
/// <returns>返回图形绘制完成的图片</returns>
public Bitmap PaintDXF(PictureBox myPicBox)
{ //定义一个GDI+对象
using (Graphics graphics = Graphics.FromImage(image))
{
////设GDI对象的单位
//graphics.PageUnit = GraphicsUnit.Pixel;
// 设置为可剪辑区域
graphics.SetClip(displayRectangle);
//定义一个刷子 设置为黑色
SolidBrush brush = new SolidBrush(Color.Black);
//用上面定义的刷子填充整个图形
graphics.FillRectangle(brush, displayRectangle);
//定义绘制直线和曲线的笔 并设置为它的颜色和宽度(宽度为浮点数)
Pen pen1 = new Pen(Color.Blue, 2f);
Pen pen2 = new Pen(Color.FromArgb(50, 50, 50), 1f);
//画横格
for (int i = 1, rh = displayRectangle.Height; i < rh; i += 40)
{
graphics.DrawLine(pen2, 0, i, displayRectangle.Width, i);
}
//画竖格
for (int i = 1, rw = displayRectangle.Width; i < rw; i += 40)
{
graphics.DrawLine(pen2, i, 0, i, displayRectangle.Height);
}
//设置图形显示区中心为坐标原点
graphics.TranslateTransform(displayRectangle.Width / 2, displayRectangle.Height / 2);
//对绘制路径用定义的矩阵进行矩阵变换
graphicsPath.Transform(translateMatrix);
//绘制图象
graphics.DrawPath(pen1, graphicsPath);
} return image;
}

四、图形平移

   /// <summary>
/// 鼠标按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainPic_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
isLeftButton = true;
xStrat = e.X;
yStart = e.Y; }
   /// <summary>
/// 鼠标拖动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainPic_MouseMove(object sender, MouseEventArgs e)
{
if (isLeftButton == true)
{
xEnd = e.X;
yEnd = e.Y;
m13 = xEnd - xStrat;
m23 = yEnd - yStart;
//重置矩阵
translateMatrix.Reset();
// 定义矩阵平移向量。
translateMatrix.Translate(m13, m23);
MainPic.Image = PaintDXF(this.MainPic);
m13 = m23 = 0;
xStrat = xEnd;
yStart = yEnd;
}
}

五、图形缩放

/// <summary>
/// 滚轮滚动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainPic_MouseWheel(object sender, MouseEventArgs e)
{
float fratio = 1f;
if (e.Delta < 0)
{
m_fratio *= 1f-0.05f;
fratio -= 0.05f;
}
else
{
m_fratio *= 1f+0.05f;
fratio += 0.05f;
}
if (m_fratio >= 10f)
{
m_fratio = 10f;
fratio = 1f;
}
if (m_fratio <= 0.1f)
{
m_fratio = 0.1f;
fratio = 1f;
}
//重置矩阵
translateMatrix.Reset();
//定义矩阵缩放向量
translateMatrix.Scale(fratio, fratio);
MainPic.Image = PaintDXF(this.MainPic);
}

最新文章

  1. 传播正能量&mdash;&mdash;做一个快乐的程序员
  2. Python or JavaScript 实现多级评论
  3. JAVA继承与覆写
  4. FineUI v3.3.2发布!目前最稳定版本,五年陈酿!
  5. putty ssh login linux
  6. 一些SVN 地址
  7. 【HDOJ】1224 Free DIY Tour
  8. StarTeam SDK 13 下载安装
  9. hdu What Are You Talking About(map)
  10. Flipping Parentheses~Gym 100803G
  11. leetCode刷题(找出数组里的两项相加等于定值)
  12. 傅里叶变换及其应用讲义(stanford_ee261)
  13. scrapy框架整理
  14. 小米手机安装mitmproxy证书
  15. mui---开发直播APP
  16. python摸爬滚打之day05----字典
  17. Math对象属性
  18. Python列表生成器
  19. [CMAKE] 详解CMakeLists.txt文件
  20. 第10章:MongoDB-CRUD操作--文档--修改--修改器

热门文章

  1. 上传媒体文件--添加显示进度条 layui的upload控件
  2. unity animation instance
  3. stream 链式结构 求和
  4. VisualSvn-Server搭建
  5. 【ZYNQ学习】各个主题的值得看的博客
  6. Unity Random
  7. java面经学习002
  8. linux下安装JDK 1.8 (Open JDK)
  9. 记录aop失效问题
  10. HCIA-ICT实战基础12-网络设备安全特性