首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

在c#版发过了,再发一次,关于绘图,该如何解决

2013-01-11 
在c#版发过了,再发一次,关于绘图再描述一遍整个问题,有一个csv文档,里面有6万多行,姑且说是3列吧,为x,y,va

在c#版发过了,再发一次,关于绘图
再描述一遍整个问题,
有一个csv文档,里面有6万多行,
姑且说是3列吧,为x,y,value,
x,y为坐标值,value为一个数值,
需要做的是根绝这些坐标点绘图,
即绘出6万多个点,可以放大缩小,
并且鼠标移动到点上可以显示value,
先后用过gdi+绘图


            Graphics g = Graphics.FromImage(bmp);
            Pen p = new Pen(Color.Black, 1);
            g.DrawLine(p, new Point(250, 0), new Point(250, 500));
            g.DrawLine(p, new Point(0, 250), new Point(500, 250));


setpixel和上面速度差不多,也很慢,不符合。
还有内存指针法绘制
像素点

  Color c = Color.Blue;
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            int stride = bmpData.Stride;
            
            int nOffset = stride - bmp.Width * 4;
            if (stride != bmp.Width * 4)
            {
                throw new Exception("Positive, aligned stride assumption error");
            }
            unsafe
            {
                byte* buf = (byte*)bmpData.Scan0;
                foreach (DataRow dr in dt.Rows)
                {
                    int x = Convert.ToInt32(dr[0]);
                    int y = Convert.ToInt32(dr[1]);
                    if (Convert.ToDouble(dr[3].ToString()) < 2.2 && Convert.ToDouble(dr[3].ToString()) > 2.1)
                    {
                        c = Color.Black;
                    }
                    if (Convert.ToDouble(dr[3].ToString()) < 2.1 && Convert.ToDouble(dr[3].ToString()) > 1)
                    {


                        c = Color.Yellow;
                    }
                    int argb = (c.A << 24) + (c.R << 16) + (c.G << 8) + (c.B);
                    int* pixel = (int*)(buf + stride * (250- y) + (250 + x) * 4);
                    *pixel = argb;
                }

            }
            bmp.UnlockBits(bmpData);



速度是挺快,但是在放大缩小并显示出value上做不到,

手里有一款vb编写的软件有我说的这个功能,他的速度基本在10秒之内,
绘出的图放大缩小显示都很好。

如果有做过的帮个忙,没有做过的求思路。。。。


以前发过帖子
http://topic.csdn.net/u/20120821/13/fdabd214-adc6-4d92-95f5-c4a6a1d6822e.html
http://topic.csdn.net/u/20120721/09/575edf42-fcba-481c-babb-b7241f50fc10.html
http://topic.csdn.net/u/20120723/11/03afbb09-f55a-4fbf-b480-8ac0bfc4e957.html?seed=1906486480&r=79461979
[解决办法]
调用控件TEEChart的鼠标悬停显示数据功能

http://www.pudn.com/downloads330/sourcecode/windows/other/detail1451946.html
[解决办法]
无论怎么变化,最终都是用像素来显示点的,所以可以将 (x,y) 根据缩放比率换算成整数坐标。
然后将对应的 value 值存放在二维数组中,用 (x,y) 做下标进行检索非常方便。
400*300 的大小直接用 PSet 完全可以 1 秒完成绘图。
'Form1
Option Explicit

Private m_Points    As PointArray

Private Sub DrawPoints()
    Dim x           As Long
    Dim y           As Long
    Dim value       As Double
    Dim lCount      As Long
    
    Debug.Print Now(), "DrawPoints(){"
    
    Me.Cls
    With m_Points
        For x = 0 To .Width - 1
            For y = 0 To .Height - 1
            
                value = .Item(x, y)
                If (2.1 <= value) And (value < 2.2) Then
                    lCount = lCount + 1
                    Me.ForeColor = vbBlack


                    Me.PSet (x, y)
                ElseIf (1 <= value) And (value < 2.1) Then
                    lCount = lCount + 1
                    Me.ForeColor = vbYellow
                    Me.PSet (x, y)
                End If
            Next
        Next
    End With
    
    Debug.Print Now(), , "Count = " & lCount
    Debug.Print Now(), "}"
End Sub

Private Sub Form_Load()
    Set m_Points = New PointArray
    m_Points.Initialize
    
    Me.ScaleMode = vbPixels
    Me.AutoRedraw = True
    Me.BackColor = vbWhite
    DrawPoints
End Sub


[解决办法]
单线绘制十万个点无论是怎样绘制对现在的机器来说基本都是秒杀,你的速度慢应该主要是消耗在其它运算上而不是绘图上,你可以用你认为最慢的方法单纯绘制试试,c#再差也不可能像你说的一样,虽然我没用C#,所以你的精力应集中在其它操作的优化上,否则就是直接写屏也会慢;

注:g.DrawLine(p, new Point(250, 0), new Point(250, 500));
不知道你的循环中有多少类似代码,如果多简直就是灾难
无论什么语言,new对象都是要时间开消的,只new一次你可能觉得没什么问题,成千上万次时你试试能节约多少时间,多花点时间优化你的代码吧

放大缩小只是坐标系变换,移动鼠标显示值只是命中测试,都很容易实现

热点排行