基于二值化图像转GCode的螺旋扫描实现

  • 基于二值化图像转GCode的螺旋扫描实现
    • 什么是双向扫描
    • 螺旋扫描代码示例

基于二值化图像转GCode的螺旋扫描实现

什么是螺旋扫描

螺旋扫描

螺旋扫描(Spiral Scanning)是激光雕刻中一种特殊的扫描方式,其特点是激光头按照螺旋形状逐渐向外移动,覆盖整个图像表面。与传统的水平、垂直或对角线扫描方式不同,螺旋扫描以一种旋转螺旋的方式进行移动,创造出一种独特的雕刻效果。

螺旋扫描的基本过程如下:

  1. 起始位置: 激光头移动到图像的起始位置。

  2. 螺旋移动: 激光头按照螺旋形状逐渐向外移动,同时进行雕刻。通常,激光头以螺旋的方式覆盖整个图像表面,从中心向外辐射。

  3. 循环重复: 重复螺旋移动的过程,直到整个图像都被刻蚀完成。

螺旋扫描的优点之一是可以在图像表面创建一种渐变的雕刻效果。由于激光头的移动轨迹呈螺旋形状,不同区域的刻蚀深度和密度可能有所不同,从而形成独特的视觉效果。这种扫描方式通常用于一些艺术品、装饰品或个性化雕刻项目,以增加雕刻作品的艺术感和独特性。

在选择扫描方式时,螺旋扫描可能不适用于所有应用,但在某些情况下,它为雕刻师提供了一种创造性的选项,以实现独特和有趣的雕刻效果。

螺旋扫描代码示例

#include <optional>
#include <string>
#include <print>
#include <format>
#include <vector>
#include <fstream>
#include <ranges>struct G0 {std::optional<float> x, y;std::optional<int> s;std::string toString() {std::string command = "G0";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}explicit operator std::string() const {std::string command = "G0";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}
};struct G1 {std::optional<float> x, y;std::optional<int> s;std::string toString() {std::string command = "G1";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}explicit operator std::string() const {std::string command = "G1";if(x.has_value()) {command += std::format(" X{:.3f}", x.value());}if(y.has_value()) {command += std::format(" Y{:.3f}", y.value());}if(s.has_value()) {command += std::format(" S{:d}", s.value());}return command;}
};inline bool ExportGCode(const std::string &fileName, std::vector<std::string> &&gcode) {std::fstream file;file.open(fileName, std::ios_base::out | std::ios_base::trunc);if(!file.is_open()) {return false;}for(auto &&v: gcode | std::views::transform([](auto item) { return item += "\n"; })) {file.write(v.c_str(), v.length());}return true;
}int main() {constexpr int imageWidth  = 10;constexpr int imageHeight = 10;// clang-format off// 假设图像数据,0表示非激光刻蚀部分,1表示进行激光刻蚀的区域constexpr int image[imageWidth][imageHeight] = {{0, 1, 1, 1, 0, 1, 1, 1, 0, 0}, // G0 G1 G1 G1 G0 G1 G1 G1 G0 G0{1, 0, 1, 0, 1, 0, 1, 0, 1, 0},{1, 1, 1, 0, 0, 1, 1, 1, 1, 1},{0, 0, 1, 1, 1, 1, 1, 0, 0, 0},{1, 1, 0, 0, 1, 0, 0, 1, 1, 1},{0, 1, 1, 0, 0, 1, 0, 0, 0, 0},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},{1, 0, 0, 0, 1, 0, 1, 0, 0, 0},{0, 1, 0, 1, 0, 1, 0, 1, 0, 1},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};// clang-format onstd::vector<std::string> command;auto internal = [&](int x,int y){if(auto const value = image[y][x];value) {command.emplace_back(G1 {x, y, 1000});  // 最大激光功率 S=1000} else {command.emplace_back(G0 {x, y, 0});}};int top = 0, bottom = imageHeight - 1, left = 0, right = imageWidth - 1;while(top <= bottom && left <= right) {for(int i = left; i <= right; ++i) {internal(top, i);}++top;for(int i = top; i <= bottom; ++i) {internal(i, right);}--right;if(top <= bottom) {for(int i = right; i >= left; --i) {internal(bottom, i);}--bottom;}if(left <= right) {for(int i = bottom; i >= top; --i) {internal(i, left);}++left;}}// 导出GCodeExportGCode("gcode.nc",std::move(command));std::println("Export data to gcode.nc");return 0;
}

螺旋扫描仿真

上述示例展示了一个10x10的二维图像数据,其中0表示非激光刻蚀部分,1表示进行激光刻蚀的区域。通过遍历图像数据,代码生成了相应的G代码指令序列,用于描述激光头在工件表面的运动路径。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/444740.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

再讲 Session 和 Token,彻底弄明白

前言 在构建用户身份管理系统时&#xff0c;选择会话&#xff08;Session&#xff09;还是令牌&#xff08;Token&#xff09;是一个关键决策&#xff0c;取决于系统的需求和特定的使用场景。本文将深入探讨何时适合使用会话&#xff0c;何时适合使用令牌&#xff0c;以帮助开发…

国图公考:考公和考编一样吗?

公务员&#xff1a;是指在各级机关中&#xff0c;符合规定&#xff0c;行使职权&#xff0c;执行公务的人员 事业单位&#xff1a;事业单位是指由国家或社会组织举办&#xff0c;从事教育、科学、文化、卫生、体育等社会公益事业的单位。 公务员和事业编都是有编制的&#xf…

制造业工厂实施MES系统带来的价值是什么?

MES系统的应用能给制造业带来哪些价值&#xff1f;制造企业想要获得更大的利润&#xff0c;就要从生产开始着手。生产制造是工厂的核心,是公司最大的成本来源。企业只有通过信息化的管理模式&#xff0c;从而达到节约成本&#xff0c;提高质量&#xff0c;才能为客户提供更满意…

8.DNS域名解析服务器

目录 1. 概述 1.1. 产生原因 1.2. 作用&#xff1a; 1.3. 连接方式 1.4. 因特网的域名结构 1.4.1. 拓扑&#xff1a; 1.4.2. 分类 1.4.3. 域名服务器类型划分 2. DNS域名解析过程 2.1. 分类&#xff1a; 2.2. 解析图&#xff1a; 2.2.1. 图&#xff1a; 2.2.2. 过…

hot100:26环形链表II

题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 算法思想&#xff1a; 在环形链表hot100&#xff1a;25环形链表-CSDN博客这篇博客中&#xff0c;我们解决了如何判断一个链表有环&#xff0c;即快慢指针相遇的地方就证明链表…

【机器学习】监督学习算法之:线性回归

线性回归 1、引言2、线性回归2.1 定义2.2 基本原理2.3 公式2.4 实现2.5 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;最近机器学习的文章写的不少啊。 小鱼&#xff1a;你还挺细心的哦。 小屌丝&#xff1a;那必须的&#xff0c;我要学习&#xff0c;我要成长…

通过与chatGPT交流实现零样本事件抽取

1、写作动机&#xff1a; 近来的大规模语言模型&#xff08;例如Chat GPT&#xff09;在零样本设置下取得了很好的表现&#xff0c;这启发作者探索基于提示的方法来解决零样本IE任务。 2、主要贡献&#xff1a; 提出了基于chatgpt的多阶段的信息抽取方法&#xff1a;在第一阶…

吉大计网笔记

Osi七层模型 物理层&#xff1a;比特流的透明传输 数据链路层&#xff1a;ip数据包装成帧并传输&#xff0c;处理相邻节点的数据传输。 网络层&#xff1a;选择路由和交换节点&#xff0c;处理任意节点的数据传输。 运输层&#xff1a;主机进程的数据传输服务&#xff0c;端到端…

6个在线网页原型工具的推荐选择

即时设计 即时设计可以说为中国设计师提供了很大的帮助。作为最受欢迎的在线网页原型图设计协作工具之一&#xff0c;在线协作是其核心特征。在线协作工作允许整个团队同时编辑文件&#xff0c;并可以随时随地访问。 团队共享组件库&#xff0c;使成员可以自由上传、下载和使用…

Flink 读取 Kafka 消息写入 Hudi 表无报错但没有写入任何记录的解决方法

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,京东购书链接:https://item.jd.com/12677623.html,扫描左侧二维…

字节:从尾部K个节点反转链表

题目 一个链表0,1,2,3,4,5,6,7&#xff0c;从链表尾部 K个节点翻转&#xff0c;求翻转后的链表。 比如&#xff1a;[0,1,2,3,4,5,6,7] k3 翻转后 [0,1,4,3,2,7,6,5]。 空间复杂度O(1)。 解法 /*** 链表 14,13,12,11,10,9,8,7,6,5,4,3,2,1* 从尾部节点1开始倒着K个一组翻转* …

Kotlin 协程:深入理解 ‘async { }‘

Kotlin 协程&#xff1a;深入理解 ‘async { }’ Kotlin 协程是一种强大的异步编程工具&#xff0c;它提供了一种简洁、易读的方式来处理并发和异步操作。在 Kotlin 协程库中&#xff0c;async {} 是一个关键的函数&#xff0c;它允许我们启动一个新的协程&#xff0c;并返回一…