| View previous topic :: View next topic |
| Author |
Message |
liquid8d
Joined: 30 Jun 2005 Posts: 66
|
Posted: Tue Jan 03, 2006 3:42 am Post subject: 360 degree rotation |
|
|
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: |
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 |
|
| Back to top |
|
 |
soulphalanx
Joined: 22 Aug 2005 Posts: 35
|
Posted: Tue Jan 03, 2006 4:13 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
liquid8d
Joined: 30 Jun 2005 Posts: 66
|
Posted: Tue Jan 03, 2006 11:26 am Post subject: |
|
|
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..
it does work, but pixels are missing the more it rotates. |
|
| Back to top |
|
 |
romero126
Joined: 24 Dec 2005 Posts: 200
|
Posted: Tue Jan 03, 2006 12:07 pm Post subject: |
|
|
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.) |
|
| Back to top |
|
 |
JoshDB

Joined: 05 Oct 2005 Posts: 87
|
Posted: Tue Jan 03, 2006 12:23 pm Post subject: |
|
|
| Not really. You find the missing variables and you mix the RGB values, i.e. missingpixelcolor=Image1R+Image2R/2, etc. etc. |
|
| Back to top |
|
 |
romero126
Joined: 24 Dec 2005 Posts: 200
|
Posted: Tue Jan 03, 2006 12:59 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
Ferrero
Joined: 19 Dec 2005 Posts: 15
|
Posted: Tue Jan 03, 2006 7:46 pm Post subject: |
|
|
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. |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Tue Jan 03, 2006 10:26 pm Post subject: |
|
|
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: |
; 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 (x >= 0) && (x < 1) && (y >= 0) && (y < 1)
writepixel row, line, image[x * image.width][y * image.height]
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 |
|
| Back to top |
|
 |
Julu Julu
Joined: 01 Nov 2005 Posts: 9 Location: Germany
|
Posted: Fri Jan 06, 2006 9:18 am Post subject: |
|
|
Hi.
I wrote this code here.
It is not fast.
Perhaps, someone can make it fast. :)
| Code: |
System.usbDiskModeActivate()
red = Color.new(255, 0, 0)
background = Image.load("backgr.png")
testImage= Image.load("testImage.png")
rotate = 0
function newDraw(xV,yV,imageV,angleV)
local angle = angleV
local centerx = math.floor((imageV:width()/2)+0.5)
local centery = math.floor((imageV:height()/2)+0.5)
local b = 0
local a = 0
local tx = 0
local ty = 0
for b=0, imageV:width()-1 do
for a=0, imageV:height()-1 do
tx = (b-centerx)*math.cos(angle*(math.pi/180)) + (a-centery)*math.sin(angle*(math.pi/180))+centerx
ty = -(b-centerx)*math.sin(angle*(math.pi/180)) + (a-centery)*math.cos(angle*(math.pi/180))+centery
if tx >0 and ty>0 and tx < imageV:width() and ty < imageV:height() then
color = imageV:pixel(tx,ty)
getColor = color:colors()
end
if getColor ~= nil then
newColor= Color.new(getColor.r, getColor.g, getColor.b, getColor.a)
screen:pixel(b+xV,a+yV,newColor)
end
end
end
end
while true do
pad = Controls.read()
screen:blit(0, 0, background, 0, 0, background:width(), background:height(), false)
newDraw((screen:width()/2)-(testImage:width()/2),(screen:height()/2)-(testImage:height()/2),testImage,rotate)
if pad:right() then
rotate = rotate + 5
end
if pad:left() then
rotate = rotate - 5
end
if pad:start() then
break
end
screen.flip()
screen.waitVblankStart()
end
|
|
|
| Back to top |
|
 |
|