[wxPython] wxDC problem

Hello,

I have a road map drawn in a wxDC and some cars in the same wxDC.
When the cars are moving, I would like to redraw only them and not the
entire map.
So I don't want to change a part of the map, but I want to have an
independant wxDC
for my cars which are moving on the map.
Do you think that what I am asking for is possible?
How can I do that?
Does the wxDC::SetClippingRegion method create an independant wxDC?

Thank you very much,
Carole.

Here is a part of my code:

···

*******************

class MapWindow(wxWindow):

#-----------------------------------------------------------------------

    def __init__(self, parent, ID_MAP, pos=wxPoint(10,10),
size=wxDefaultSize):

        EVT_PAINT(self, self.onPaint)

#-----------------------------------------------------------------------

    def onPaint(self, event):

        dc = wxPaintDC(self)
        self.drawMap(dc)

#-----------------------------------------------------------------------

    def drawMap(self, dc = None):

        dc.Clear()

        # I draw each lane of each road
        for i in range(len(self.myTerrain.roads)):
             for j in range(len(self.myTerrain.roads[i].lanes)):
                 for k in
range(len(self.myTerrain.roads[i].lanes[j].lanePointsCentral) - 1):
                      line =
self.coefZoom*self.myTerrain.roads[i].lanes[j].width
                      dc.SetPen(wxPen(wxNamedColour('grey'), line ))
                      dc.DrawLine(
self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k].x +
self.xGap ,\

self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k].y +
self.yGap ,\

self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k+1].x
+ self.xGap ,\

self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k+1].y
+ self.yGap )

        # I draw only one car for the moment
        # carCorners = [ (x1,y1), (x2,y2), (x3,y3), (x4,y4) ]
        # carCorners = each corner of the rectangle which represents the
car

        dc.SetPen(wxPen(wxNamedColour('BLACK'), 3))
        dc.DrawPolygon([ [self.coefZoom*self.myVehicle.carCorners[0][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[0][1]
+ self.yGap],\
                         [self.coefZoom*self.myVehicle.carCorners[1][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[1][1]
+ self.yGap],\
                         [self.coefZoom*self.myVehicle.carCorners[2][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[2][1]
+ self.yGap],\
                         [self.coefZoom*self.myVehicle.carCorners[3][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[3][1]
+ self.yGap] ])

My related problem was to place drag-able cursors on a graph. I didn't
want to redraw the entire graph each time the cursor moved.

I used a separate wxMemoryDC for the graph axes, data and cursors. To
re-render the window, I Blit each of these DCs to a buffer DC which is
then Blitt'ed to the screen (wxClientDC) (to avoid flicker). If the
cursors move, I only redraw the wxMemoryDC for the cursors then Blit the
three together. This all works fine provided Blitting the bitmaps is
faster than drawing individual DC elements (might not be true for large
windows).

Bryan

···

On Tue, 2002-04-23 at 16:16, Carole Valentin wrote:

Hello,

I have a road map drawn in a wxDC and some cars in the same wxDC.
When the cars are moving, I would like to redraw only them and not the
entire map.
So I don't want to change a part of the map, but I want to have an
independant wxDC
for my cars which are moving on the map.
Do you think that what I am asking for is possible?
How can I do that?
Does the wxDC::SetClippingRegion method create an independant wxDC?

Thank you very much,
Carole.

Here is a part of my code:
*******************

class MapWindow(wxWindow):

#-----------------------------------------------------------------------

    def __init__(self, parent, ID_MAP, pos=wxPoint(10,10),
size=wxDefaultSize):

        EVT_PAINT(self, self.onPaint)

#-----------------------------------------------------------------------

    def onPaint(self, event):

        dc = wxPaintDC(self)
        self.drawMap(dc)

#-----------------------------------------------------------------------

    def drawMap(self, dc = None):

        dc.Clear()

        # I draw each lane of each road
        for i in range(len(self.myTerrain.roads)):
             for j in range(len(self.myTerrain.roads[i].lanes)):
                 for k in
range(len(self.myTerrain.roads[i].lanes[j].lanePointsCentral) - 1):
                      line =
self.coefZoom*self.myTerrain.roads[i].lanes[j].width
                      dc.SetPen(wxPen(wxNamedColour('grey'), line ))
                      dc.DrawLine(
self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k].x +
self.xGap ,\

self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k].y +
self.yGap ,\

self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k+1].x
+ self.xGap ,\

self.coefZoom*self.myTerrain.roads[i].lanes[j].lanePointsCentral[k+1].y
+ self.yGap )

        # I draw only one car for the moment
        # carCorners = [ (x1,y1), (x2,y2), (x3,y3), (x4,y4) ]
        # carCorners = each corner of the rectangle which represents the
car

        dc.SetPen(wxPen(wxNamedColour('BLACK'), 3))
        dc.DrawPolygon([ [self.coefZoom*self.myVehicle.carCorners[0][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[0][1]
+ self.yGap],\
                         [self.coefZoom*self.myVehicle.carCorners[1][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[1][1]
+ self.yGap],\
                         [self.coefZoom*self.myVehicle.carCorners[2][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[2][1]
+ self.yGap],\
                         [self.coefZoom*self.myVehicle.carCorners[3][0]
+ self.xGap,\
                          self.coefZoom*self.myVehicle.carCorners[3][1]
+ self.yGap] ])

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwindows.org
http://lists.wxwindows.org/mailman/listinfo/wxpython-users

--
Bryan Cole
Teraview Ltd., 302-304 Cambridge Science Park, Milton Road, Cambridge
CB4 0WG, United Kingdom.
tel: +44 (1223) 435380 / 435386 (direct-dial) fax: +44 (1223) 435382

I have a road map drawn in a wxDC and some cars in the same wxDC.
When the cars are moving, I would like to redraw only them and not the
entire map.
So I don't want to change a part of the map, but I want to have an
independant wxDC
for my cars which are moving on the map.
Do you think that what I am asking for is possible?
How can I do that?

Create a wxBitmap that is the size of the area you need to draw, create a
wxMemoryDC and select the bitmap into it. Then draw the section of the map
and the car into the mem dc and then Blit the bitmap into your real DC.
There are a few examples of using wxMemoryDC in the demo you can look at.

Does the wxDC::SetClippingRegion method create an independant wxDC?

No, it just prevents any drawing from happening outside the region. All
drawing opperations are "clipped" at the region boundary.

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

Robin Dunn wrote:

> I have a road map drawn in a wxDC and some cars in the same wxDC.
> When the cars are moving, I would like to redraw only them and not the
> entire map.
> So I don't want to change a part of the map, but I want to have an
> independant wxDC

Create a wxBitmap that is the size of the area you need to draw, create a
wxMemoryDC and select the bitmap into it. Then draw the section of the map
and the car into the mem dc and then Blit the bitmap into your real DC.
There are a few examples of using wxMemoryDC in the demo you can look at.

I think robin missed a step here: you want to draw the map to the
offscreen bitmap, and then each time the cars move, you can blit the map
to the ClientDC, and then draw the car onto it. That way you never have
to re-draw your map, only the cars. I've found that a blit is very
fast, so this looks very clean. Not that you want to do your drawing to
a clientDC when you are not in an OnPiant event.

I have a nifty Canvas that I have written to do pretty much what you
want. IT is an object canvas, and when you add objects, you specify
whether they are in the foreground or background. The background is not
re-drawn if it hasn't changed. It allows for some reasonably fast
animation. What is unique about it is that all objects are drawon in
Floating point coordinates, and the resulting picture can be zoomed and
scrolled around in. Also, I use it for map stuff, so it also supports a
flat-earth projection for Lat-Long coordiantes. I dpon't know if your
map is large enough scale, for that to be useful.

It can be found at:

ftp://home.orr.noaa.gov/FTP_ORR/from_orr/ChrisBarker/Float_Canvas/

If nothing else, it may give you some ideas, and there is code for all
this double buffering we are talking about.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                        
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

I think robin missed a step here:

Yep, that happens from time to time when I only spend 2-5 minutes on each
email. <wink>

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!