473,386 Members | 1,745 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

How to paint continual lines without repainting the first lines ?

4
In my program, the background is a map, and the map has 100 grids on it.. the user inserts coordinates and a number and the program paints a dot in the coordinates provided by the user, if the user inserts another coordinates with the same number provided earlier, the program paints another dot and connects the previous one with the new one.

A few users will insert coordinates so the program will be a bit busy painting all the lines and dots all over again and the screen will flash because of all the map, grids, dots and lines painted all over again.

Is there a way to have a picture box for each line (by line I mean, the "number" that the user inserted the has all the coordinates) ? I tried adding transparent pictureboxes but it's white and not transparent.


Thanks,
Guy.
Feb 3 '11 #1
9 3043
GaryTexmo
1,501 Expert 1GB
I don't know the details about your program too well so I'll throw about some suggestions and you can take them as you please :)

* I believe you can directly control when the panel gets redrawn. You could try only drawing when something changes (ie, a coordinate is placed on it) or the window itself needs to refresh. I know you can directly control how the background gets drawn but I'm not sure how to do it. You can look into it though.

* If your map doesn't scale, rotate, or scroll, why not just use a static bitmap for the grid? Now you're looking at a single paint instead of 100 for the grid lines. Even if you have to scroll/scale there are tricks you can do with an oversized bitmap and sneaky positioning.

* Windows should only redraw automatically when it decides a paint is needed. If you're not animating, just let it go ahead and do it's thing. 100 lines isn't terribly much... you mentioned several users might be involved but it's still drawing on a single client per user, so it shouldn't be a big deal. Windows paint should be able to handle that kind of grid without issue.

* Consider switching to a platform more appropriate to heavy drawing. You can embed an XNA control on a form and my own tests on a machine I bought 4 years ago had me quite happily able to draw 22 000 "objects" (sprites, lines, whatever) per cycle before I started to dip below the refresh rate cap (60 Hz).
Feb 3 '11 #2
GuyM
4
Here's an example:
A user type number 12 and grid 34 so the program paints a point in grid 34 with the number 12 (the program uses a dictionary and stacks to store it), then, the user inserts the number 12 again but now grid 35 so the program paints a dot in 35 and connects it with a line to the previous dot. Lets say that a few more dots and lines are painted and now the user inserts a number with grid zero which means he want to remove the lines and dots of this number, now the program needs to clear the whole screen and paint the remaining lines. So I need a way to paint each number and it's lines seperatly.
Feb 3 '11 #3
GaryTexmo
1,501 Expert 1GB
Any of the above suggestions should work... I think the real question here is, are you experiencing a slow down? If you're not, keep going as you are. I wouldn't think painting 100 extra lines for the grid would be overly taxing on GDI+... if it's an issue of flicker you should probably investigate double buffering so you're not watching everything draw.

If it really is slow, and your grid is static (ie, will never change in any way) just draw it as a background image.

Finally, as I mentioned, maybe look into XNA. This would be ideal if you wanted your map to scale, zoom, or perhaps rotate. GDI+ isn't exactly known for its drawing efficiency.
Feb 3 '11 #4
GuyM
4
My map isn't rotating or scaling, it's static, and the grids are too, so I only need to redraw everything when the user inserts a coordinate and a number, but it happens 6-12 times in a minute, I don't want the program to repaint the whole lines and dots because the amount will be very high in some point (about 50 lines) and repainting 50 lines every 5 seconds will be hard. I want a different painting block for each number and its lines, can I create a transparent panel for each one ? Will it work ?

Thanks :)
Feb 4 '11 #5
GaryTexmo
1,501 Expert 1GB
Layering controls is actually a lot more expensive than just drawing the line. I'd recommend just having a single panel and doing all your painting on that. I just ran some tests, GDI+ handles that many lines quite easily and I had my repaint running in a 60 fps redraw loop using a timer to invalidate the form.

You should be able to just drop down a single control (panel) as a "canvas", or even draw on your main form itself depending on how you want to organize things.

Here's a rudimentary grid drawing on a form... if you port this code into a project to run it, you'll see that it's quite happy to draw this many lines.

Expand|Select|Wrap|Line Numbers
  1.     public partial class Form1 : Form
  2.     {
  3.         private const int FRAMES_PER_SECOND = 60;
  4.         private const int GRID_SPACING = 5;
  5.         private const int MAJOR_LINE_X = 10;
  6.         private const int MAJOR_LINE_Y = 10;
  7.  
  8.  
  9.         private Timer m_timer = new Timer();
  10.  
  11.         public Form1()
  12.         {
  13.             InitializeComponent();
  14.  
  15.             m_timer.Interval = (int)(1000.0 * (1.0 / FRAMES_PER_SECOND));
  16.             m_timer.Tick += new EventHandler(m_timer_Tick);
  17.             this.Width = 640;
  18.             this.Height = 480;
  19.         }
  20.  
  21.         void m_timer_Tick(object sender, EventArgs e)
  22.         {
  23.             this.Invalidate();
  24.         }
  25.  
  26.         protected override void OnPaint(PaintEventArgs e)
  27.         {
  28.             base.OnPaint(e);
  29.  
  30.             Color drawColor = Color.DarkGray;
  31.             Graphics g = e.Graphics;
  32.             for (int x = 0; x < Math.Ceiling(this.Width / (double)GRID_SPACING); x++)
  33.             {
  34.                 drawColor = (x % MAJOR_LINE_X == 0) ? Color.Black : Color.DarkGray;
  35.                 g.DrawLine(new Pen(drawColor), x * GRID_SPACING, this.ClientRectangle.Top, x * GRID_SPACING, this.ClientRectangle.Bottom);
  36.             }
  37.  
  38.             for (int y = 0; y < Math.Ceiling(this.Height / (double)GRID_SPACING); y++)
  39.             {
  40.                 drawColor = (y % MAJOR_LINE_Y == 0) ? Color.Black : Color.DarkGray;
  41.                 g.DrawLine(new Pen(drawColor), this.ClientRectangle.Left, y * GRID_SPACING, this.ClientRectangle.Right, y * GRID_SPACING);
  42.             }
  43.         }
  44.     }
You could quite easily do something like this in your own code, but perhaps your paint method would look something like..

Expand|Select|Wrap|Line Numbers
  1. protected override void OnPaint(PaintEventArgs e)
  2. {
  3.   PaintGrid(e);
  4.   PaintPoints(e);
  5.   PaintConnectorLines(e);
  6. }
Feb 4 '11 #6
GuyM
4
Yes, it looks like the second code you wrote.
I have a drawAll method that draws everything, first the grids, then all tracks (a number is actually a track, so it paints a number and all of his lines and dots and then go to the next number).

So I should set the map image as the form background and paint the grids on the form, and then the painting will be on the transparent panel ?
Feb 4 '11 #7
GaryTexmo
1,501 Expert 1GB
Ok, so if you're using code similar to what I wrote, why are you experiencing such poor performance? Feel free to play with it on your side, but I cranked that up so it was drawing at least 500 lines and had no issues at all.

Anyway, you don't need to use a transparent panel, just draw in the correct order. You can use Graphics.DrawImage(...) to draw the background bitmap. There's no reason to draw to more than one control here.
Feb 4 '11 #8
GaryTexmo
1,501 Expert 1GB
Oh, duh... in my example I forgot to start the timer haha. Yes, it flickers to hell, but it's 'cause you get to watch it draw constantly.

I'm sorry... ugh, it would help if I gave you useful advice. Let me go take a look at this, I'm pretty sure double buffering is the answer here, I'm just not sure offhand how to do it. Check back here.
Feb 4 '11 #9
GaryTexmo
1,501 Expert 1GB
Ahh here we go, I knew it was something simple. Put this in your form's constructor...

Expand|Select|Wrap|Line Numbers
  1. SetStyle(ControlStyles.UserPaint, true);
  2. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  3. SetStyle(ControlStyles.DoubleBuffer, true);
Here's an update to the code I posted, with the timer turned on.

Expand|Select|Wrap|Line Numbers
  1.     public partial class Form1 : Form
  2.     {
  3.         private const int FRAMES_PER_SECOND = 60;
  4.         private const int GRID_SPACING = 5;
  5.         private const int MAJOR_LINE_X = 10;
  6.         private const int MAJOR_LINE_Y = 10;
  7.  
  8.         private Timer m_timer = new Timer();
  9.  
  10.         public Form1()
  11.         {
  12.             InitializeComponent();
  13.  
  14.             m_timer.Interval = (int)(1000.0 * (1.0 / FRAMES_PER_SECOND));
  15.             m_timer.Tick += new EventHandler(m_timer_Tick);
  16.             m_timer.Start();
  17.             this.Width = 640;
  18.             this.Height = 480;
  19.  
  20.             SetStyle(ControlStyles.UserPaint, true);
  21.             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  22.             SetStyle(ControlStyles.DoubleBuffer, true);
  23.         }
  24.  
  25.         void m_timer_Tick(object sender, EventArgs e)
  26.         {
  27.             this.Invalidate();
  28.             Console.WriteLine("Repainted...");
  29.         }
  30.  
  31.         protected override void OnPaint(PaintEventArgs e)
  32.         {
  33.             base.OnPaint(e);
  34.  
  35.             Color drawColor = Color.DarkGray;
  36.  
  37.             Graphics g = e.Graphics;
  38.             for (int x = 0; x < Math.Ceiling(this.Width / (double)GRID_SPACING); x++)
  39.             {
  40.                 drawColor = (x % MAJOR_LINE_X == 0) ? Color.Black : Color.DarkGray;
  41.                 g.DrawLine(new Pen(drawColor), x * GRID_SPACING, this.ClientRectangle.Top, x * GRID_SPACING, this.ClientRectangle.Bottom);
  42.             }
  43.  
  44.             for (int y = 0; y < Math.Ceiling(this.Height / (double)GRID_SPACING); y++)
  45.             {
  46.                 drawColor = (y % MAJOR_LINE_Y == 0) ? Color.Black : Color.DarkGray;
  47.                 g.DrawLine(new Pen(drawColor), this.ClientRectangle.Left, y * GRID_SPACING, this.ClientRectangle.Right, y * GRID_SPACING);
  48.             }
  49.         }
  50.     }
There we go, no flicker. Sorry about that!
Feb 4 '11 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Amy G | last post by:
I am looking to make this code a little "nicer"... any suggestions??? I want to do a "read+" where I would be able to first read the contents of the file... then either close the file out or write...
5
by: Wai Yip Tung | last post by:
When I do for line in fp: the line string usually has a '\n' at the end. In many cases I don't want the line break character. I can trim it using if line.endswith('\n'): line = line ...
1
by: Erik Jensen | last post by:
I am interested in calling Application.Run() without passing a first form as the argument to the Run method. Reason being is that i would like to instantiate some helper or foundation classes...
2
by: Murali | last post by:
Hello Everyone, I am breaking my head with this problem. Please help me out. Let me first explain my problem : Here it is: I am working in realtime environment where i will be creating...
6
by: davidgordon | last post by:
Hi, I regularly code in standard asp with MySQL. I have a page which displays records with the background colour of each record table row in a different colour. There are 2 table rows per...
1
by: booman | last post by:
Hi, I have a buffer of jpeg data which i need to pass into the IJG jpeg decompressor. This decompressor only takes FILE * (a pointer to an open file). As i am using this in an image server i need...
0
docdiesel
by: docdiesel | last post by:
Hi all, on my Linux system I got a logfile containing lines like these: ab=0;cb-ok=1;valid=1;nr=23412;txt=sometext;md5=5A4D6e342... ab=27;cb-ok=0;valid=0;nr=8754;txt=othertext;md5=3A763C5......
2
by: obkfixx | last post by:
help! how do u print a datareport without showing the datareport??? u print it automatically..... but the format n ur data report will be printed except that u dont show it.
8
by: tuananh87vn | last post by:
i'm about to use perl to read the content of a text file then write all lines in this file, except the first line, into another text file. Reading and writing file I think is ok to me, but I don't...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.