C# Winform自制多轴力臂(简单易懂,方便扩展)

      WinForms框架广泛应用于上位机开发领域,其中对力臂的精准控制是常见需求之一。本文深入探讨了如何创建自定义的多轴力臂图形控件,不仅涵盖了力臂图形控件的角度调节机制,还详细展示了如何实现力臂运动的生动动态效果,为开发者提供了一套高效、直观的力臂控制解决方案。

通过本文,您将学习到:

  • 如何设计并实现一个功能全面的多轴力臂图形控件,该控件能够直观地反映力臂的当前状态。
  • 控件中角度控制的实现细节,包括如何通过编程手段调整力臂的角度,以及角度变化时的实时反馈。
  • 利用动画或图形渲染技术,为力臂的运动添加流畅的动态效果,提升用户体验。

示例代码:

        /// <summary>
        /// 重绘图形轨迹
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
             绘制背景
            //g.Clear(Color.White);

            // 定义机械手臂的起点和终点
            PointF basePoint1 = new PointF(baseX, baseY);
            PointF endPoint1 = new PointF(baseX, baseY);
            // 计算手臂的终点位置
            double radians1 = rotateAngle1 * (Math.PI / 180);
            endPoint1.X = (float)(basePoint1.X - EgeLength1 * Math.Cos(radians1));
            endPoint1.Y = (float)(basePoint1.Y + EgeLength1 * Math.Sin(radians1));
            // 绘制手臂1
            g.DrawLine(new Pen(Encoder1Color, 3), basePoint1, endPoint1);
            // 绘制编码器1
            g.FillEllipse(Brushes.LightBlue, baseX - EncoderSize / 2, baseY - EncoderSize / 2, EncoderSize, EncoderSize);


            PointF basePoint2 = endPoint1;
            PointF endPoint2 = new PointF(baseX - EgeLength1, EgeLength1);
            // 计算手臂的终点位置
            double radians2 = rotateAngle2 * (Math.PI / 180);
            endPoint2.X = (float)(basePoint1.X - (EgeLength1 * Math.Cos(radians1) + EgeLength2 * Math.Cos(radians1 + radians2)));
            endPoint2.Y = (float)(basePoint1.Y + (EgeLength1 * Math.Sin(radians1) + EgeLength2 * Math.Sin(radians1 + radians2)));
            // 绘制手臂2
            g.DrawLine(new Pen(Encoder2Color, 3), basePoint2, endPoint2);
            // 绘制编码器2
            g.FillEllipse(Brushes.LightBlue, endPoint1.X - EncoderSize / 2, endPoint1.Y - EncoderSize / 2, EncoderSize, EncoderSize);

            PointF basePoint3 = endPoint2;
            PointF endPoint3 = new PointF(baseX - 2 * EgeLength1, EgeLength1);
            // 计算手臂的终点位置
            double radians3 = rotateAngle3 * (Math.PI / 180);
            endPoint3.X = (float)(basePoint1.X - (EgeLength1 * Math.Cos(radians1) + EgeLength2 * Math.Cos(radians1 + radians2) + EgeLength3 * Math.Cos(radians1 + radians2 + radians3)));
            endPoint3.Y = (float)(basePoint1.Y + (EgeLength1 * Math.Sin(radians1) + EgeLength2 * Math.Sin(radians1 + radians2) + EgeLength3 * Math.Sin(radians1 + radians2 + radians3)));
            // 绘制手臂3
            g.DrawLine(new Pen(Encoder3Color, 3), basePoint3, endPoint3);
            // 绘制编码器3
            g.FillEllipse(Brushes.LightBlue, endPoint2.X - EncoderSize / 2, endPoint2.Y - EncoderSize / 2, EncoderSize, EncoderSize);

            if (PositiveFlag)
            {
                // 绘制电批
                g.FillEllipse(ScrewPositiveColor, endPoint3.X - ScrewSize / 2, endPoint3.Y - ScrewSize / 2, ScrewSize, ScrewSize);
            }
            else
            {
                int recWidth = 40;
                int recHeight = 13;
                //double tanValue = (endPoint3.Y - basePoint1.Y) / (basePoint1.X - endPoint3.X);
                //double angle = Math.Tanh(tanValue) * (180 / Math.PI);
                // 设置矩形的位置和大小
                Rectangle rect = new Rectangle((int)(endPoint3.X - recWidth / 2), (int)(endPoint3.Y - recHeight / 2), recWidth, recHeight);
                RotateRectangle(g, rect, ScrewNegativeColor, 90 - rotateAngle1- rotateAngle2- rotateAngle3);
            }

        }

实例链接:https://download.csdn.net/download/lvxingzhe3/89506988

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决VSCode中导入PyTorch时报错的HTTP错误与Channel冲突

问题描述与解释 在Anaconda中成功安装PyTorch&#xff0c;并进行了验证&#xff1a; (base) C:\Users\Hui>conda activate pytorch(pytorch) C:\Users\\Hui>python Python 3.8.19 (default, Mar 20 2024, 19:55:45) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on …

妙手ERP支持授权TikTok Shop全托管店铺,支持智能编辑、定时发布等操作!

全托管模式可以说是近两年跨境电商的热潮&#xff0c;在全托管模式下&#xff0c;卖家只需备货&#xff0c;平台进行运营、履约。因此&#xff0c;这种模式也迅速成为计划出海的跨境卖家重点关注方向。 一、TikTok Shop全托管 目前&#xff0c;几大主流跨境电商平台都已上线全…

springboot旅游管理系统-计算机毕业设计源码16021

摘 要 本文旨在设计和实现一个基于Spring Boot框架的旅游管理系统。该系统通过利用Spring Boot的快速开发特性和丰富的生态系统&#xff0c;提供了一个高效、可靠和灵活的解决方案。系统将实现旅游景点信息的管理、线路规划、跟团游玩、旅游攻略、酒店信息管理、订单管理和用户…

【操作与配置】VSCode配置C/C++及远程开发

MINGW环境配置 进入网站&#xff0c;如下图下载&#xff1a;MinGW Distro - nuwen.net 运行安装包&#xff0c;使其安装在你指定的位置 将MinGW的bin目录添加到系统的环境变量PATH中 使用 winx 选择进入“系统”点击“高级系统设置”在“系统属性&#xff1a;高级”窗口中&am…

Vue前端打包

关于NGINX 介绍:Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少&#xff0c;并发能力强&#xff0c;在各大型互联网公司都有非常广泛的使用。 NGiMx 官网:https://nginx.org/ conf 配置文件目录 html静态资源文件目录 lo…

学习笔记(linux高级编程)11

进程间通信 》信号通信 应用&#xff1a;异步通信。 中断&#xff0c;&#xff0c; 1~64&#xff1b;32应用编程。 如何响应&#xff1a; Term Default action is to terminate the process. Ign Default action is to ignore the signal. wait Core Default action is …

Ignis 应用: 社交 + 游戏 + 工业4.0,Ignis 构建Web3生态圈

引言 在数字经济快速发展的今天&#xff0c;Web3技术为我们带来了前所未有的变革。作为Ardor平台的主要子链&#xff0c;Ignis公链在推动Web3生态系统建设中扮演了重要角色。本文将通过介绍Vessel Chain、Mythical Beings和Bridge Champ等应用&#xff0c;探讨Ignis公链如何通…

基于循环神经网络的一维信号降噪方法(简单版本,Python)

代码非常简单。 import torch import torch.nn as nn from torch.autograd import Variable from scipy.io.wavfile import write #need install pydub module #pip install pydub import numpy as np import pydub from scipy import signal import IPython import matplot…

基于强化学习DQN的股票预测【股票交易】

强化学习笔记 第一章 强化学习基本概念 第二章 贝尔曼方程 第三章 贝尔曼最优方程 第四章 值迭代和策略迭代 第五章 强化学习实例分析:GridWorld 第六章 蒙特卡洛方法 第七章 Robbins-Monro算法 第八章 多臂老虎机 第九章 强化学习实例分析:CartPole 第十章 时序差分法 第十一…

swiftui中常用组件picker的使用,以及它的可选样式

一个可选项列表就是一个picker组件搞出来的&#xff0c;它有多个样式可以选择&#xff0c;并且可以传递进去一些可选数据&#xff0c;有点像前端页面里面的seleted组件&#xff0c;但是picker组件的样式可以更多。可以看官方英文文档&#xff1a;PickerStyle | Apple Developer…

【Week-G2】人脸图像生成(DCGAN)--pytorch版本

文章目录 0、遇到的问题1、配置环境 & 导入数据2、定义模型3、训练模型4、什么是DCGAN? &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 本文环境&#xff1a; 系统环境&#xff1a;…

从搜索框的提示词中再探防抖和节流

前言 最近逛掘金时&#xff0c;看到了一篇文章。发现是我之前写过的一篇文章主题是防抖和节流的&#xff0c;看防抖时没感觉哪里不一样&#xff0c;但是当我看到节流时发现他的节流怎么这么繁琐(・∀・(・∀・(・∀・*)&#xff1f; 抱着疑惑的想法&#xff0c;我仔细拜读了这…

PyCharm 如何设置作者信息

1、点击pycharm右上角的齿轮&#xff0c;选择settings 2、选择editor 3、选择 Editor File and Code Templates 4、选择作者信息的文件类型&#xff0c;中间选择框选择Python Script 5、然后在右边的输入框中输入相关的信息 # -*- coding: utf-8 -*- """ Time …

kotlin接口,前端怎么调用?

文章目录 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1f4dc;其他专栏&#xff1a;Java学习路线 Jav…

构建大数据生态:Sqoop、Hadoop、IDEA和Maven的完整安装与数据预处理指南【实训Day03】

一、Sqoop安装 1 上传安装包并解压缩(在hadoop101上) # cd /opt/software 点击xftp上传sqoop的安装文件sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz # tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/ # cd /opt/module/ # mv s…

vue3+vue-router+vite 实现动态路由

文章中出现的代码是演示版本&#xff0c;仅供参考&#xff0c;实际的业务需求会更加复杂 什么是动态路由 什么场景会用到动态路由 举一个最常见的例子&#xff0c;比如说我们要开发一个后台管理系统&#xff0c;一般来说后台管理系统都会分角色登录&#xff0c;这个时候也就涉…

基于Vue.js和SpringBoot的地方美食分享网站系统设计与实现

你好&#xff0c;我是计算机专业的学姐&#xff0c;专注于前端开发和系统设计。如果你对地方美食分享网站感兴趣或有相关需求&#xff0c;欢迎随时联系我。 开发语言 Java 数据库 MySQL 技术 Vue.js SpringBoot Java 工具 Eclipse, MySQL Workbench, Maven 系统展示…

【Spring Boot】关系映射开发(一):一对一映射

关系映射开发&#xff08;一&#xff09;&#xff1a;一对一映射 1.认识实体间关系映射1.1 映射方向1.2 ORM 映射类型 2.实现 “一对一” 映射2.1 编写实体2.1.1 新建 Student 实体2.1.2 新建 Card 实体 2.2 编写 Repository 层2.2.1 编写 Student 实体的 Repository2.2.2 编写…

AMEYA360代理:海凌科60G客流量统计雷达模块 4T4R出入口绊数计数

数字化时代&#xff0c;不管是大型商城还是各种连锁店&#xff0c;客流统计分析都可以帮助企业更加精准地了解顾客需求和消费行为。 海凌科推出一款专用于客流量统计的60G雷达模块&#xff0c;4T4R&#xff0c;可以实时进行固定范围内的人体运动轨迹检测&#xff0c;根据人体的…

0703_ARM7

练习&#xff1a; 封装exti&#xff0c;cic初始化函数 //EXTI初始化 void hal_key_exti_init(int id,int exticr,int mode){//获取偏移地址int address_offset (id%4)*8;//获取寄存器编号int re_ser (id/4)1;//printf("address_offset%d,re_ser%d\n",address_o…