[Drawkit] Scaling issues

Graham Cox graham.cox at bigpond.com
Fri May 23 18:35:12 PDT 2008


On 24 May 2008, at 10:47 am, Graham Cox wrote:

> nce the linewidth can be set independently of actually constructing  
> the grid cache it would be easy to set this on the fly taking into  
> account the zoom without invalidating the cache itself. I'll have a  
> look at that this morning.


I modified the grid to use the following code in its -drawRect:inView:  
method. It prevents the drawn line width from exceeding 1 pixel but  
does so in a way that comes into force smoothly as you zoom. Other  
things I tried caused abrupt changes in the appearance of the grid  
which I didn't like. I also don't bother drawing the finest part of  
the grid when zoomed out more than a factor of 2 - at that scale you  
can't see this part of the grid so no point drawing it.

Give this a try and see how it works for your situation. I have tried  
it with a zoom range from 0.025 to 250x (10000:1) and I find it  
acceptable (at very high zooms the span and divs lines become hard to  
tell apart but I don't think that's a big problem). I do also notice a  
very slight rounding error misalignment at maximum zoom (the ruler  
mark and the span line are misaligned by a couple of pixels). I think  
this is just hitting the limits of precision of a floating point  
value, so there may be nothing that can be done about it.

You need to #import DKDrawKitMacros.h to get the LIMIT macro.

		else
		{
			// draw directly from the cache. Apply the linewidth accounting for  
the view's scale factor
			
			float zoom = [aView scale];
			float dlw, slw, mlw;
			
			dlw = LIMIT( m_divisionLineWidth / zoom, 0.05, 1.0 );
			slw = MIN( m_spanLineWidth / zoom, 1.0 );
			mlw = MIN( m_majorLineWidth / zoom, 1.0 );
			
			// make sure the actual drawn line width can't exceed 1 pixel
				
			if ( zoom * slw > 1.0 )
				slw = 0;

			if ( zoom * mlw > 1.0 )
				mlw = 0;
			
			[m_spanCache setLineWidth:slw];
			[m_majorsCache setLineWidth:mlw];
			
			// don't draw the smallest divisions at all if we are zoomed out  
more than 0.5 - you can't
			// see them anyway so no point spending time drawing them
			
			if ( zoom >= 0.5 )
			{
				if ( zoom * dlw > 1.0 )
					dlw = 0;
				
				[m_divsCache setLineWidth:dlw];
				[m_divisionColour setStroke];
				[m_divsCache stroke];
			}
			[m_spanColour setStroke];
			[m_spanCache stroke];
			[m_majorColour setStroke];
			[m_majorsCache stroke];
		}


cheers, Graham


More information about the Drawkit mailing list