使用DrawLine C#绘制抛物线

时间:2017-02-04 17:57:18

标签: c# graph

晚上好,我在网上知道有类似的问题和一些关于它的教程,但我希望你检查我的代码并更正它。我的意思是,我想知道我的项目有什么问题。 我必须在主面板上绘制一个抛物线图。 我还必须包括两个按钮,放大和缩小,用于缩小和放大"视图"小组的观点(以及抛物线)。 我被建议使用scale var。 这是我的代码:

注意:x0,y0是panel_main x center,y center 我有x,y用于从等式中确定x,y xpc,ypc被转换为窗口比例(像素也是如此) xmin,xmax是具有一定比例的极值,留在面板上

我希望你能给我一个提示,非常感谢!

public void DisegnaParabola()
{
     Graphics gs = panel_main.CreateGraphics();
     pen.Color = Color.Black;     

    scale = (x0*2) / zoom;        //Pixels equivalent to 1x or 1y
    n_punti = (x0*2) / scale;     //Number of x math points that are visible in window
    xmin = -(n_punti / 2);                    
    xmax = n_punti / 2;                          
    precision = 1 / scale;          //Increment of x to have 1px 
    if (asse_parabola.SelectedIndex == 0)   //if Y axis
    {
        for (double i = xmin + precision; i < xmax; i += precision)
        {
            rifx = i - precision;                      //Old points 
            rifxpc = rifx * scale;
            rify = (a * Math.Pow(rifx, 2)) + b * rifx + c;
            rifypc = y0 - (rify * scale);              

            x = i;                                     //New points
            y = (a * Math.Pow(x, 2)) + b * x + c;
            ypc = y0 - (y * scale);

            gs.DrawLine(pen, (float)rifxpc, (float)rifypc, (float)xpc, (float)ypc);
        }
    }
    else
    {
        scale = (y0*2) / zoom;        //Pixels for 1y
        n_punti = (y0*2) / scale;     //Numbers of y in the window
        ymin = -(n_punti / 2);                    
        ymax = n_punti / 2;

        for(double i=ymin+precision; i<ymax; i+=precision)
        {
            rify = y - precision;
            rifypc = (y0*2) - rify * scale;
            rifx = (a * Math.Pow(rify, 2)) + b * rify + c;
            rifxpc = x0 + (rifx * scale);

            y = i;
            x = (a * Math.Pow(y, 2)) + b * y + c;
            xpc = x0 + (x * scale);

            gs.DrawLine(pen, (float)rifypc, (float)rifxpc, (float)ypc, (float)xpc); 
        }

    }

    lbl_canc.Visible = true;


}

1 个答案:

答案 0 :(得分:0)

你的问题实际上包含了几个任务,而且通常关键是将这些任务分开......

  • 有一个问题是获取数据,我会将详细信息留给您,但会展示如何从其余部分中提取数据。

  • 下一个问题是缩放数据。我将向您展示如何完全避免使用此工具并改为使用绘图工具。

  • 第三个是将它们绘制到显示表面。正如您所知,一旦其他问题得到解决,这一点非常简单。

让我们从最重要的一步开始:收集数据。您尝试在同一段代码中创建并缩放和绘制它们。这有很多缺点..

让我们首先以合适的结构收集数据:

List<PointF> points = new List<PointF>();

List<T>是大部分时间的选择集合;肯定比阵列好多了!在某些方法中,您应该使用从某个公式计算的数据填充该列表。

以下是一个例子:

List<PointF> getPoints(float start, float end, int count, float ymax)
{
    List<PointF> points = new List<PointF>();
    float deltaX = (end - start) / count;

    for (int i = 0; i < count; i++)
    {
        float x = i * deltaX;
        // insert your own formula(s) here!
        float y = ymax + (float)Math.Sin(x * somefactor) * ymax;
        points.Add(new PointF(x, y));
    }
    return points;
}

现在是第二个重要部分:如何扩展数据?这可以在创建它们时完成;但同样,将两个分开,使它们变得更加简单。

因此,这是一个函数,它不是缩放数据,而是用于绘制它们的Graphics对象:

void ScaleGraphics(Graphics g, List<PointF> data)
{
    float xmax = data.Select(x => x.X).Max();
    float ymax = data.Select(x => x.Y).Max();
    float xmin = data.Select(x => x.X).Min();
    float ymin = data.Select(x => x.Y).Min();

    float width = Math.Abs(xmax - xmin);
    float height = Math.Abs(ymax - ymin);

    var vr = g.VisibleClipBounds;

    g.ScaleTransform(vr.Width / width, vr.Height / height);
}

此方法可确保列表中的所有数据都适合绘图表面。如果要将它们限制为不同的大小,可以将其传入并相应地更改代码。

最后我们需要做实际绘图。我们应该在我们应该的地方,也就是在我们的绘图表面控制的Paint事件中......:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    if (points.Count < 2) return;  // no lines to draw, yet
    ScaleGraphics(e.Graphics, points);
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    using ( Pen pen = new Pen(Color.Blue )
          { Width = 1.5f , LineJoin = LineJoin.Round, MiterLimit = 1f} )
        e.Graphics.DrawLines(pen, points.ToArray());
}
相关问题