C#+wpf界面源码框架,总结运动控制路径算法而写,控件源码+模板源码,分享给想入行的朋友们,引你快速入行,大神略过,可用于激光切割,雕刻机,分板机,点胶机,插件机等,本模板主要考虑到各运动控制硬件不同,视觉应用功能(应用视觉软件)也不同,所以只开发各路径编辑功能,除此功能外请自行添加 主要功能如1~9描述了: 1:鼠标画点,线,圆,圆弧,椭圆,折线,矩形,多边形,工作矩形 2:用运动轴坐标画点,线,圆,圆弧,椭圆,折线,矩形,多边形,工作矩形 3: 鼠标编辑画点,线,圆,圆弧,折线,矩形,多边形,工作矩形 4:实现一些坐标调整工具等 5: 运动轨迹跟踪 6: 支持中文,数字,字符转路径,字符转一维二维码路径 7: 支持打开CAD的dxf文件并解析显示路径 8: 支持生成G代码,txt文本,CSV表格,NC文件 9: 模板已有模拟运行,自行添加板卡驱动运行坐标即可,因考虑到各项目板卡不同,所以暂不集成板卡 重点:绘图控件(重在控件,模板在于用法,也可在此基础上用于项目,控件可以继续添加自已想要的功能
最近在搞运动控制项目的时候,发现很多新人卡在路径算法和界面框架搭建上。刚好手头有个自用的WPF绘图框架,拆了非核心部分给大家瞅瞅怎么玩路径编辑。这个框架重点在绘图控件设计,直接上硬菜。
绘图控件是整个框架的魂,继承自WPF的Canvas搞了个PathEditorControl。处理鼠标事件这块特别有意思,用了个策略模式切换不同绘图工具:
public class PathEditorControl : Canvas { private IDrawingTool _currentTool; // 切换绘图工具时更换策略对象 public void SwitchTool(ToolType type) { _currentTool = type switch { ToolType.Line => new LineTool(), ToolType.Arc => new ArcTool(), _ => new SelectionTool() }; } protected override void OnMouseDown(MouseButtonEventArgs e) { _currentTool?.HandleMouseDown(this, e.GetPosition(this)); } }每个工具实现自己的HandleMouseDown逻辑,比如画圆的时候得记录圆心和半径。这里用抽象类比接口更合适,因为有些工具需要共享基础绘图方法。
坐标转换是另一个坑点,设备坐标和界面像素要能互相转换。框架里搞了个带比例尺的双向转换器:
public class CoordinateConverter { private double _pixelsPerMillimeter = 40.0; // 假设1mm=40像素 public Point ToScreen(Point machinePoint) { return new Point(machinePoint.X * _pixelsPerMillimeter, machinePoint.Y * _pixelsPerMillimeter); } public Point ToMachine(Point screenPoint) { return new Point(screenPoint.X / _pixelsPerMillimeter, screenPoint.Y / _pixelsPerMillimeter); } }实际项目里得考虑坐标系的旋转和平移,这里用了个简化版。调试时经常遇到Y轴方向反了的情况,记得加个正负号翻转。
C#+wpf界面源码框架,总结运动控制路径算法而写,控件源码+模板源码,分享给想入行的朋友们,引你快速入行,大神略过,可用于激光切割,雕刻机,分板机,点胶机,插件机等,本模板主要考虑到各运动控制硬件不同,视觉应用功能(应用视觉软件)也不同,所以只开发各路径编辑功能,除此功能外请自行添加 主要功能如1~9描述了: 1:鼠标画点,线,圆,圆弧,椭圆,折线,矩形,多边形,工作矩形 2:用运动轴坐标画点,线,圆,圆弧,椭圆,折线,矩形,多边形,工作矩形 3: 鼠标编辑画点,线,圆,圆弧,折线,矩形,多边形,工作矩形 4:实现一些坐标调整工具等 5: 运动轨迹跟踪 6: 支持中文,数字,字符转路径,字符转一维二维码路径 7: 支持打开CAD的dxf文件并解析显示路径 8: 支持生成G代码,txt文本,CSV表格,NC文件 9: 模板已有模拟运行,自行添加板卡驱动运行坐标即可,因考虑到各项目板卡不同,所以暂不集成板卡 重点:绘图控件(重在控件,模板在于用法,也可在此基础上用于项目,控件可以继续添加自已想要的功能
字符转路径的功能比较骚,用GlyphTypeface获取字形轮廓数据。注意处理中文字体的矢量轮廓:
var glyphTypeface = new GlyphTypeface(new Uri("fonts/simhei.ttf")); var indices = new List<ushort>(); var offsets = new List<double>(); foreach (char c in text) { var glyphIndex = glyphTypeface.CharacterToGlyphMap[c]; indices.Add(glyphIndex); offsets.Add(0); // 字间距调整在这处理 } var geometry = glyphTypeface.GetGlyphOutline(indices, 100, 1, offsets);生成的PathGeometry可以直接扔给绘图控件显示。二维码生成用了ThoughtWorks.QRCode库,转成点阵后生成折线路径。
DXF解析这块建议用第三方库NetDxf,但要注意不同版本格式兼容性。遇到过R12版本圆弧数据解析异常的坑,后来发现是闭合角度计算问题:
using NetDxf; var dxf = DxfDocument.Load("file.dxf"); foreach (var entity in dxf.Entities.Lines) { // 将DXF线段转为框架内部的PathSegment }G代码生成模块最常被问,核心是遍历路径对象生成指令。举个直线插补的例子:
public string GenerateGCode(IEnumerable<PathSegment> paths) { var sb = new StringBuilder(); sb.AppendLine("G90"); // 绝对坐标 foreach (var path in paths) { if(path is LineSegment line) { sb.AppendLine($"G1 X{line.End.X:F3} Y{line.End.Y:F3} F500"); } } return sb.ToString(); }实际项目要处理进给速度、刀具补偿等参数,这里做了简化。导出时记得处理不同地区的小数点格式问题,德国人用逗号会出幺蛾子。
模拟运行模块用了WPF的动画系统,通过修改RenderTransform实现视觉跟踪:
var animate = new DoubleAnimation(endX, TimeSpan.FromSeconds(duration)); toolhead.BeginAnimation(Canvas.LeftProperty, animate);真要接硬件时把这部分替换成板卡SDK的坐标写入就行。框架里留了运行时策略接口,方便切换模拟/真实模式。
这个模板最大的优势是路径算法和界面控件解耦,我见过有人拿去改造成激光雕刻机控制程序,只花了三天就接上了板卡驱动。控件本身支持样式重写,用Blend改个外观分分钟的事。下次可以聊聊怎么用这个框架实现自动避障算法,那又是另一个深坑了。