【问题标题】:Can we create 3D graph in 4 quadrants in C#.NET winform?我们可以在 C#.NET winform 的 4 个象限中创建 3D 图形吗?
【发布时间】:2018-09-27 05:51:31
【问题描述】:

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

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

下面是对应的代码:

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);
        }
    }

我希望我的 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);
    }

【问题讨论】:

  • 由于您的某些数据为负数,因此自动坐标轴也会出现在那里。您始终可以将其最小值设置为0扩展到 4 象限形式 是什么意思?
  • 我已经更新了这个问题。该图最终应如上图所示。这可以在 C#.NET 中完成吗?
  • 更准确地说我想在3D笛卡尔坐标系中显示图形。

标签: c# .net winforms charts


【解决方案1】:

您可以通过将两个轴移动到中间来轻松地设置图表的样式;这是通过设置他们的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;

请注意,MSChart 在 3d 模式下的真正问题始终是 z 轴,因为真的没有。 (如果有人对如何通过大量系列来模拟它感兴趣,请参阅here。我的示例使用 32 系列..)

您可以自己绘制,使用内置函数进行 3d 转换 (TransformPoints),但这是一项繁琐的工作,尤其是在标签方面..

【讨论】:

  • 这就是我想要的。我将更新代码 n 检查。
  • 我在`prepare3dChart()`中更新了这段代码。现在我正在 3D 笛卡尔系统中获取图形。
【解决方案2】:

更新后的代码:

  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);
    }

【讨论】:

  • 不确定这是否应该是一个答案,因为它主要是复制我的代码。也许将最终代码添加到您的问题中会更合适..?
  • 评论中没有上传图片的选项。所以我在“答案”中上传了最终代码。
  • 我的意思是用代码和最终图像更新问题.. 1+ 问题,尽管所有困难的东西都已经到位。 (来自不久前的一些code I wrote ;-)
  • 我的一位同事使用了您的代码。我问他(过去式。 :)
猜你喜欢
  • 2011-05-19
  • 1970-01-01
  • 2014-08-28
  • 2019-01-28
  • 1970-01-01
  • 2010-10-25
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多