360 degree rotation

Discuss using and improving Lua and the Lua Player specific to the PSP.

Moderators: Shine, Insert_witty_name

Post Reply
liquid8d
Posts: 66
Joined: Thu Jun 30, 2005 6:29 am

360 degree rotation

Post by liquid8d »

Hello,

I have been looking around for something to rotate images by a certain angle. I found the stuff for flipping/inverting images, but couldn't find anything for rotating partially.

I found an algorithm which works, but when rotating there are missing/transparent pixels because of the rotation:

Code: Select all

rotatedImage = Image.createEmpty(64, 64)

function rotateImage(theImage, angle)
   centerx = (theImage:width() / 2)
   centery = (theImage:height() / 2) 
   for x = 1, theImage:width() do
      for y = 1, theImage:height() do
		 -- rotate
	      x2 = math.cos(angle) * (x - centerx) - math.sin(angle) * (y - centery) + centerx 
         y2 = math.sin(angle) * (x - centerx) + math.cos(angle) * (y - centery) + centery 
         rotatedImage:blit(x2, y2, theImage, x, y, 1, 1) 
      end
   end
   return rotatedImage
end

Any suggestions?

liquid8d
soulphalanx
Posts: 35
Joined: Mon Aug 22, 2005 7:48 am

Post by soulphalanx »

there are missing and transparent pixels because the rotated image still has to be a rectangle and that the rotated image has to fit in the initial size of the image

i hope that doesnt confuse you
liquid8d
Posts: 66
Joined: Thu Jun 30, 2005 6:29 am

Post by liquid8d »

I understand what you mean, but my missing pixels are in the center of the image... I would assume when the image is rotated, the edges would clip.. but here is what i get..

Image

it does work, but pixels are missing the more it rotates.
romero126
Posts: 200
Joined: Sat Dec 24, 2005 2:42 pm

Post by romero126 »

The reason why is because the variables after the calculation return partial values.. up +1 away from the variable..

This cannot be fixed without a huge work arround with image smoothing (which means a way to adverage a color arround the mising portion of the picture and print it out.)
User avatar
JoshDB
Posts: 87
Joined: Wed Oct 05, 2005 3:54 am

Post by JoshDB »

Not really. You find the missing variables and you mix the RGB values, i.e. missingpixelcolor=Image1R+Image2R/2, etc. etc.
romero126
Posts: 200
Joined: Sat Dec 24, 2005 2:42 pm

Post by romero126 »

Which is exactly what I just said. Pixel1 + Pixel2 / 2 is an adverage of the two pixels. But wait Theres more.. I also said adveraging pixel's arround the missing pixel To allow for Left + Right + Up + Down/4. So you have a less obvious pixel discoloration.
Ferrero
Posts: 15
Joined: Mon Dec 19, 2005 7:26 pm
Contact:

Post by Ferrero »

Another solution, is to invert your computing :

for each pixel of the destination image, find the orignal pixel. In this case you don't have blank pixels.
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

This is how normal texturemapping is done. A naive approach to rotate an image would be something like this: (not C, not LUA, but something simple)

Code: Select all

; vertical deltas
dyx = cos(a + 90 degrees) / image.width
dyy = sin(a + 90 degrees) / image.height

; horizontal deltas
dxx = cos(a) / image.width
dxy = sin(a) / image.height

yx = 0
yy = 0
for line = 0 to screen.height
 x = yx
 y = yy
 yx += dyx
 yy += dyy
 for row = 0 to screen.width
  if &#40;x >= 0&#41; && &#40;x < 1&#41; && &#40;y >= 0&#41; && &#40;y < 1&#41;
   writepixel row, line, image&#91;x * image.width&#93;&#91;y * image.height&#93;
  x += dxx
  y += dxy
This would rotate the image around the top corner and clip is so that it does not read outside the image. This is of course simplified and if you need to rotate an arbitrary image you should instead either write a proper texturemapped triangle-filler or use the GE to do your dirty-work, since this is what it's really good at.
GE Dominator
Julu Julu
Posts: 9
Joined: Tue Nov 01, 2005 8:57 am
Location: Germany

Post by Julu Julu »

Hi.

I wrote this code here.
It is not fast.
Perhaps, someone can make it fast. :)

Code: Select all

System.usbDiskModeActivate&#40;&#41;
red = Color.new&#40;255, 0, 0&#41;

background = Image.load&#40;"backgr.png"&#41;
testImage= Image.load&#40;"testImage.png"&#41;

rotate = 0

function newDraw&#40;xV,yV,imageV,angleV&#41;
local angle = angleV
local centerx = math.floor&#40;&#40;imageV&#58;width&#40;&#41;/2&#41;+0.5&#41;
local centery = math.floor&#40;&#40;imageV&#58;height&#40;&#41;/2&#41;+0.5&#41;
local b = 0
local a = 0
local tx = 0
local ty = 0

	for b=0, imageV&#58;width&#40;&#41;-1 do	
		for a=0, imageV&#58;height&#40;&#41;-1 do
			tx = &#40;b-centerx&#41;*math.cos&#40;angle*&#40;math.pi/180&#41;&#41; + &#40;a-centery&#41;*math.sin&#40;angle*&#40;math.pi/180&#41;&#41;+centerx
			ty = -&#40;b-centerx&#41;*math.sin&#40;angle*&#40;math.pi/180&#41;&#41; + &#40;a-centery&#41;*math.cos&#40;angle*&#40;math.pi/180&#41;&#41;+centery			
			
			if tx >0 and ty>0 and tx < imageV&#58;width&#40;&#41; and ty < imageV&#58;height&#40;&#41; then
				color = imageV&#58;pixel&#40;tx,ty&#41;
				getColor = color&#58;colors&#40;&#41;
			end			
			
			if getColor ~= nil then
				newColor= Color.new&#40;getColor.r, getColor.g, getColor.b, getColor.a&#41;
				screen&#58;pixel&#40;b+xV,a+yV,newColor&#41;
			end
		end
	end
end



while true do
	pad = Controls.read&#40;&#41;
	
	screen&#58;blit&#40;0, 0, background, 0, 0, background&#58;width&#40;&#41;, background&#58;height&#40;&#41;, false&#41;	
	newDraw&#40;&#40;screen&#58;width&#40;&#41;/2&#41;-&#40;testImage&#58;width&#40;&#41;/2&#41;,&#40;screen&#58;height&#40;&#41;/2&#41;-&#40;testImage&#58;height&#40;&#41;/2&#41;,testImage,rotate&#41;
	
	if pad&#58;right&#40;&#41; then
		rotate = rotate + 5
	end	
	
	if pad&#58;left&#40;&#41; then
		rotate = rotate - 5
	end

	if pad&#58;start&#40;&#41; then
		break
	end	
	
	screen.flip&#40;&#41;
	screen.waitVblankStart&#40;&#41;
end


Post Reply