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);
}

[C# 学习笔记]运用 GDI+ 的 Matrix 进行显示图形的平移和缩放的更多相关文章

  1. 【Qt官方例程学习笔记】Analog Clock Window Example (画笔的平移/旋转/缩放应用)

    这个例子演示了如何使用QPainter的转换和缩放特性来简化绘图. 值得学习的: 定时器事件ID检查: 在定时器事件中检查定时器id是比较好的实践. QPainter抗锯齿: We call QPai ...

  2. deepin linux学习笔记(四)进不去图形界面怎么办?

    目录 deepin linux学习笔记(四)进不去图形界面怎么办? 前言 更换成lxde桌面 进不去图形界面怎么办? 总结 deepin linux学习笔记(四)进不去图形界面怎么办? 前言 生命不息 ...

  3. Android学习笔记进阶八之Matrix矩阵

    Matrix,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 在Android里面,Matrix由9个float值构成,是一个3*3的矩阵.最好记住.如下图: ...

  4. Dynamic CRM 2015学习笔记(2)更改系统显示语言

    默认装的是英文的系统,想换成中文的.下面列出操作步骤: 1. 下载并安装语言包 http://www.microsoft.com/en-US/download/details.aspx?id=4501 ...

  5. canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)

    [下篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  6. [原创]java WEB学习笔记30:Cookie Demo 之显示最近浏览的记录

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  7. JavaWeb和WebGIS学习笔记(五)——使用OpenLayers显示地图

    系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...

  8. CSS3学习笔记--transform中的Matrix(矩阵)

    transform: matrix(a,b,c,d,e,f) ,如下图矩阵所示,任意点(x,y,1)经过matrix变化为(ax+cy+e,bx+dy+f,1),由此可以知道,matrix参数与tra ...

  9. Android学习笔记进阶九之Matrix对称变换

    网上很多的倒影特效实际上就是一个对称变换,在改变透明度即可. Matrix对称变换包括很多种,有关于Y轴对称,关于X轴对称,关于y= -x对称等等. 1 关于Y轴对称 // 获取资源文件的引用res ...

  10. Android学习笔记进阶十之Matrix错切变换

    刚开始我也不懂啥叫错切变换,一看效果图你就恍然大悟. 对图像的错切变换做个总结: x = x0 + b*y0; y = d*x0 + y0; 与之对应的方法是: Matrix matrix = new ...

随机推荐

  1. 帮你躲坑:pip install tensorflow 报错怎么办,import tensorflow 报错怎么办?

    补一补:什么是TensorFlow? 一句话介绍: Google 开源的基于数据流图的科学计算库,适合用于机器学习.深度学习等人工智能领域 百度百科的介绍: TensorFlow是谷歌基于DistBe ...

  2. vue 打开页面触发事件

    vue中created(),mounted()与activated()区别及应用 created():在创建vue对象时,当html渲染之前就触发:但是注意,全局vue.js不强制刷新或者重启时只创建 ...

  3. 使用Echarts 动态更新散点图

    最近遇到一个作业,要求使用 Echarts 散点图,本来这个图是很容易的,官网上也有很多的教程.但是如果可以动态的更新 Echarts 散点图就更好了.我本身对 js 不感兴趣,经过不停的查找资料最终 ...

  4. BurpSuite暴力破解和防御实战

    burpsuite暴力破解 工具准备 burp suite 用于攻击web 应用程序的集成平台 jsEncrypter 一个用于前端加密Fuzz的Burp Suite插件,支持base64.sha.m ...

  5. macOS 常用键盘快捷键大全

    对于初次接触 macOS 的朋友来说,除了要寻找不同的 APP 软件之外,还有一件事情也直接影响着使用电脑的效率,那就是 - 键盘快捷键! 与 Windows 的差异 我们先来认识一下苹果 Mac 键 ...

  6. CentOS7 修改root密码

    能登录系统修改root密码 passwd root(可以是其他什么用户) 输入新密码(两次)   忘记root密码不能进入系统,修改root密码   1.开机进入grub界面按e进入单用户编辑模式 2 ...

  7. 第九章 MySQL 高可用(MHA)

    MySQL 高可用(MHA) 一 MHA高可用部署 需要使用的前提: 当普通主从复制不能满足我们的需求,  主节点宕机  影响业务的不间断运行.这里就需要用到MHA 高可用 1. MHA高可用的介绍 ...

  8. 记录 windows RabbitMq 安装教程

    安装地址:https://www.rabbitmq.com/ RabbitMq 官网下载如下两个exe文件,otp_win64_22.0.exe 文件是rabbitmq的运行环境,必须安装!!! 傻子 ...

  9. 放苹果 tzoj2679 //自然数拆分 tzoj5827;(dp)

    放苹果 tzoj2679  描述 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. 输入 第一行是测试数据的数目t ...

  10. MySQL Atlas 读写分离软件介绍

    MySQL Atlas介绍 目录 MySQL Atlas介绍 一.MySQL Atlas介绍 1.1.1 MySQL Atlas介绍 1.1.2 Atlas基本管理 一.MySQL Atlas介绍 1 ...