.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骚操作】

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

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

相关文章

.NET CORE(C#) WPF 抽屉式菜单

.NET CORE(C#) WPF 抽屉式菜单阅读导航本文背景代码实现本文参考源码1. 本文背景使用简单动画实现抽屉式菜单2. 代码实现使用 .NET CORE 3.1 创建名为 “AnimatedColorfulMenu” 的WPF模板项目,添加1个Nuget库:MaterialDesignThemes,版本为最…

C++string容器-子串获取

string子串 功能描述&#xff1a; 从字符串中获取想要的子串 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <cstring>//string求子串void test01() {string str "abcdef";string subStr str.sub…

我的 .NET Core 博客性能优化经验补充

点击上方蓝字关注“汪宇杰博客”导语去年年底我写了一篇《我的 .NET Core 博客性能优化经验总结》&#xff0c;但后来还发现有一处遗漏需要补充。我们一起来看看~牺牲空间换时间我们知道软件设计只有高手才能做到又小又快&#xff0c;像我这种普通程序员通常只有两种方案&#…

使用 OAS(OpenAPI标准)来描述 Web API

无论哪种类型的Web API, 都可能需要给其他开发者使用. 所以API的开发者体验是很重要的. API的开发者体验, 简写为 API DX (Developer Experience). 它包含很多东西, 例如如何使用API, 文档, 技术支持等等, 但是最重要的还是API的设计. 如果 API 设计的不好, 那么使用该API构建的…

dedemodule.class.php,DEDECMS5.7模块/模块管理列表显示空白问题解决方法

DEDECMS5.7模块/模块管理列表显示空白(站长基地配图)今天站长基地升级至dedecms最新版本&#xff0c;进入后台意外的发现&#xff0c;模块/模块管理一片空白&#xff0c;但有没有及时备份&#xff0c;于是赶紧去网上找寻解决办法&#xff0c;经过整理&#xff0c;大致有以下几种…

dotNET Core 中怎样操作AD(续1)

在之前的文章《dotNET Core 中怎样操作 AD&#xff1f;》中主要以AD的数据同步到数据库的场景来描述了在 dotNetCore 中怎样操作AD&#xff0c;本文将继续介绍一些在 dotNetCore 中操作 AD 的其他常用操作。环境dotNET Core&#xff1a;3.0Novell.Directory.Ldap.NETStandard2_…

【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分

为了更好的完善Magicodes.IE&#xff0c;春节期间我们会进行一次大的重构。由于精力有限&#xff0c;急缺文档和翻译&#xff08;将文档翻译为英文文档&#xff09;支持&#xff0c;诚邀各位加入。同时在功能方便也做了相关规划&#xff0c;有兴趣的朋友可以参与提交PR。https:…

Mbp,一个用于学习.net core的开发框架

Mbp(https://github.com/mbpframework/Mbp)是一个.net core 3的企业级web开发框架,是我个人用于学习.net core而发起的一个开源项目.这个借鉴了国外优秀开源项目abp vnext,及国内优秀开源框架Osharp的一些思想和实现.欢迎各路开发爱好者加入这个项目,一起学习,一起玩耍,共同成长…

什么?原来C#还有这两个关键字

系列介绍简介【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面&#xff0c;比如C#的小细节&#xff0c;AspnetCore&#xff0c;微服务中的.net知识等等。场景您可以在下班坐地铁的时候&#xff0c;拿出…

蓝桥杯2015初赛-三羊献瑞-枚举

题目描述 观察下面的加法算式&#xff1a; 其中&#xff0c;相同的汉字代表相同的数字&#xff0c;不同的汉字代表不同的数字。 请你填写“三羊献瑞”所代表的4位数字&#xff08;答案唯一&#xff09;&#xff0c;不要填写任何多余内容。 输出 请你填写“三羊献瑞”所代表…

如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出

这是该系列的第一篇文章&#xff1a;在ASP.NET Core 3.0中使用Serilog.AspNetCore。第1部分-使用Serilog RequestLogging来简化ASP.NET Core的日志输出&#xff08;本篇文章&#xff09;第2部分-使用Serilog记录所选的端点名称[敬请期待]第3部分-使用Serilog.AspNetCore记录MVC…

net下的高性能轻量化半自动orm+linq的《SqlBatis》

一、项目介绍该项目内置单表linq操作&#xff0c;xml动态sql解析&#xff0c;词法分析&#xff0c;类型映射等功能。SqlMapper,用来处理sql与数据库操作&#xff0c;它设计的目标是支持mysql,sqlserver,sqllite,pgsql等.TypeMapper用于完成将数据库的字段类型映射到C#类型&…

如何快速融入团队(六)

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;一我总是在记忆深处探访那些拥有高效率团队的一切特征&#xff0c;并试图从纷繁复杂的记忆尘埃中找出一些共性&#xff0c;庆幸我已经习惯于通过阅读和思考来解读这些内容&a…

临近年关,修复ASP.NET Core因浏览器内核版本引发的单点登录故障

临近年关&#xff0c;咨询师提出360、搜狗急速浏览器无法单点登录到公司核心产品WD: 重定向过多。现象经过测试&#xff0c; 出现单点登陆故障的是搜狗、360等双核浏览器(默认使用Chrome内核)&#xff0c; 较新式的Edge、Chrome、Firefox均未出现此障碍。Developer tool监测不到…

Asp.Net Core 已支持 gRPC-Web !!

grpc-dotnet 项目在 PR #695 完成了 ASP.NET Core 服务与 .NET Core gRPC 客户端的 gRPC-Web 实现。虽然目前还是实验性项目&#xff0c;但是并不阻碍我们为之兴奋。下面我们来看看如何使用。gRPC-Web 简介gRPC-Web 允许从浏览器应用程序使用 gRPC&#xff0c;gRPC-Web 支持在新…

蓝桥杯2017初赛-打印大X-找规律

题目描述 小明希望用星号拼凑&#xff0c;打印出一个大X&#xff0c;他要求能够控制笔画的宽度和整个字的高度。 为了便于比对空格&#xff0c;所有的空白位置都以句点符来代替。 要求输入两个整数m n&#xff0c;表示笔的宽度&#xff0c;X的高度。 输入 输入存在多组数据 …

蓝桥杯2015决赛-方格填数-枚举 or dfs

题目描述 在2行5列的格子中填入1到10的数字。 要求&#xff1a;相邻的格子中的数&#xff0c;右边的大于左边的&#xff0c;下边的大于上边的。 如下图所示的2种&#xff0c;就是合格的填法。 请你计算一共有多少种可能的方案。 输出 请输出该整数&#xff0c;不要输出任何多…

【实战 Ids4】║ 在Swagger中调试认证授权中心

回家的路上照顾好自己哟~大家好&#xff0c;老张已经顺利到家啦&#xff0c;闲的无事写两篇文章冒个泡吧&#xff0c;其实写的内容都是群友提出来的问题&#xff0c;简单的我会在群里直接提供思路&#xff0c;麻烦的我就写个文章说明一下吧&#xff0c;也是自己的一个记录作用&…

linux 集群 java,Linux Tomcat 集群 利用记实1--搭建javaWeb运行情况

前段时候一向在搞linux&#xff0c;有很多多少工具只曩昔没有做过。影象不是那么深刻&#xff0c;此刻把历程记实下来&#xff0c;以备今后盘问。一&#xff1a;起首说一下我们的计划&#xff0c; 一共有六台办事器&#xff0c;此中两台安置Oracle 10g做数据库集群(这个不在这篇…

在 Blazor WebAssembly 中使用 gRPC-Web

对于单页面应用程序&#xff0c;gRPC-Web 是 JSON-over-HTTP 的一种方便、高性能的替代方案。如果你已经了解关于 gRPC 和 gRPC-Web 的一切&#xff0c;你可以跳到 添加 gRPC 服务到一个Blazor WebAssembly 应用程序 一节。如果你只是想要一些简单的 Blazor WebAssembly gRPC-…