Foreword
I sent an article before " ," the article, but some people have questioned, that there is no "scientific" ( ) ???? basis.用.NET写“算命”程序
mi
xin
The so-called "Tai Chi two appearances, two appearances of Health four images, four images and raw gossip, gossip given good and bad, good and bad of Health of the Republic", so I just proved that Tai Chi diagram can be drawn, it shows no fortune-telling "science" is based on Well ????.NET
.NET
First look at the final results:
Tai Chi constitution
Careful observation of this Tai Chi, which is divided into the following sections:
Basic window
White circle left, right circular black
White left circle black circle, black circle in the right white circle
1/4
1/4
Black, white semicircle
Rotation animation
Therefore, when the production, we started production from these areas.
Basic window
First need to render a window, use , you can easily create a:FlysEngine.Desktop
using var taiji = new RenderWindow();
taiji.Draw += (o, e) =>
{
e.Clear(Color.CornflowerBlue);
};
RenderLoop.Run(taiji, () => taiji.Render(1, 0));
Operating results are as follows:
White circle left, right circular black
Direct2D
Draw a circle and there are very simple API
, can be called directly, but before you need to determine the radius of the circle, our most window 宽
and 高
a smaller value minus the 5
margin units ( Margin
), the way to calculate the center point, in order to slightly after doing matrix transformation:
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;
Incidentally, the definition of what black and white two colors:
Color Color_Black = Color.Black;
Color Color_White = Color.White;
Therefore drawing code as follows:
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));
At this time, operating results are as follows:
1/4 round
1/4
One round is the essence of Tai Chi, which represents precisely the yin and yang of alternate complementary.
Its essence is the circle center of a circle there is another color, the code is relatively simple, simply add the following code to above:
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));
At this time, operating results are as follows:
Black and white semicircle
There is one final finishing touches, is the need for a larger circle that contains the graphics. Think about it, in fact, this "larger circle" are two different colors semicircle in the Direct2D
middle, you need Geometry
to realize, first of all to define this semicircle:
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();
Then in Draw
the event Clear
after the first draw on the black semicircle:
ctx.Transform = Matrix3x2.Scaling(scale, scale) * Matrix3x2.Translation(center);
ctx.FillGeometry(arc, o.XResource.GetColor(Color_Black));
Operating results are as follows:
Then draw the white semicircle, to write code is also noted that left and right circularly code before drawing:
ctx.Transform = Matrix3x2.Scaling(scale, scale) * Matrix3x2.Rotation((float)Math.PI) * Matrix3x2.Translation(center);
ctx.FillGeometry(arc, o.XResource.GetColor(Color_White));
Operating results are as follows:
此时就已经是一个完整的太极图标了,最后还需要添加旋转动画。
旋转动画
动画的本质,是图形的坐标、旋转随着时间的移动,而有规律的移动。这里特指旋转,我们定义每秒旋转 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骚操作】