首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Winforms中绘制ECG

在Winforms中绘制ECG
EN

Stack Overflow用户
提问于 2009-08-19 13:07:05
回答 4查看 5.1K关注 0票数 2

我以前没有在winforms中绘图的经验,在一个表单中我想要绘制ecg。或者假设一个正弦波或特定区域中的任何波函数,但我所做的是例如。表单的其余部分将是带有按钮和标签的普通表单,

有没有人愿意看完一篇教程

:)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-08-19 13:14:51

你有几个选择,你可以编写自己的控件,它将处理数据并呈现它。对于更复杂的图,这可能有点复杂,但基本原理总是相同的,设置X和Y值范围,然后使用GDI从左到右绘制一条线,没有什么特别的。

对于更高级的功能来说,这可能会变得有点复杂,你可以使用一些图表控件,我读过WPF post或查看codeproject.com,我记得,我看到很少有人尝试编写一些像样的图表控件,这些控件是开源的,新文章可能会用WPF编码,但你也应该找到一些更旧的东西。

编辑:

您可以找到一些有用的链接:Graph plotting lib that's main goal is to simulate ECG another graph plotting lib

票数 2
EN

Stack Overflow用户

发布于 2009-08-19 13:24:50

您需要创建自定义控件。

代码语言:javascript
运行
复制
public class MyECGDrawer : Control{}

在其中,您将重写OnPaint事件

代码语言:javascript
运行
复制
protect override OnPaint(PaintEventArgs pe ){}

然后在paint函数中,你可以按照你想要的方式来绘制图形,比如说sin(x)

代码语言:javascript
运行
复制
// refresh background
pe.Graphics.FillRectangle( Brushes.White, 0, 0, Width, Height );
int prevX = -1, prevY = -1;
for(int x = 0; x < Width; x++ )
{
    if( prevX >= 0 )
    {
        pe.Graphics.DrawLine( Pens.Black, prevX, prevY, x, Math.sin(x) );
    }
    prevX = x;
    prevY = Math.sin(x);
}

要强制重新绘制ECG,可以调用控件上的.Invalidate()函数。您应该能够从设计器中拖放窗体中的控件。

最后,这个类看起来就像

公共类控件: MyECGDrawer {}

在其中,您将重写OnPaint事件

代码语言:javascript
运行
复制
public class MyECGDrawer : Control
{
protect override OnPaint(PaintEventArgs pe )
{
   // refresh background
    pe.Graphics.FillRectangle( Brushes.White, 0, 0, Width, Height );
    int prevX = -1, prevY = -1;
    for(int x = 0; x < Width; x++ )
    {
        if( prevX >= 0 )
            pe.Graphics.DrawLine( Pens.Black, prevX, prevY, x, Math.sin(x) );
        prevX = x;
        prevY = Math.sin(x);
    }
}
}
票数 1
EN

Stack Overflow用户

发布于 2009-08-19 23:06:09

我写下了下面的代码并进行了测试。它似乎做了您想做的事情,但请注意,它只是在没有延迟的循环中绘制sin(x) -即sin(x)的绘图从左边流得如此之快,以至于你几乎看不到它。但是,您可以在循环内的任何行上放置一个断点,然后使用F5单步执行循环,以查看它的工作速度很慢-假设您的流心电信号数据只会以某个固定的速度到达,所以这在您的实现中应该不是问题。

在下面的示例中,monitor是winforms窗体上的一个PictureBox。其他的都是本地的。

代码语言:javascript
运行
复制
private void drawStream(){
  const int scaleX = 40;
  const int scaleY = 40;
  Point monitorTopLeft = new Point(0, 0);
  Point MonitorTopLeftMinus1 = new Point(-1, 0);

  int halfX = monitor.Width / 2;
  int halfY = monitor.Height / 2;
  Size size = new Size(halfX + 20, monitor.Height);

  Graphics g = monitor.CreateGraphics();
  g.TranslateTransform(halfX, halfY);
  g.ScaleTransform(scaleX, scaleY);
  g.Clear(Color.Black);
  g.ResetClip();

  float lastY = (float)Math.Sin(0);
  float y = lastY;
  Pen p = new Pen(Color.White, 0.01F);
  float stepX = 1F / scaleX;

  for (float x = 0; x < 10; x += stepX) {
    g.CopyFromScreen(monitor.PointToScreen(monitorTopLeft), MonitorTopLeftMinus1, size, CopyPixelOperation.SourceCopy);
    y = (float)Math.Sin(x);
    g.DrawLine(p, -stepX, lastY, 0, y);
    lastY = y;
  }
}

一些可能对您有帮助的其他信息:

  1. 图片框中的原点从左上角开始。TranslateTransform允许您平移(即移动)原点。在本例中,我将其转换为图片框宽度的一半,其height.
  2. ScaleTransform的另一半更改了图片框的放大倍数-请注意,它甚至放大了用于在图片框上绘制的笔的宽度-这就是为什么笔的宽度设置为0.01.
  3. CopyFromScreen执行bitblt的原因。它的源点是相对于屏幕的,目标是相对于picturebox的,要移动的矩形的大小忽略了任何变换(比如我们添加的缩放和平移变换)。
  4. 注意到DrawLine方法中的X坐标是-stepx和0。所有的绘图基本上都发生在y轴的右边(即x= 0),然后CopyFromScreen将绘制的部分向左移动,这样它就会向左“流动”。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1299816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档