C#绘制三维坐标系

ops/2025/2/9 14:09:17/

1、代码

#region 三维坐标系的绘制private int axisLength=30;[Category("坐标系")][Description("轴长")]public int AxisLength{get { return axisLength; }set { if(value>30) axisLength = value; }}private int axisGap=10;[Category("坐标系")][Description("边距")]public int AxisGap{get { return axisGap; }set { axisGap = value; }}private string axisNameX = "X";[Category("坐标系")][Description("X轴")]public string AxisNameX{get { return axisNameX; }set { axisNameX = value; }}private string axisNameY = "Y";[Category("坐标系")][Description("Y轴")]public string AxisNameY{get { return axisNameY; }set { axisNameY = value; }}private string axisNameZ = "Z";[Category("坐标系")][Description("Z轴")]public string AxisNameZ{get { return axisNameZ; }set { axisNameZ = value; }}private Font axisFont=new Font("黑体",9,FontStyle.Bold);[Category("坐标系")][Description("字体")]public Font AxisFont{get { return axisFont; }set { axisFont = value; }}private Pen axisPen = new Pen(Color.Black, 2);[Category("坐标系")][Description("画笔")]public Pen AxisPen{get { return axisPen; }set { axisPen = value; }}private Brush axisBrush = new SolidBrush(Color.Black);[Category("坐标系")][Description("画刷")]public Brush AxisBrush{get { return axisBrush; }set { axisBrush = value; }}/// <summary>/// 绘制三维坐标系/// </summary>/// <param name="g"></param>/// <param name="userScreen"></param>public void CoordinateDraw(Graphics g, Size userScreen){int temp = axisGap + (int)(axisLength / 1.414);Point coordinateOrigion = new Point(temp, userScreen.Height - temp);Point originX = new Point(temp + axisLength, userScreen.Height - temp);Point originY = new Point(temp, userScreen.Height - temp - axisLength);Point originZ = new Point(axisGap, userScreen.Height - axisGap);DrawLineWithArrow(g, axisPen, coordinateOrigion, originX, 10);DrawLineWithArrow(g, axisPen, coordinateOrigion, originY, 10);DrawLineWithArrow(g, axisPen, coordinateOrigion, originZ, 10);SizeF size = g.MeasureString(axisNameX, axisFont);g.DrawString(axisNameX, axisFont, axisBrush, new Point(originX.X - (int)size.Width, originX.Y + 5));g.DrawString(axisNameY, axisFont, axisBrush, new Point(originY.X + 5, originY.Y));size = g.MeasureString(axisNameZ, axisFont);g.DrawString(axisNameZ, axisFont, axisBrush, new Point(originZ.X, originZ.Y - (int)size.Height - 10));}#endregionprotected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;Size userScreen = new Size(e.ClipRectangle.Width, e.ClipRectangle.Height);CoordinateDraw(g, userScreen);}/// <summary>/// 绘制带箭头线/// </summary>/// <param name="g"></param>/// <param name="pen"></param>/// <param name="start"></param>/// <param name="end"></param>/// <param name="arrowSize"></param>public static void DrawLineWithArrow(Graphics g, Pen pen, PointF start, PointF end, float arrowSize = 10){g.DrawLine(pen, start, end);if (arrowSize > 0){DrawArrow(g, pen, start, end, arrowSize);}}/// <summary>/// 绘制带箭头线的箭头/// </summary>/// <param name="g">GDI+绘图</param>/// <param name="pen">画笔</param>/// <param name="start">起始点</param>/// <param name="end">结束点</param>/// <param name="arrowSize">箭头大小</param>public static void DrawArrow(Graphics g, Pen pen, PointF start, PointF end, float arrowSize = 10){// 计算线的角度float angle = (float)Math.Atan2(end.Y - start.Y, end.X - start.X);// 箭头起点和终点PointF arrowStart = end;PointF arrowEnd1 = new PointF(end.X - arrowSize * (float)Math.Cos(angle - Math.PI / 6),end.Y - arrowSize * (float)Math.Sin(angle - Math.PI / 6));PointF arrowEnd2 = new PointF(end.X - arrowSize * (float)Math.Cos(angle + Math.PI / 6),end.Y - arrowSize * (float)Math.Sin(angle + Math.PI / 6));// 绘制箭头g.DrawLine(pen, arrowStart, arrowEnd1);g.DrawLine(pen, arrowStart, arrowEnd2);}

2、运行结果
在这里插入图片描述


http://www.ppmy.cn/ops/156991.html

相关文章

计算机领域QPM、TPM分别是什么并发指标,还有其他类似指标吗?

在计算机领域&#xff0c;QPM和TPM是两种不同的并发指标&#xff0c;它们分别用于衡量系统处理请求的能力和吞吐量。 QPM&#xff08;每分钟请求数&#xff09; QPM&#xff08;Query Per Minute&#xff09;表示每分钟系统能够处理的请求数量。它通常用于衡量系统在单位时间…

【Redis】redis 存储的列表如何分页和检索

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

PCDN 搭建的常见问题与答疑

一&#xff0e;PCDN基本概念与原理 Q1: 什么是PCDN&#xff1f; A1: PCDN是一种基于P2P&#xff08;Peer-to-Peer&#xff09;技术的内容分发网络&#xff0c;通过利用用户终端设备的空闲资源和带宽&#xff0c;实现内容的快速分发和共享。它能够在不增加服务器负载的情况下&…

【RabbitMQ重试】重试三次转入死信队列

以下是基于RabbitMQ死信队列实现消息重试三次后转存的技术方案&#xff1a; 方案设计要点 队列定义改造&#xff08;核心参数配置&#xff09; Bean public Queue auditQueue() {Map<String, Object> args new HashMap<>();args.put("x-dead-letter-exchan…

本地缓存 Caffeine 中的时间轮(TimeWheel)是什么?

大家好&#xff0c;我是 方圆。在前文 缓存之美&#xff1a;万文详解 Caffeine 实现原理 中&#xff0c;我们详细介绍了 Caffeine 缓存添加元素和读取元素的流程&#xff0c;并详细解析了配置固定元素数量驱逐策略的实现原理。在本文中我们将主要介绍 配置元素过期时间策略的实…

opencv打开摄像头出现读取帧错误问题

打不开摄像头原因&#xff1a; 手动开启一下&#xff0c;右下角摄像头亮了说明开启了 读取帧错误原因&#xff1a; usb协议错了导致画质损坏&#xff0c;调成3.1即可解决

docker多个容器的相互通信

在同一台宿主机上运行多个 Docker 容器时&#xff0c;容器之间可以通过以下几种方式实现通信&#xff1a; 1. 使用 Docker 默认网络&#xff08;Bridge 网络&#xff09; Docker 默认会为每个容器分配一个 bridge 网络&#xff0c;容器可以通过 IP 地址或容器名称互相通信。 …

大模型Dense、MoE 与 Hybrid-MoE 架构的比较

在大模型架构设计中&#xff0c;Dense&#xff08;全连接&#xff09;、MoE&#xff08;混合专家&#xff09;和Hybrid-MoE&#xff08;混合式MoE&#xff09;是三种主流的参数组织方式&#xff0c;它们在模型容量、计算效率和应用场景上存在显著差异。以下从核心原理、技术特点…