思路
我們可以使用Ellipse先畫出一個圓當背景,然後用Canvas再疊加畫上刻度線,就能得到如下的效果
我們先用Ellipse畫一個橙色的圓,然後將Canvas的寬度和高度繫結到Ellipse的寬度和高度
<Grid> <Ellipse Fill="Orange" Width="400" Height="400" Name="BackEllipse"/> <Canvas x:Name="MainCanvas" Width="{Binding Width,ElementName=BackEllipse}" Height="{Binding Height,ElementName=BackEllipse}"/> </Grid>
然後我們現在只需要知道點的位置,就可以通過canvas畫出相應的線條了.
計算圓上點的位置
假設我們要計算的點為X,那麼隊員X點的座標為(X1,Y1)
sin(a)=Y1/r => Y1=r*sin(a)
cos(a)=X1/r => X1=r*cos(a)
使用Math.Sin來計算的話得先把角度轉換為弧度
角度轉換為弧度
參考https://blog.csdn.net/chelen_jak/article/details/80480390
1、角度定義
兩條射線從圓心向圓周射出,形成一個夾角和夾角正對的一段弧。當弧長正好等於圓周長的360分之一時,兩條射線的夾角的大小為1度。(單位: º)
2、弧度定義
兩條射線從圓心向圓周射出,形成一個夾角和夾角正對的一段弧。當這段弧長正好等於圓的半徑時,兩條射線的夾角大小為1弧度(單位:rad)
即弧度 = 弧長 / 半徑
圓一週的弧度=周長 / 半徑 => 2πr / r =360º => π=180º,繼而可以知道一弧度等於180º/π
可知:sin(30º)=Math.Sin(30*Math.PI / 180)
使用canvas畫出線段
我們只需要計算出X點和Z點的座標,就能使用Line來連線兩點畫出刻度線了.
假設Z所在的圓的半徑為r,X所在的圓的半徑為(r-20)
double radius = BackEllipse.Width / 2; Line lineScale = new Line(); lineScale.X1 = (radius - 20) * Math.Cos(30 * Math.PI / 180); lineScale.Y1 = (radius - 20) * Math.Sin(30 * Math.PI / 180); lineScale.X2 = radius * Math.Cos(30 * Math.PI / 180); lineScale.Y2 = radius * Math.Sin(30 * Math.PI / 180); lineScale.Stroke = Brushes.Red; lineScale.StrokeThickness = 2; MainCanvas.Children.Add(lineScale);
可以得到影像
我們先把把canvas用藍色填充,然後把X點設為(0,0)來看下效果可知,圓心的位置為左上角,我們可以先把刻度都畫出來,再移動下canvas繪畫的起點到橙色圓的圓心就行了
我們把360度分成100分來畫出100個刻度線,程式碼如下
double radius = BackEllipse.Width / 2; double min = 0; double max = 100; double step = 360.0 / (max - min); for (int i = 0; i < max - min; i++) { Line lineScale = new Line { X1 = (radius - 20) * Math.Cos(i * step * Math.PI / 180), Y1 = (radius - 20) * Math.Sin(i * step * Math.PI / 180), X2 = radius * Math.Cos(i * step * Math.PI / 180), Y2 = radius * Math.Sin(i * step * Math.PI / 180), Stroke = Brushes.Red, StrokeThickness = 2 }; MainCanvas.Children.Add(lineScale); }
我們只需要把X點和Z點都加上半徑就能把canvas繪畫的起點移動到圓心的位置,把canvas的背景色去掉效果就實現我們想要的效果了
完整的代為如下
前臺程式碼
<Grid> <Ellipse Fill="Orange" Width="400" Height="400" Name="BackEllipse"/> <Canvas x:Name="MainCanvas" Width="{Binding Width,ElementName=BackEllipse}" Height="{Binding Height,ElementName=BackEllipse}"/> </Grid>
後臺程式碼
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DoDraw(); } private void DoDraw() { double radius = BackEllipse.Width / 2; double min = 0; double max = 100; double step = 360.0 / (max - min); for (int i = 0; i < max - min; i++) { Line lineScale = new Line { X1 = ((radius - 20) * Math.Cos(i * step * Math.PI / 180)) + radius, Y1 = ((radius - 20) * Math.Sin(i * step * Math.PI / 180)) + radius, X2 = (radius * Math.Cos(i * step * Math.PI / 180)) + radius, Y2 = (radius * Math.Sin(i * step * Math.PI / 180)) + radius, Stroke = Brushes.Red, StrokeThickness = 2 }; MainCanvas.Children.Add(lineScale); } } }