.NET绘制旋转太极图

2023-11-06 08:32
文章标签 绘制 旋转 net 太极图

本文主要是介绍.NET绘制旋转太极图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

我之前发了一篇《 用.NET写“算命”程序》的文章,但有人纷纷提出了质疑,认为没有“科学”( mi xin)依据????。

所谓“太极生两仪,两仪生四象,四象生八卦,八卦定吉凶,吉凶生大业”,因此,我只要证明 .NET可以将太极图绘制出来,不就说明 .NET算命的“科学”是有依据了嘛????

首先来看一下最终效果: 

太极的构成

仔细观察这个太极图,它分为以下几部分:

  • 基本窗口

  • 白色左圆、黑色右圆

  • 白色左圆中的黑色 1/4圆,黑色右圆中的白色 1/4

  • 黑色、白色半圆

  • 旋转动画

因此制作时,我们从这些方面着手制作。

基本窗口

首先需要一个渲染窗口,使用 FlysEngine.Desktop,可以轻松制作一个:

using var taiji = new RenderWindow();
taiji.Draw += (o, e) =>
{e.Clear(Color.CornflowerBlue);
};
RenderLoop.Run(taiji, () => taiji.Render(1, 0));

运行效果如下: 

白色左圆、黑色右圆

Direct2D有绘制圆和非常简单的 API,可以直接调用,但在此之前需要先确定该圆的半径,我们最窗口 和 的较小值减去 5单位的边距( Margin),顺便计算一下中心点,以便于稍后做矩阵变换:

float GetMinEdge() => Math.Min(taiji.XResource.RenderTarget.Size.Width, taiji.XResource.RenderTarget.Size.Height);
Vector2 GetCenter() => new Vector2(taiji.XResource.RenderTarget.Size.Width / 2, taiji.XResource.RenderTarget.Size.Height / 2);
float GetR() => (GetMinEdge() - 5.0f) / 2;

顺便定义一下黑、白两种颜色:

Color Color_Black = Color.Black;
Color Color_White = Color.White;

所以绘制的代码如下:

float scale = GetR();
Vector2 center = GetCenter();
Matrix3x2 rotation = Matrix3x2.Rotation(angle);
ctx.Transform = rotation * Matrix3x2.Scaling(scale, scale) * Matrix3x2.Translation(center);
ctx.FillEllipse(new Ellipse(new Vector2(0.5f, 0), 0.5f, 0.5f), o.XResource.GetColor(Color_Black));
ctx.FillEllipse(new Ellipse(new Vector2(-0.5f, 0), 0.5f, 0.5f), o.XResource.GetColor(Color_White));

此时,运行效果如下: 

1/4圆

1/4圆是太极的精髓之一,正是它代表了阴与阳的互生互补。

其本质就是圆的中心还有另一个颜色的圆,代码相对简单,只需在上文代码中添加如下即可:

ctx.FillEllipse(new Ellipse(new Vector2(0.5f, 0), 0.25f, 0.25f), o.XResource.GetColor(Color_White));
ctx.FillEllipse(new Ellipse(new Vector2(-0.5f, 0), 0.25f, 0.25f), o.XResource.GetColor(Color_Black));

此时,运行效果如下: 

黑白半圆

还需要最后临门一脚,就是需要一个更大的圆,包含这个图形。仔细想想,其实这个“更大的圆”是两个不同颜色的半圆,在 Direct2D中,需要使用 Geometry来实现,首先来定义这个半圆:

using var arc = new PathGeometry(taiji.XResource.Direct2DFactory);
var sink = arc.Open();
sink.BeginFigure(new Vector2(-1f, 0), FigureBegin.Filled);
sink.AddArc(new ArcSegment
{Point = new Vector2(1f, 0), Size = new Size2F(1f, 1f), RotationAngle = 0.0f, SweepDirection = SweepDirection.Clockwise, ArcSize = ArcSize.Large, 
});
sink.EndFigure(FigureEnd.Open);
sink.Close();

然后在 Draw事件的 Clear之后,首先绘制黑色上半圆:

ctx.Transform = Matrix3x2.Scaling(scale, scale) * Matrix3x2.Translation(center);
ctx.FillGeometry(arc, o.XResource.GetColor(Color_Black));

运行效果如下: 

然后再绘制白色下半圆,注意代码也要写在绘制左右圆的代码之前:

ctx.Transform = Matrix3x2.Scaling(scale, scale) * Matrix3x2.Rotation((float)Math.PI) * Matrix3x2.Translation(center);
ctx.FillGeometry(arc, o.XResource.GetColor(Color_White));

运行效果如下: 

此时就已经是一个完整的太极图标了,最后还需要添加旋转动画。

旋转动画

动画的本质,是图形的坐标、旋转随着时间的移动,而有规律的移动。这里特指旋转,我们定义每秒旋转 0.25圈(即每 4秒转一圈):

const float Speed = 0.25f;

转换为旋转角,需要在 UpdateLogic中添加代码如下:

float angle = 0.0f;
taiji.UpdateLogic += (w, dt) =>
{angle += MathUtil.Mod2PI(Speed * MathUtil.TwoPi * dt);
};

最后需要将旋转角 angle转换为矩阵变换,注意在操作矩阵乘法时,旋转往往要放在第一位,否则旋转中心点可能会出现意外,代码如下,用于替换上文中的直接绘制代码:

Matrix3x2 rotation = Matrix3x2.Rotation(angle);
ctx.Transform = rotation * Matrix3x2.Scaling(scale, scale) * Matrix3x2.Translation(center);
ctx.FillGeometry(arc, o.XResource.GetColor(Color_Black));
ctx.Transform = rotation * Matrix3x2.Scaling(scale, scale) * Matrix3x2.Rotation((float)Math.PI) * Matrix3x2.Translation(center);
ctx.FillGeometry(arc, o.XResource.GetColor(Color_White));
ctx.Transform = rotation * Matrix3x2.Scaling(scale, scale) * Matrix3x2.Translation(center);

最后,运行效果如下: 

总结

前言中关于“科学”的论述,只是开个玩笑……但绘制这个太极图形,还是需要一些技巧的。

本文中的所有可直接运行的代码,已经上传到我的 Github:https://github.com/sdcb/blog-data/tree/master/2020/20200119-draw-taiji-using-dotnet

喜欢的朋友请关注我的微信公众号:【DotNet骚操作】

这篇关于.NET绘制旋转太极图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/355567

相关文章

C#利用Free Spire.XLS for .NET复制Excel工作表

《C#利用FreeSpire.XLSfor.NET复制Excel工作表》在日常的.NET开发中,我们经常需要操作Excel文件,本文将详细介绍C#如何使用FreeSpire.XLSfor.NET... 目录1. 环境准备2. 核心功能3. android示例代码3.1 在同一工作簿内复制工作表3.2 在不同

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图

在.NET项目中嵌入Python代码的实践指南

《在.NET项目中嵌入Python代码的实践指南》在现代开发中,.NET与Python的协作需求日益增长,从机器学习模型集成到科学计算,从脚本自动化到数据分析,然而,传统的解决方案(如HTTPAPI或... 目录一、CSnakes vs python.NET:为何选择 CSnakes?二、环境准备:从 Py

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

在ASP.NET项目中如何使用C#生成二维码

《在ASP.NET项目中如何使用C#生成二维码》二维码(QRCode)已广泛应用于网址分享,支付链接等场景,本文将以ASP.NET为示例,演示如何实现输入文本/URL,生成二维码,在线显示与下载的完整... 目录创建前端页面(Index.cshtml)后端二维码生成逻辑(Index.cshtml.cs)总结

解决hive启动时java.net.ConnectException:拒绝连接的问题

《解决hive启动时java.net.ConnectException:拒绝连接的问题》Hadoop集群连接被拒,需检查集群是否启动、关闭防火墙/SELinux、确认安全模式退出,若问题仍存,查看日志... 目录错误发生原因解决方式1.关闭防火墙2.关闭selinux3.启动集群4.检查集群是否正常启动5.

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,