Zooming smoothly

BlitzMax Forums/BlitzMax Programming/Zooming smoothly

I am trying to smoothly zoom into a portion of the screen over a given number of frames. For example, suppose the screen is 800x600 and I want to zoom in so that 150,150 to 170,170 now fills the screen, but I want it to zoom in gradually over several frames.
Problem is, if I do it linearly, it will appear to speed up as I get closer to the portion of the screen I'm zooming into. I also tried using a sine function to taper off the zoom, which made things a little better, but was still getting a speedup toward the end.
Here is a sample zooming in on the x on the screen using both linear zooming and sine zooming. As you can see, both versions visually speed up toward the end and isn't consistent across the entire zoom range.
SuperStrict

Graphics 800,600
'start out with the virtual coordinates at a 1:1 with the actual screen coordinates
Global ZX1:Double = 0 'Coordinate on left edge of screen
Global ZY1:Double = 0 'coordinate at to
Global ZX2:Double = 799 'coordinate at right
Global ZY2:Double = 599 'coordinate at bottom

While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
	Cls
	Line 150,150,170,170
	line 150,170,170,150
	DrawText "Press L for linear zoom",10,500
	DrawText "Press S for Sine zoom",10,520
	Flip
	If KeyHit(KEY_L) Then LinearZoom(150,150,170,170)
	If KeyHit(KEY_S) Then SineZoom(150,150,170,170)
Wend

'plots a line on the screen using virtual coordinates
Function Line(x1:Double,y1:Double,x2:Double,y2:Double)
	Local rx1:Int = (x1-ZX1)*800/(ZX2-ZX1) 'convert the virtual coordinates to screen coordinates
	Local rx2:Int = (x2-ZX1)*800/(ZX2-ZX1)
	Local ry1:Int = (y1-ZY1)*600/(ZY2-ZY1)
	Local ry2:Int = (y2-ZY1)*600/(ZY2-ZY1)

	DrawLine rx1,ry1,rx2,ry2
End Function

Function LinearZoom(ex1:Double,ey1:Double,ex2:Double,ey2:Double)
	Local sx1:Double = ZX1
	Local sx2:Double = ZX2
	Local sy1:Double = ZY1
	Local sy2:Double = ZY2
	
	For Local i:Int = 0 To 300
		Local Percent:Double = Double(i)/Double(300)
		ZX1 = ex1*Percent
		ZY1 = ey1*Percent
		ZX2 = (ex2-sx2)*Percent+sx2
		ZY2 = (ey2-sy2)*Percent+sy2
		Cls
		line(150,150,170,170)
		line(150,170,170,150)
		Flip
	Next
	WaitKey()
	ZX1 = 0
	ZX2 = 799
	ZY1 = 0
	ZY2 = 599
End Function

Function SineZoom(ex1:Double,ey1:Double,ex2:Double,ey2:Double)
	Local sx1:Double = ZX1
	Local sx2:Double = ZX2
	Local sy1:Double = ZY1
	Local sy2:Double = ZY2
	
	For Local i:Int = 0 To 300
		Local Time:Double = Double(i)/Double(300)
		Local Percent:Double = Sin(Time*Double(90))
		ZX1 = ex1*Percent
		ZY1 = ey1*Percent
		ZX2 = (ex2-sx2)*Percent+sx2
		ZY2 = (ey2-sy2)*Percent+sy2
		Cls
		line(150,150,170,170)
		line(150,170,170,150)
		Flip
	Next
	WaitKey()
	ZX1 = 0
	ZX2 = 799
	ZY1 = 0
	ZY2 = 599
End Function