.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绘制旋转太极图的更多相关文章
- Winform GDI+绘图二:绘制旋转太极图
大家好,今天有时间给大家带来Winform自绘控件的第二部分,也是比较有意思的一个控件:旋转太极图. 大家可以停下思考一下,如果让你来绘制旋转的太极图,大家有什么样的思路呢?我今天跟大家展示一下,我平 ...
- 基于CSS3伪元素和动画绘制旋转太极图
通过CSS3的动画知识来完成一个旋转的太极. 任务 1.创建一个div,用CSS控制其大小.边框.位置等,做成一个静态的圆形,一半为红色一半为白色. 2.用div的伪元素位置两个圆环并放置核实位置,使 ...
- Html5 绘制旋转的太极图
采用Html5+JavaScript在Canvas中绘制旋转的太极图,如下图所示: 具体思路和绘制逻辑,在上图中已有说明,代码如下: <script type="text/javasc ...
- HTML 5:绘制旋转的太极图
HTML: <!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title& ...
- Python turtle绘制阴阳太极图代码解析
本文详细分析如何使用Python turtle绘制阴阳太极图,先来分解这个图形,图片中有四种颜色,每条曲线上的箭头表示乌龟移动的方向,首先从中心画一个半圆(红线),以红线所示圆的直径作半径画一个校园, ...
- CSS3绘制旋转的太极图案(一)
实现步骤: 基础HTML: <div class="box-taiji"> <div class="circle-01">< ...
- C#利用GDI+绘制旋转文字等效果
C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...
- 测试canvas绘制旋转文字的性能
canvas 绘制各种动画效果时,我们经常会使用画布旋转,使绘制上去的元素有旋转的效果. 最近在项目中碰到了很严重的性能问题,经常排查发现是因为绘制批量文字时使用了画布旋转,且每行文字的旋转角度是不一 ...
- CSS3制作太极图以及用JS实现旋转太极图
太极图可以理解为一个一半黑一半白的半圆,上面放置着两个圆形,一个黑色边框白色芯,一个白色边框黑色芯. 1.实现黑白各半的圆形. .box{ width:200px;height:200px; bor ...
随机推荐
- 关于移动端弹层下的body滚动
关于移动端弹层下的body滚动 这个问题在移动端挺常见的,网上也有一些解决方法,现在笔者来总结一下:css的解决方案都有兼容问题,js是比较稳定的解决方法(虽然比较麻烦) ps: 本文的例子都是用vu ...
- js基础——流程控制语句
1.if语句 if(条件表达式){ 若条件成立只执行我,下面的分支不执行 }else if(条件表达式){ 语句; }else if(条件表达式){ 语句; }else{ ...
- linux 在启动时获得专用的缓冲
如果你真的需要一个大的物理上连续的缓冲, 最好的方法是在启动时请求内存来分配它. 在启动时分配是获得连续内存页而避开 get_free_pages 施加的对缓冲大小限制的唯一 方法, 不但最大允许大小 ...
- Linux 内核提交 urb
一旦 urb 被正确地创建,并且被 USB 驱动初始化, 它已准备好被提交给 USB 核心来发送 出到 USB 设备. 这通过调用函数 usb_submit_urb 实现: int usb_submi ...
- Fetch 记录
encodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号.正斜杠.问号和井字号:而encodeURIComponent()则会对它发现的任何非标准字符进行编码. Fetch 请求body ...
- 【35.12%】【POJ 1988】Cube Stacking
Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 24007 Accepted: 8432 Case Time Limit: 100 ...
- koa2--07.cookies的设置和使用
cookies本身在koa中即可直接设置和使用,不需要在安装中间件 //cookies的使用 const koa = require('koa'); var router = require('koa ...
- javascript拷贝
function copy(obj){ //浅拷贝 var result = {}; for(var attr in obj){ result[attr] = obj[attr]; } return ...
- Java8 Date API
一 .Clock 时钟 Clock类提供了访问当前日期和时间的方法,Clock是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数.某一个特定的时间点也 ...
- 20191010-7 alpha week 1/2 Scrum立会报告+燃尽图 06
此作业参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8750 小组名称:“组长”组 组长:杨天宇 组员:魏新,罗杨美慧,王歆瑶,徐丽 ...