Using GetPixel to find edges & points for collision

qwazimoto

Active member
Joined
Oct 20, 2006
Messages
39
Programming Experience
Beginner
Hi

I am creating a program where I have to simulate people moving around an entertainment complex. The user must be able to draw the complex's floor layout, then add any objects to the layout, eg tables, gardens ect.
I feel competant enough to tackle these problems
(except the AI for the people moving around but that will be in another thread I guess).
What I would like help with is after the user has drawn an image they are happy with to be the birds eye floor layout. I need to find the walls of this layout. I have already got this working but not in a verry appropriate way (I think). So heres what im doing now.
All outlines of anything drawn will be red.
this code gets the position of all red pixels starting from left down to right down
VB.NET:
[COLOR=#008000]'declare the rectangle to get image from[/COLOR]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] rect [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] Rectangle([/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Panel1.Location.X, [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Panel1.Location.Y, [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Panel1.Width, [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Panel1.Height)[/SIZE]
 
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] pnlBMP [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Bitmap [COLOR=#008000]'Declare a bitmap[/COLOR][/SIZE]
[SIZE=2][COLOR=#008000]'"Copyrect" returns the image and applies it to pnlBMP[/COLOR][/SIZE]
[SIZE=2]pnlBMP = [/SIZE][SIZE=2][COLOR=#0000ff]CType[/COLOR][/SIZE][SIZE=2](copyRect(Panel1, [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] RectangleF(Panel1.Location.X,  [/SIZE]
[SIZE=2]                     _Panel1.Location.Y, Panel1.Width, Panel1.Height)), Bitmap).Clone[/SIZE]
 
[SIZE=2]pnlBMP.Save([/SIZE][SIZE=2][COLOR=#800000]"testimage.bmp"[/COLOR][/SIZE][SIZE=2]) [COLOR=#008000]'Save a copy of this image[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] pnts(0) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Point [COLOR=#008000]'Decalre a point array[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] x, y, count [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer = 0[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][SIZE=2] x = 1 [/SIZE][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][SIZE=2] pnlBMP.Width        [COLOR=#008000]'For each pixel on X axis[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff] For[/COLOR][/SIZE][SIZE=2] y = 1 [/SIZE][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][SIZE=2] pnlBMP.Height    [COLOR=#008000]'check all pixels on Y axis  [/COLOR][/SIZE]
 
[COLOR=#008000]    'if the pixels color = red then add its location to array[/COLOR]
[SIZE=2][COLOR=#0000ff]    If[/COLOR][/SIZE][SIZE=2] pnlBMP.GetPixel(x, y).ToArgb = Color.Red.ToArgb [/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[SIZE=2]         pnts(count) = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] Point(x, y - 1)[/SIZE]
[SIZE=2][COLOR=#0000ff]         ReDim[/COLOR][SIZE=2][COLOR=#0000ff]Preserve[/COLOR][/SIZE][SIZE=2] pnts(count)[/SIZE]
          count += 1
[/SIZE][SIZE=2][COLOR=#0000ff]    End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff] Next[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#008000]'Write the points of each red pixel to text file[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] w [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] IO.StreamWriter([/SIZE][SIZE=2][COLOR=#800000]"points.txt"[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] i [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][SIZE=2] i = 0 [/SIZE][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][SIZE=2] pnts.Length - 1[/SIZE]
[SIZE=2]w.WriteLine(pnts(i).ToString)[/SIZE]
[SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE]
[SIZE=2]w.Close()[/SIZE]

The layout will almost always be an odd shape (consisting of squares, poly's, ellipses), and these red lines that are used for walls, may not just be the outline of this image as there will usualy be walls inside the building...

All I want is a fast way to find wether a person is going to collide with a wall? but I need to know how to arrange the point array/ array's of where the walls are, in a way that can be checked fast...
A good way I think of looking at this is as if it were a maze.
Where I go from here depends on the best Idea i guess so thanks.
Im pretty blank and I appolagise if I cant be more specific but thanks in advance for any suggestions
 
Last edited:
Instead of adding the red outline points to your array of Point, add them to a GraphicsPath, also create own GP instances for walls and other objects. Then use the GP.IsVisible method to determine collisions with each obstacle. If any Point in obstacle is visible inside the 'person' Graphicspath then you have hit it. The GP is also very flexible for building the path of points from various graphics methods like lines circles and rectangles (see its method list!), and you get the full range of points from the PathPoints property when needed.

You can also improve performance by using the GP.GetBounds that return the full rectangle that contains the shape, then use these Rectangle.IntersecsWith method for very fast determintation if any shape is close to the other and needs further hit-test analyzis as outlined above.
 
Thanks

thank you verry much for that info, it solved more of my problems than I even mentioned...but more q's arise...
I will look into graphics path with great detail. But, this will require me to rethink my design upto this point(well actually Im not working to a design at this point, Im just trying anything to get a better knowledge of GDI for my real attempt which will begin with a design)

since you gave me such good advice, i have to ask more Q's. How do you think I should go about the drawing. my initial method was to use a class for rectangles, one for ellipses and one for poly's, all of which would take the appropriate args,(color ect) and the user selects the shape from tool bar, then clicks and drags to draw shape... I guess you could give me some far better ideas on how to go about this.
by the way, each class instance (shape) is added to an array, so I have a verry easy undo option... in the panels paint event i use a for each shape in shapes() and call the classes "draw" sub...

This is my first drawing app (as you may well have guessed),
thanks in advance...


BTW a good tutorial/source is worth a thousand posts.
 
Ahhh. a better way to look at it

OK...
basicaly im trying to make a simple 2d map creator, and then create an automated game that requires no user input.
each map may have multiple rooms.
no doors are needed.
I can have as many preset shapes and objects as needed, so perhaps no drawing is needed.
Or perhaps i can even use a free game engine.(not that I know of any right now)

any suggestions???
 
How do you think I should go about the drawing.
All GraphicsPath objects can easily be drawn with the Graphics.DrawPath Method or .FillPath method. So in the canvas control Paint event handler you can just do somehting like this:
VB.NET:
For Each gp As GraphicsPath in myGPobjects
 e.Graphics.DrawPath(pen, gp)
'or
 e.Graphics.FillPath(brush, gp)
Next
If objects don't move you can economize drawing operations by first drawing them to its own bitmap and use that as a background.
 
blabla

Yeah, the background thing is what i done it this way for, to reduce processing at simulation runtime.
any more suggestions?
not urgent as i havent made any attempt at the graphics path suggestion at this stage.

thanks man...:rolleyes:
do ya like my cat?
 
Back
Top