C# WPF界面源码框架:运动控制路径算法总结与分享
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; // 假设1mm40像素 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 Listushort(); var offsets new Listdouble(); 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(IEnumerablePathSegment 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改个外观分分钟的事。下次可以聊聊怎么用这个框架实现自动避障算法那又是另一个深坑了。