我们可以在C#.NET winform的4个象限中创建3D图形吗?

use*_*587 5 .net c# charts winforms

我想在C#.NET中以4个象限形式创建一个3D Graph.对于即时,我可以如下所示.如果您看到图表的一角以(-150,-200)开头.我希望从(0,0)开始,并扩展到4象限形式.

在此输入图像描述

请告诉我如何以4象限形式转换这个3D图形?

以下是相应的代码:

void prepare3dChart(Chart chart, ChartArea ca)
    {
        ca.Area3DStyle.Enable3D = true;  
        Series s = new Series();
        chart.Series.Add(s);
        s.ChartType = SeriesChartType.Bubble;  
        s.MarkerStyle = MarkerStyle.Diamond;
        s["PixelPointWidth"] = "100";
        s["PixelPointGapDepth"] = "1";

        chart.ApplyPaletteColors();

        addTestData(chart);
    }
    void addTestData(Chart chart)
    {
        Random rnd = new Random(9);
        double x = 0, y = 0, z = 0;
        for (int i = 0; i < 100; i++)
        {
            AddXY3d(chart.Series[0], x, y, z);          
            x = Math.Sin(i / 11f) * 88 + rnd.Next(3);
            y = Math.Cos(i / 10f) * 88 + rnd.Next(5);
            z = (Math.Sqrt(i * 2f) * 88 + rnd.Next(6));
        }
    }
    int AddXY3d(Series s, double xVal, double yVal, double zVal)
    {
        int p = s.Points.AddXY(xVal, yVal, zVal);           
        s.Points[p].Color = Color.Transparent;
        return p;
    }
    private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
    {
        Chart chart = sender as Chart;

        if (chart.Series.Count < 1) return;
        if (chart.Series[0].Points.Count < 1) return;

        ChartArea ca = chart.ChartAreas[0];

        List<List<PointF>> data = new List<List<PointF>>();
        foreach (Series s in chart.Series)
            data.Add(GetPointsFrom3D(ca, s, s.Points.ToList(), e.ChartGraphics));

        renderLines(data, e.ChartGraphics.Graphics, chart, true);  
        renderPoints(data, e.ChartGraphics.Graphics, chart, 6);  
    }
    List<PointF> GetPointsFrom3D(ChartArea ca, Series s,
                         List<DataPoint> dPoints, ChartGraphics cg)
    {
        var p3t = dPoints.Select(x => new Point3D((float)ca.AxisX.ValueToPosition(x.XValue),
            (float)ca.AxisY.ValueToPosition(x.YValues[0]),
            (float)ca.AxisY.ValueToPosition(x.YValues[1]))).ToArray();
        ca.TransformPoints(p3t.ToArray());

        return p3t.Select(x => cg.GetAbsolutePoint(new PointF(x.X, x.Y))).ToList();
    }
    void renderLines(List<List<PointF>> data, Graphics graphics, Chart chart, bool curves)
    {
        for (int i = 0; i < chart.Series.Count; i++)
        {
            if (data[i].Count > 1)
                using (Pen pen = new Pen(Color.FromArgb(64, chart.Series[i].Color), 2.5f))
                    if (curves) graphics.DrawCurve(pen, data[i].ToArray());
                    else graphics.DrawLines(pen, data[i].ToArray());
        }
    }

    void renderPoints(List<List<PointF>> data, Graphics graphics, Chart chart, float width)
    {
        for (int s = 0; s < chart.Series.Count; s++)
        {
            Series S = chart.Series[s];
            for (int p = 0; p < S.Points.Count; p++)
                using (SolidBrush brush = new SolidBrush(Color.FromArgb(64, S.Color)))
                    graphics.FillEllipse(brush, data[s][p].X - width / 2,
                                         data[s][p].Y - width / 2, width, width);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我希望我的3D图形有4个象限,如下所示: 在此输入图像描述

谢谢@TaW.我得到了正确的代码.

   void prepare3dChart(Chart chart, ChartArea ca)
    {
        ca.Area3DStyle.Enable3D = true;
        ca.BackColor = Color.Transparent;

        ca.AxisX.Minimum = -300;
        ca.AxisX.Maximum = 300;
        ca.AxisY.Minimum = -300;
        ca.AxisY.Maximum = 300;

        ca.AxisX.Crossing = 0;  // move both axes..
        ca.AxisY.Crossing = 0;  // to the middle

        ca.AxisX.Interval = 50;
        ca.AxisY.Interval = 50;

        ca.AxisX.MajorGrid.LineColor = Color.LightGray;
        ca.AxisY.MajorGrid.LineColor = Color.LightGray;

        chart.Series.Clear();
        Series s = new Series();
        chart.Series.Add(s);
        s.ChartType = SeriesChartType.Bubble;  
        s.MarkerStyle = MarkerStyle.Diamond;
        s["PixelPointWidth"] = "100";
        s["PixelPointGapDepth"] = "1";

        chart.ApplyPaletteColors();

        addTestData(chart);
    }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

TaW*_*TaW 7

通过将两个轴移动到中间,您可以轻松地将图表的样式设置为这样; 这是通过设置他们的Crossings:

在此输入图像描述

使用的代码是这样的:

ChartArea ca = chart1.ChartAreas[0];

ca.BackColor = Color.Transparent;

ca.AxisX.Minimum = -300;
ca.AxisX.Maximum = 300;
ca.AxisY.Minimum = -300;
ca.AxisY.Maximum = 300;

ca.AxisX.Crossing = 0;  // move both axes..
ca.AxisY.Crossing = 0;  // to the middle

ca.AxisX.Interval = 100;
ca.AxisY.Interval = 100;

ca.AxisX.MajorGrid.LineColor = Color.LightGray;
ca.AxisY.MajorGrid.LineColor = Color.LightGray;
Run Code Online (Sandbox Code Playgroud)

请注意,在3d模式下,MSChart的真正问题始终是z轴,因为实际上没有一个.(如果有人对如何模拟它有兴趣,可以通过很多系列来看这里.我的例子使用32系列..)

您可以使用3D转换(TransformPoints)的内置函数自己绘制,但这是一项繁琐的工作,特别是在标注方面.