関数のグラフ

前回線分・折れ線で折れ線の描き方を確認したので、今回はその応用として関数のグラフを描く。

準備

最初から用意されているGridにgrid1という名前を付ける。 詳細はこちら.

注:次のプログラムでは、usingディレクティブと名前空間は省略しているので、その部分は適宜補う必要がある。

グラフ

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Canvas canvas1 = new Canvas();
        grid1.Children.Add(canvas1);
        Graph graph = new Graph();
        graph.Origin = new Point(400, 200);
        graph.Scale = 30;
        graph.MainCanvas = canvas1;
        graph.SetPoints(x => Math.Sin(x), -10, 10);
        graph.Draw(Brushes.Blue);
        graph.DrawAxis(-10, 10, -2, 2, Brushes.Gray);
    }
}
class Graph
{
    public Point Origin;
    public Canvas MainCanvas;
    public double Scale;
    public Point[] Points;
    public int N = 500;
    public void ClearCanvas() { MainCanvas.Children.Clear(); }
    public void SetPoints(Func<double, double> f, double x1, double x2)
    {
        Points = Enumerable.Range(0, N + 1).Select(i => x1 + i * (x2 - x1) / N).
            Select(x => new Point(x, f(x))).ToArray();
    }
    public void Draw(Brush brush)
    {
        var points2 = Points.Select(p => new Point(Origin.X + Scale * p.X, Origin.Y - Scale * p.Y));
        Polyline polyline = new Polyline();
        PointCollection pointC = new PointCollection();
        foreach (var item in points2) { pointC.Add(item); }
        polyline.Points = pointC;
        polyline.Stroke = brush; // 線の色
        polyline.StrokeThickness = 1; // 線の太さ
        MainCanvas.Children.Add(polyline);
    }
    public void DrawAxis(double x1, double x2, double y1, double y2, Brush brush)
    {
        Line xAxis = new Line();
        Line yAxis = new Line();
        xAxis.X1 = Origin.X + x1 * Scale;
        xAxis.Y1 = Origin.Y;
        xAxis.X2 = Origin.X + x2 * Scale;
        xAxis.Y2 = Origin.Y;
        yAxis.Y1 = Origin.Y - y1 * Scale;
        yAxis.X1 = Origin.X;
        yAxis.Y2 = Origin.Y - y2 * Scale;
        yAxis.X2 = Origin.X;
        xAxis.Stroke = brush;
        yAxis.Stroke = brush;
        MainCanvas.Children.Add(xAxis);
        MainCanvas.Children.Add(yAxis);
    }
}

実行結果.

解説

Graphクラスは、描きたい関数のグラフを、折れ線として近似して指定したキャンバスに描画する。 折れ線の代表点(頂点)はSetPointsで指定するが、分割数は「N」で初期値は500としている。 Drawメソッドによって、実際にキャンバスに描画が行われる。 DrawAxisはx軸とy軸を描くもので、引数は5個。

DrawAxis(x軸の左端の位置,x軸の右端の位置,y軸下端の位置,y軸上端の位置,色)

となっている。 複数のグラフを描きたい場合は、SetPointsとDrawメソッドをくりかえせば良い。

関数fのグラフを描くには、代表点としては \[(x_k,f(x_k))\] を取れば良く、SetPointsではその処理を行っている。

WPFでは下側がyの正の向きであることに注意が必要である。 また、Scaleによって拡大・縮小もしたいので、最終的にグラフを描くには、ちょっとした変換が必要になる。 この変換はSetPointsではなく、Drawメソッドの中で行っている。