03/04/2016

[UWP] Draw a Circle Sector With Path


Hình tròn (Circle) có thể được tạo một cách dễ dàng bởi các control có sẵn trong Universal App. Dưới đây là liệt kê một vài control cơ bản mà bạn có thể sử dụng:

  • Ellipse với Width = Height
  • Rectangle với Width = Height, RadiuX = RadiusY= Width/2
  • Grid/Border với Width = Height, CornerRadius =  Width/2

Vậy để vẽ một Sector của hình tròn thì sao? Đừng lo lắng, bạn có thể sử dụng Path để vẽ chúng. Path thực chất chỉ chứa các dữ liệu... để tạo nên  một hình phức tạp, thuộc tính chứa dữ liệu đó là Data.

Tìm hiểu thêm:


Nếu bạn làm việc bằng công cụ thiết kế trực quan thì dữ liệu Data tự tạo ra gồm một chuỗi các ký tự, thoạt trông khá khó hiểu. Nhưng nó chỉ là tọa độ, độ dài của các point, line và đều bắt đầu với một ký tự đại diện để phân biệt.

Tìm hiểu thêm:


Trong một yêu cầu mới với nhiều thay đổi, ví dụ như tạo Sector của hình tròn với bán kính (Radius), góc (Degrees), vị trí (Start angle - End angle) tùy biến. Có lẽ sử dụng code-behind sẽ dễ dàng hơn.

Figure 1: I had drawn on Visio 2016

A. Input

Radius: Nhập vào độ dài bán kính.
Angle/Percent: Nhập vào góc hoặc phần trăm Sector muốn tạo.
Start Angle: Tọa độ bắt đầu của Sector. Mặc định thì tọa độ 0 như trên hình
End Angle: Không cần thiết, ta dựa vào angle/percent + start angle ta có thể biết end angle.

B. Request

CenterPoint: Tọa độ vị trí trung tâm của hình tròn, bạn chọn ở đâu thì hình tròn sẽ nằm ở đó.
Radius: Độ dài bán kính
StartPoint: Tọa độ điểm bắt đầu của Arc, ta có công thức
var startX= centerPoint.X + radius * Math.Cos(startAngle * Math.PI / 180);
var startY = centerPoint.Y + radius * Math.Sin(startAngle  * Math.PI / 180);
EndPoint: Tọa độ điểm cuối của Arc, ta có công thức
var endX= centerPoint.X + radius * Math.Cos(endAngle * Math.PI / 180);
var endY = centerPoint.Y + radius * Math.Sin(endAngle  * Math.PI / 180);
Size: Width/Height của Arc, ta dựa vào Radius, do đó ta có Size(Radius,Radius)
Chú ý: Nếu bạn thay thế Angle/Percent bằng Radian thì rút gọn Math.PI/180 bằng Math.PI

C. Implementation Method: C#

private PathGeometry CreateCircleSectorAtPoint(double center, double radius, double percent, double startAngle)
{
    //Request
    var centerPoint = new Point(center, center);
    var angle = 360 * (percent / 100);
    var endAngle = startAngle + angle;

    var startX = centerPoint.X + radius * Math.Cos(startAngle * Math.PI / 180);
    var startY = centerPoint.Y + radius * Math.Sin(startAngle * Math.PI / 180);

    var endX =  centerPoint.X + radius * Math.Cos(endAngle * Math.PI / 180);
    var endY =  centerPoint.Y + radius * Math.Sin(endAngle * Math.PI / 180);

    //Path Figure

    PathFigure pf = new PathFigure();
    pf.StartPoint = new Point(startX, startY);
    pf.IsClosed = true;
    pf.IsFilled = true;

    //ARC
    ArcSegment arc = new ArcSegment();
    arc.Point = new Point(endX, endY);
    arc.Size = new Size(radius, radius);
    arc.IsLargeArc = percent > 50 ? true : false;
    arc.SweepDirection = SweepDirection.Clockwise;

    // Line Segment
    LineSegment ls = new LineSegment();
    ls.Point = new Point(center, center);

    // Add child
    PathSegmentCollection psc = new PathSegmentCollection();
    psc.Add(arc);
    psc.Add(ls);

    pf.Segments = psc;
    PathFigureCollection pfc = new PathFigureCollection();
    pfc.Add(pf);

    PathGeometry pg = new PathGeometry();
    pg.Figures = pfc;

    //Return Data
    return pg;
}

D. Result

Figure 2: Demo Circle Sector On Visual Studio 2015 - UWA

Done :)

E. Read more

Figure 3: About Sigment and Sector
See calculate for Sigment
Warning:
The argument to Math.Sin(a) and Math.Cos(a) is in radians, not degrees. To convert, multiply by π/180:
var a = Math.Sin(27);
// Result: 0.956375928404503
var b = Math.Sin(27 * Math.PI / 180);
// Result: 0.453990499739547
Try it in Visual Studio and your calculator!

Created: 03/04/2016
Updated: 04/04/2016
Updated: 05/04/2016
Full Source code: DrawCircleSector

Share

Happy Reading!

[UWP] Draw a Circle Sector With Path
4/ 5
Oleh

Buzz!

Stay updated via email new newsletter

Don't
Use obscene or offensive language.
Personally attack people, their edits, or their comments.
Rant or otherwise harass, abuse, or intimidate others.
Post anything you don't want the world to see. This is a public space.
Infringe copyright.