Link to home
Start Free TrialLog in
Avatar of arindam042099
arindam042099

asked on

Zoom In and Zoom Out

I have a drawing application which draws lines ... These are stored in array ... Now there might so happen that one might load around 36000 data points (lines) at one time ... When this happen the zoom code that I have wrote becomes very slow ... When I draw the rectangle to mark the zoom area it tries to paint all the points inside the rectangle and when I drag the rectangle on mouse move it takes a while for that rectangle to show up .... I do not want this ... When I draw the rectangle it should not paint all the points at the back over and over again when I drag the rectangle to the extend upto where I want to zoom ... How can I do that ... I have the code which draws these lines in the OnDraw function and the rectangle is also defined in Ondraw ... The application works but if I had done this 4-5 years back it would have been excellent but it is too slow for today speedy application ... Please help ... I am badly stuck ... I tried to define the rectangle in mousemove using CClientdc but when I draw the rectangle it blinks ... In mouse move I use InvalidateRect(zoomrect) ... ZoomRect is rectangle that takes all the points inside the zoomrect ... So only that part of the application gets painted next time ... Besides after zoom 2-3 times when I try to draw the rectangle all the points inside this zoom rect starts bouncing ... This looks real ugly ... I think all the problem will be solved if the points inside the rectangle does not get painted when I draw the rectangle ...
I will be happy to show the code and/or add extra points if necessary ...but i need to know how to fix it ...

thanks
Avatar of ghimireniraj
ghimireniraj

Dont
give any invalidate command in the mousemove events but instead just invalidate for example when the mouse down events occur.

Or use some kind of count technique to invalidate and call OnDraw only when for example entered ONMOUSEMOVE event for 100 times.

Use memeory dc as well

niraj
Avatar of arindam042099

ASKER

Dont
give any invalidate command in the mousemove events but instead just invalidate for example when the mouse down events occur.

NOT SURE WHAT YOU MEAN BY THOSE STATEMENTS ... DO YOU MEAN THAT I SHOULD NOT GIVE AN INVALIDATE RECT ON MOUSE DOWN ... I AM GIVING AN INVALIDATERECT ON MOUSE DOWN INSTEAD OF INVALIDATE AS IT WILL TRY TO DRAW ALL THE DATA POINTS EVEN THOSE OUTSIDE THE ZOOM RECTANGLE ... BELOW IS THE CODE I HAVE IN MOUSEMOVE
.... TELL ME ABOUT THE COUNTER ....
Please be advised that I am not an expert in Visual ...

thanks

// ******************** ZOOM MODE *****************************
  // set up the array stores the starting points for all the lines
  if (mode ==2)
  {
        if (m_bZoom == 1)
        {
// SAVING THE ZOOM RECTANGLE'S PIXEL COORDINATES
       // save pixels values
         SaveRectPixel3=(float)point.x;
         SaveRectPixel4=(float)point.y;

         // save voltage and time
       SaveRectQuantity3 = time_cal(point); // time save
       SaveRectQuantity4 = voltage_cal(point); // voltage save



            // ******** Rectangle Designation ***********
            zoom_x1 = (float)SaveRectPixel1; // top left  
            zoom_y1 = (float)SaveRectPixel4; // bottom right
            zoom_x2 = (float)SaveRectPixel3; // bottom right
            zoom_y2 = (float)SaveRectPixel2; // top left      
            tracer_zoom.SetRect((int)zoom_x1,(int)zoom_y2,(int)zoom_x2,(int)zoom_y1);

      

            //    Invalidate the rectangle
         x1_zoom00 = (float) SaveRectPixel1-(float)30.0;
         x2_zoom00 = (float) SaveRectPixel3+(float)30.0;
         y2_zoom00 = (float) SaveRectPixel2-(float)15.0;
         y1_zoom00 = (float) SaveRectPixel4+(float)15.0;

         mousezoom.SetRect((int)x1_zoom00,(int)y2_zoom00,(int)x2_zoom00,(int)y1_zoom00);
//         Invalidate();
         InvalidateRect(mousezoom);  


//      GetDC();
            CClientDC dc(this);
        OnPrepareDC(&dc);

 
//                  CPen *oldpen, lightblackpen,lightredpen;
//                  lightredpen.CreatePen(PS_SOLID,1,RGB(255,0,0));
//                  lightblackpen.CreatePen(PS_SOLID,1,RGB(0,0,0));
//                  oldpen=dc.SelectObject(&lightblackpen);

            dc.Rectangle(tracer_zoom);
            //dc.LPtoDP(tracer_zoom);
        OnDraw(&dc);
//      ReleaseDC(&dc);
         //delete dc;
//      dc.SelectObject(oldpen); // deselect the object by restoring



        }
  }// end of mode 2 zoom
// ******************** ZOOM MODE *****************************
   CView::OnMouseMove(nFlags, point);


} // end of mouse move
// ****************************************************************
ASKER CERTIFIED SOLUTION
Avatar of RONSLOW
RONSLOW

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Also, do your drawing to an off-screen bitmap and blt the whole lot on.

And you can get the dirty / clipping rectangle and do clip testing to that (many) non-visible lines don't get drawn (eg. bounding rect for the line does not intersect the clipping rect, then don't even bother trying to draw it.).
/******NOT SURE WHAT YOU MEAN BY THOSE STATEMENTS ... DO YOU MEAN THAT I SHOULD NOT GIVE AN INVALIDATE RECT ON MOUSE DOWN ... I AM GIVING AN INVALIDATERECT ON MOUSE DOWN INSTEAD OF INVALIDATE AS IT WILL TRY TO DRAW ALL THE DATA POINTS EVEN THOSE OUTSIDE THE ZOOM RECTANGLE ... BELOW IS THE CODE I HAVE IN MOUSEMOVE
..... TELL ME ABOUT THE COUNTER .... *****/


Ronslows idear might be better .. Try that as well ..


What i meant to say was your mousedown event is contionously triggered when you hold the mouse down and move it.
So there will be an iterative call to the OnDraw function. That means Drawing is going on iteratively which is making it very slow and flikering.

my count option was like this

In the class describe a variable
////////////////
int count;

/////////in your mousedown event  when ever you call invalidate do it like this

/////////////////
count++;
if((count % 100))==0)InValidateRect();
if(count==20000)count=0;
///////////////////////


See what happens

also try to use memory device context
where you draw all the time and draw to your screen  once a while

niraj


















try 50,25,10, diff values instead of 100 as well

niraj
Thanks
I did not have the time to look into it ... I will see the case that niraj suggested me tonight ... ronslow since I have not gone bitmap application I might need a little more help to decipher how to do this ... I will try the CRectTracker as well something I have not used earlier ...
I am assuming that this CRectTracker will be wrtten in MouseMove also ... as dc.CRectTracker

Thanks you all again I will evaluate the answer as soon as I get the chance to try it myself ... did not get any yet
basically, when you want to do select a rectangle (eg when you handle the mouse button down), you create a CRectTracker object and ask it to track the mouse.  It wil draw and adjust the rectangle for you until you release the mouse and then tell you what you did.

This saves you doing this manually in your own code.

Failing that, if you DO wnat to do it yourself, directly do a dc.DrawFocusRect (uses and Xor pen, so you can just draw again in the same place to erase).
Sorry to get back after a long time .. had to work on two other priority projects ... anyway I am going nuts on this and i do not understand the crecttracker and dc.DrawFocusRect very well ...
Niraj I tried your counter but i do not think it will work .. it is more of a trial and error process
what i really need is what RONSLOW suggested with CRectTracker or dc.DrawFocusRect... I tried both and I am not able to make it work because I do not fully understand how this is done

for the CRectTracker this is what I did
to my code provided above ...

ONLBDOWN
      // **** CRectTracker Code *****
         if(m_tracker.Track(this, point, FALSE, NULL))
         {
        CClientDC dc(this);
            OnPrepareDC(&dc);
                              m_tracker.Draw(&dc);

         }
inmousemove i Did NOT invalidate anymore (as i was doing in my code above)

NOTE:The rectangle is not drawn ...I obviously donot understand how to do that can you please write a small code to make this work ...

DrawFocusRect try
==================
nothing in LBDWN
in onmousemove
==============
            CClientDC dc(this);
        OnPrepareDC(&dc);


//            dc.DrawFocusRect(tracer_zoom);



When I did the above with dc.drawfocusrect it did draw the rectangle but when i scrolled down on move mouse all the rectangles positions where being displaced making the whole screen where the rectangles where resized look dirty but at the background the data points for the points were retained ... How to solve this ... Please provide me with a code ... I will increase the points accordingly but i really need to get this working soon and your help is greatly appreciated as i am at a loss

Hope you understand what I mean