Drawing FIG .NET rotation Taiji

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  circle1/41/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

Direct2DDraw 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  5margin 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/4One 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  Direct2Dmiddle, you need  Geometryto 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  Drawthe event  Clearafter 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骚操作】

发布了1535 篇原创文章 · 获赞 586 · 访问量 237万+

Guess you like

Origin blog.csdn.net/sD7O95O/article/details/104057719