Here's some ancient B2D code, should be easy enough to adapt for your needs...
;**************************************************************************************************
;***** Rotazooming - vomit inducing - YAN 2001
;**************************************************************************************************
Graphics 640,480
source_image = LoadImage("phsyc.png") ; a 128x128 pixel image
rot_image = CreateImage(160, 160)
Dim sint#(359), cost#(359)
For t=0 To 359
sint#(t) = Sin(t)
cost#(t) = Cos(t)
Next
SetBuffer BackBuffer()
a = 0 : s# = 0 : tx# = 0 : ty# = 0
Repeat
fast_rotateflt(source_image, 128, 128, 64, 64, rot_image, 156, 156, cost#(a)*80, sint#(a)*160, a, s#)
TileBlock rot_image, tx#, ty#
Flip
a = (a + 1) Mod 360
s# = Abs(cost#(a)) + 0.4
tx# = cost#(a) * 160
ty# = sint#(a) * 160
Until KeyDown(1)
End
;
Function fast_rotateflt(src_image, src_w, src_h, src_cx, src_cy, dst_image, dst_w, dst_h, dst_cx, dst_cy, angle, scale#)
;src_w & src_h MUST be powers of 2 : 2,4,8,16,32...etc
ducol# = sint#(angle) * (1 / scale#)
dvcol# = cost#(angle) * (1 / scale#)
durow# = dvcol#
dvrow# = -ducol#
rowu# = src_cx - ((dst_cx * dvcol#) + (dst_cy * ducol#))
rowv# = src_cy - ((dst_cx * dvrow#) + (dst_cy * durow#))
src_buff = ImageBuffer(src_image)
dst_buff = ImageBuffer(dst_image)
src_h = src_h - 1
src_w = src_w - 1
dst_h = dst_h - 1
dst_w = dst_w - 1
LockBuffer(ImageBuffer(src_image))
LockBuffer(ImageBuffer(dst_image))
For y=0 To dst_h
u# = rowu#
v# = rowv#
For x=0 To dst_w
CopyPixelFast (u# And src_w), (v# And src_h), src_buff, x, y, dst_buff
u# = u# + durow#
v# = v# + dvrow#
Next
rowu# = rowu# + ducol#
rowv# = rowv# + dvcol#
Next
UnlockBuffer(ImageBuffer(src_image))
UnlockBuffer(ImageBuffer(dst_image))
End Function
;Original C routine By Steven M Mortimer
;
;void FastRotate(
; WORD *pDstBase, Int dstW, Int dstH, Int dstDelta,
; WORD *pSrcBase, Int srcW, Int srcH, Int srcDelta,
; Float fDstCX, Float fDstCY,
; Float fSrcCX, Float fSrcCY,
; Float fAngle, Float fScale)
;{
; srcDelta /= sizeof(WORD);
; dstDelta /= sizeof(WORD);
; Float duCol = (Float)Sin(-fAngle) * (1.0f / fScale);
; Float dvCol = (Float)Cos(-fAngle) * (1.0f / fScale);
; Float duRow = dvCol;
; Float dvRow = -duCol;
; Float startingu = fSrcCX - (fDstCX * dvCol + fDstCY * duCol);
; Float startingv = fSrcCY - (fDstCX * dvRow + fDstCY * duRow);
; Float rowu = startingu;
; Float rowv = startingv;
; For(Int y = 0; y < dstH; y++)
; {
; Float u = rowu;
; Float v = rowv;
;
; WORD *pDst = pDstBase + (dstDelta * y);
; For(Int x = 0; x < dstW ; x++)
; {
; WORD *pSrc = pSrcBase + (((Int)u) & srcW-1) +
; ((((Int)v) & srcH-1) * srcDelta );
; *pDst++ = *pSrc++;
; u += duRow;
; v += dvRow;
; }
; rowu += duCol;
; rowv += dvCol;
; }
;