【问题标题】:Graphic transformations图形转换
【发布时间】:2015-12-20 04:12:28
【问题描述】:

我正在处理以 M 频率重复的数据(如正弦波/余弦波等)。 我编写了一个简单的显示控件,它获取数据并绘制连接线以在漂亮的图片中表示数据。

我的问题是,如果将数据绘制到位图上,则给出的数据是象限 1 的数据在象限 3 中,而象限 2 的数据在象限 4 中(反之亦然)。

位图宽度为M,高度为array.Max - array.Min

是否有一个简单的转换来改变数据,使其显示在适当的象限中?

【问题讨论】:

    标签: c# graphics


    【解决方案1】:

    一个很好的思考方式是世界坐标中的(0,0)被划分为

    (0,0), (width, 0), (0,height), (width, height)

    图像坐标中的 (width/2, height/2)。

    从那里,转换将是:

    Data(x,y) => x = ABS(x - (width/2)), y = ABS(y - (Height/2))
    

    【讨论】:

      【解决方案2】:

      Graphics.ScaleTransform 不是一个好主意,因为它不仅会影响布局,还会影响绘图本身(笔触、文本的粗细等)。

      我建议您准备点列表,然后使用 Matrix 类对其进行转换。这是我为您制作的一个小例子,希望对您有所帮助。

          private PointF[] sourcePoints = GenerateFunctionPoints();
      
          protected override void OnPaint(PaintEventArgs e)
          {
              base.OnPaint(e);
      
              e.Graphics.Clear(Color.Black);
      
              // Wee need to perform transformation on a copy of a points array.
              PointF[] points = (PointF[])sourcePoints.Clone();
      
              // The way to calculate width and height of our drawing.
              // Of course this operation may be performed outside this method for better performance.
              float drawingWidth = points.Max(p => p.X) - points.Min(p => p.X);
              float drawingHeight = points.Max(p => p.Y) - points.Min(p => p.Y);
      
              // Calculate the scale aspect we need to apply to points.
              float scaleAspect = Math.Min(ClientSize.Width / drawingWidth, ClientSize.Height / drawingHeight);
      
              // This matrix transofrmation allow us to scale and translate points so the (0,0) point will be
              // in the center of the screen. X and Y axis will be scaled to fit the drawing on the screen.
              // Also the Y axis will be inverted.
              Matrix matrix = new Matrix();
              matrix.Scale(scaleAspect, -scaleAspect);
              matrix.Translate(drawingWidth / 2, -drawingHeight / 2);
      
              // Perform a transformation and draw curve using out points.
              matrix.TransformPoints(points);
              e.Graphics.DrawCurve(Pens.Green, points);
          }
      
          private static PointF[] GenerateFunctionPoints()
          {
              List<PointF> result = new List<PointF>();
      
              for (double x = -Math.PI; x < Math.PI; x = x + 0.1)
              {
                  double y = Math.Sin(x);
                  result.Add(new PointF((float)x, (float)y));
              }
      
              return result.ToArray();
          }
      
          protected override void OnSizeChanged(EventArgs e)
          {
              base.OnSizeChanged(e);
              Invalidate();
          }
      

      【讨论】:

      • 谢谢您,您在哪里找到了 Matrix 数据集?
      • 不好意思,我忘了说,你需要导入命名空间 System.Drawing.Drawing2D
      【解决方案3】:

      尝试使用反转 y 轴

      g.ScaleTransform(1, -1);
      

      【讨论】:

      • 我不熟悉 ScaleTransform。我会调查的。如果我能提升你,我会的!但我需要 x 和 y 轴。乔在解释方面做得比我好
      【解决方案4】:

      还请记住,对于在缩放的上下文中绘图,如果必须,Pen 例如在其某些构造函数中将宽度作为 Single,这意味着可以使用反比例的小数值来对 ScaleTransform 的效果进行不变的补偿。

      更新:忘记了,Pen 有自己的本地 ScaleTransform,所以 x 和 y 都可以补偿。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-15
        • 2013-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-08
        • 1970-01-01
        • 2020-05-02
        相关资源
        最近更新 更多