.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);

最后,运行效果如下:

总结

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

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

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

.NET绘制旋转太极图的更多相关文章

  1. Winform GDI+绘图二:绘制旋转太极图

    大家好,今天有时间给大家带来Winform自绘控件的第二部分,也是比较有意思的一个控件:旋转太极图. 大家可以停下思考一下,如果让你来绘制旋转的太极图,大家有什么样的思路呢?我今天跟大家展示一下,我平 ...

  2. 基于CSS3伪元素和动画绘制旋转太极图

    通过CSS3的动画知识来完成一个旋转的太极. 任务 1.创建一个div,用CSS控制其大小.边框.位置等,做成一个静态的圆形,一半为红色一半为白色. 2.用div的伪元素位置两个圆环并放置核实位置,使 ...

  3. Html5 绘制旋转的太极图

    采用Html5+JavaScript在Canvas中绘制旋转的太极图,如下图所示: 具体思路和绘制逻辑,在上图中已有说明,代码如下: <script type="text/javasc ...

  4. HTML 5:绘制旋转的太极图

    HTML: <!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title& ...

  5. Python turtle绘制阴阳太极图代码解析

    本文详细分析如何使用Python turtle绘制阴阳太极图,先来分解这个图形,图片中有四种颜色,每条曲线上的箭头表示乌龟移动的方向,首先从中心画一个半圆(红线),以红线所示圆的直径作半径画一个校园, ...

  6. CSS3绘制旋转的太极图案(一)

        实现步骤: 基础HTML: <div class="box-taiji"> <div class="circle-01">< ...

  7. C#利用GDI+绘制旋转文字等效果

    C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...

  8. 测试canvas绘制旋转文字的性能

    canvas 绘制各种动画效果时,我们经常会使用画布旋转,使绘制上去的元素有旋转的效果. 最近在项目中碰到了很严重的性能问题,经常排查发现是因为绘制批量文字时使用了画布旋转,且每行文字的旋转角度是不一 ...

  9. CSS3制作太极图以及用JS实现旋转太极图

     太极图可以理解为一个一半黑一半白的半圆,上面放置着两个圆形,一个黑色边框白色芯,一个白色边框黑色芯. 1.实现黑白各半的圆形. .box{ width:200px;height:200px; bor ...

随机推荐

  1. window 系统下修改`CMD`的编码格式的方法,`CHCP` 的 使用

    CHCP的使用 CHCP是一个计算机指令,能够显示或设置活动代码页编号. 一般上是在命令提示框中使用,用来查询和修改命令提示框的编码格式 具体使用方法 查看活动代码页编号 方式1: >>& ...

  2. 2019-6-5-WPF-使用封装的-SharpDx-控件

    title author date CreateTime categories WPF 使用封装的 SharpDx 控件 lindexi 2019-6-5 9:4:36 +0800 2018-4-24 ...

  3. H3C 动态路由协议的基本原理

  4. vue+element-ui实现分页

    我使用得是el-table+el-pagination来实现的, 话不多说,直接上代码 html代码部分 <!-- table --> <el-table :data="s ...

  5. Trendalyzer is an information visualization software

    Trendalyzer is an information visualization software for animation of statistics that was initially ...

  6. 【Docker】镜像分层存储与镜像精简

    Linux操作系统 Linux操作系统由内核空间和用户空间组成. 内核空间是kernel,用户空间是rootfs, 不同Linux发行版的区别主要是rootfs.比如 Ubuntu 14.04 使用 ...

  7. 使用exp/imp 在oracle数据库间导数据

    最近工作需要将oracle数据库的表数据导出到另一个oracle数据库表,找到了oracle 自带的命令行,并记录下导数据过程. 导数据过程分以下几步: 假设源数据库为A,目标数据库为B 1.在B上通 ...

  8. slim中的请求URI

    请求 URI 每个 HTTP 请求都有一个识别被请求的应用程序资源的 URI .HTTP 请求 URI 分为这几部分: Scheme (e.g. http or https) Host (e.g. e ...

  9. win10安装Keras报错处理

    本机已经安装好TensorFlow安装Keras的过程中遇到了些问题,解决后做一下记录: 1.Keras与TensorFlow的关系 Keras默认以TensorFlow为后端,同时可选以Theano ...

  10. 驱动领域DDD的微服务设计和开发实战

    你是否还在为微服务应该拆多小而争论不休?到底如何才能设计出收放自如的微服务?怎样才能保证业务领域模型与代码模型的一致性?或许本文能帮你找到答案. 本文是基于 DDD 的微服务设计和开发实战篇,通过借鉴 ...