.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. 【u224】传送机

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 刷完牙洗完脸,黄黄同学就要上课去了.可是黄黄同学每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄 ...

  2. P1072 城市轰炸

    题目描述 一个大小为N*M的城市遭到了X次轰炸,每次都炸了一个每条边都与边界平行的矩形. 在轰炸后,有Y个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几轮. 输入格式 ...

  3. CKEditor配置,最适合新手两种方式详解。

    CKEditor.js的配置,大概有两种方式,这里有基础版和全面的版本可以试验 https://cdn.ckeditor.com/4.8.0/full-all/ckeditor.js http://c ...

  4. 【GYM102091】2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest

    A-Evolution Game 题目大意:有$n$个不同的野兽,定义第$i$ 个野兽有 $i$ 个眼睛和 $h[i]$ 个角,你可以任意从中选择一个野兽进行进化,每次进化角数量必须增加,而且进化后要 ...

  5. C# 大端小端转换

    关于大端和小端,是一个有趣的问题.本文告诉大家如何在C#转换大端和小端. 这里有一个有趣的故事,请看详解大端模式和小端模式 - CSDN博客 默认的 C# 使用的是小端,如果收到的消息是大端,那么就会 ...

  6. 快排java代码

    定一个基准位,递归左右两边排序. public void fun(){ int arr[] = {2,3,4,5,6,7,822,3,4,5,8,6,5,4,2,1}; //System.out.pr ...

  7. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  8. Java 连接 SQL Server 数据库

    //连接数据库 public Connection getConnection(){ //url为绝对路径 String url="jdbc:sqlserver://127.0.0.1:14 ...

  9. ELK学习实验007:Nginx的日志分析系统之Metribeat配置

    一 Metricbeat 简介 1.1 系统级监控,更简洁将 Metricbeat 部署到您的所有 Linux.Windows 和 Mac 主机,并将它连接到 Elasticsearch 就大功告成了 ...

  10. 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树

    正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...