График уравнения в C#

private void MakeGraph()
{
        float xmin = -3;
    float xmax = 3;
    float ymin = -3;
    float ymax = 3;

        int wid = picGraph.ClientSize.Width;
    int hgt = picGraph.ClientSize.Height;
    Bitmap bm = new Bitmap(wid, hgt);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.SmoothingMode = SmoothingMode.AntiAlias;

                RectangleF rect = new RectangleF(
            xmin, ymin, xmax - xmin, ymax - ymin);
        PointF[] pts = 
        {
            new PointF(0, hgt),
            new PointF(wid, hgt),
            new PointF(0, 0),
        };
        gr.Transform = new Matrix(rect, pts);

                using (Pen graph_pen = new Pen(Color.Blue, 0))
        {
                        gr.DrawLine(graph_pen, xmin, 0, xmax, 0);
            gr.DrawLine(graph_pen, 0, ymin, 0, ymax);
            for (int x = (int)xmin; x <= xmax; x++)
            {
                gr.DrawLine(graph_pen, x, -0.1f, x, 0.1f);
            }
            for (int y = (int)ymin; y <= ymax; y++)
            {
                gr.DrawLine(graph_pen, -0.1f, y, 0.1f, y);
            }
            graph_pen.Color = Color.Red;

                        Matrix inverse = gr.Transform;
            inverse.Invert();
            PointF[] pixel_pts =
            {
                new PointF(0, 0),
                new PointF(1, 0)
            };
            inverse.TransformPoints(pixel_pts);
            float dx = pixel_pts[1].X - pixel_pts[0].X;
            dx /= 2;

                        List points = new List();
            for (float x = xmin; x <= xmax; x += dx)
            {
                bool valid_point = false;
                try
                {
                                        float y = F(x);

                                                            if (points.Count == 0) valid_point = true;
                    else
                    {
                        float dy = y - points[points.Count - 1].Y;
                        if (Math.Abs(dy / dx) < 1000)
                            valid_point = true;
                    }
                    if (valid_point) points.Add(new PointF(x, y));
                }
                catch
                {
                }

                                                if (!valid_point)
                {
                    if (points.Count > 1)
                        gr.DrawLines(graph_pen, points.ToArray());
                    points.Clear();
                }

            }

                        if (points.Count > 1)
                gr.DrawLines(graph_pen, points.ToArray());
        }
    }

        picGraph.Image = bm;
}

Этот код начинается с определения границ координат -3 & le; x & le; 3, -3 & le; y & le; 3, где он будет рисовать график. Затем код превращает Bitmap в соответствие с picGraph PictureBox программы и делает объект Graphics для рисования на Bitmap .

Далее код определяет преобразование для сопоставления границ координат с растровым изображением. Этот пример не беспокоится о том, что это искажает график. В качестве альтернативы вам может понадобиться масштабировать график, чтобы сделать координатную область максимально возможной без искажений.

Этот код устанавливает свойство Graphics объекта Transform для преобразования, которое выполняет сопоставление. Теперь код может рисовать в нормальном пространстве координат, и преобразование автоматически преобразует чертеж в преобразованную систему координат.

Затем программа создает Pen с толщиной 0. Это важно, потому что преобразование будет влиять на ручки с любой другой толщиной. Например, если преобразование масштабируется, чтобы сделать результат немного высоким и тонким, тогда он будет масштабировать ручки, чтобы сделать их более толстыми в вертикальном направлении, чем в горизонтальном направлении. Однако ручки с толщиной 0 всегда имеют ширину 1 пиксель и не преобразуются.

Код рисует оси X и Y с помощью тонкой ручки, а затем меняет цвет пера перед рисованием графика.

Чтобы сделать график гладким, программа отображает значения, где X увеличивается на 1/2 пикселя на каждом шаге. Вы можете отображать значение для каждого пикселя по горизонтали, но каждый пиксель получше дает лучший результат, когда график очень вертикальный. (Более аналитически вы можете взять производную функцию и нарисовать больше очков, когда производная будет большой и меньше, когда она будет низкой. Чтобы думать об этом по-другому, вы можете построить аналогичное количество точек на единицу длины кривой. точка на половину пикселя, кажется, дает довольно хороший результат.)

Чтобы построить точки для каждых 1/2 пикселей в направлении X, кривая делает массив размером 2 точки на расстоянии 1 пиксель. Он использует инверсию преобразования объекта Graphics для просмотра, если точки представляют точки в растровой карте, где они отображаются в координатном пространстве. Расстояние между ними указывает, как далеко друг от друга точки в пространстве координат должны быть на расстоянии 1 пиксель от Bitmap. Программа просто делит на 2, чтобы получить координатное расстояние X для половины пикселя.

Наконец, программа готова нарисовать некоторые точки. Он проходит через точки, вызывающие функцию F, чтобы получить значения Y. Если наклон между одной точкой и предыдущей является чрезвычайно крутой, программа предполагает, что это разрыв. Например, если F (x) = 1 / x, то существует разрыв в точке x = 0, так как точка немного слева является очень большим отрицательным значением, точка чуть правее - очень большое положительное значение, и функция не определена при x = 0.

Если программа не находит разрыва, она добавляет новую точку в список точек. Если программа обнаруживает разрывы, она извлекает ранее сохраненные точки и запускает новый список.

После того, как он покрыл каждое значение X в нужном диапазоне, программа рисует все точки, которые еще не нарисованы.

В следующем коде показана функция F, которую использует этот пример, но вы должны иметь возможность подключать другие уравнения без особых усилий.

// Функция для построения графика.
private float F(float x)
{
    return (float)((1 / x + 1 / (x + 1) - 2 * x * x) / 10);
}

Источник: http://csharphelper.com/blog/2016/11/graph-an-equation-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector