| |
Trap
Registered: Jul 2010 Posts: 223 |
2D Bitmap rotation with interpolation
Hi,
I need subject function. I've been doing some goosearching on the subject but so far I only found algorithms that do not use interpolation. So, can some kind soul please point me in the right direction?
So far I only found rotation by shearing to make interpolation but the algorithm i found is too sketchy for me to be able to convert it to something executable.
thanks
Trap |
|
... 11 posts hidden. Click here to view all posts.... |
| |
Trap
Registered: Jul 2010 Posts: 223 |
Well yes and no. I do understand the theory behind shearing and interpolation but I am not sure if this is the 'best' algorithmic approach (given that I prioritize quality over speed). |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
from the topy of my head:
work with subpixels, that is each pixel's midle is at #.5 so middle of pixel 3,5 is 3.5 and 5.5
now apply rotation keep it all nice floating point, work with pixel's middle point's!!
now after a pixel is rotated you will see how far it is off from the middle point of the pixel it fell into.
now you can use any of the usual texture filter methods to calculate the pixel's color. bilinear, anisotropic, bicubic, etc. all these methods work basically by checking how far you are off from the pixel middle point iirc. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
ok I see the problem, I guess its a good idea to rotate neighbour pixels and interpolate those according how much each falls off from the middle point of the DST pixel. |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Simple z-rotation? Quality before speed? if yes & yes:
From the top of my head:
a = angle;
// UV-vector
ux = cos(a);
uy = sin(a);
vx = -sin(a);
vy = cos(a);
// Center
cx = width/2;
cy = height/2;
for (y=0; y<height; y++) {
for (x=0; x<width; x++) {
texel = bitmap[(x-cx)*ux + (y-cy)*uy][(x-cx)*vx + (y-cy)*vy];
plot(x,y,texel);
}
}
|
| |
Mixer
Registered: Apr 2008 Posts: 452 |
If one has 2 squares, one rotated by some angle and puts them on top of each other, they overlap depending on their orientation. Assume one is source and the other is destination.
If these were grids, one destination grid square could overlap with many source grid regions depending on their orientation.
If destination pixel overlaps with many "rotated" grid pixels, what should the destination pixel color be set to? |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Well, it's basically a resampling problem.
99% of texture mapping hardware just does bilinear interpolation of the original texture (at least for the instance where there is no scaling, only rotation in the 2d plane), so all you're doing is computing for each destination pixel a fractional position in the source texture, then interpolating the colours from the four corners of the square you land in.
Photoshop defaults to using bicubic interpolation for resampling images instead, which works well for photographs but can overshoot for anything with hard edges..
Here, have some code for reading from sub-pixel locations using bilinear:
http://www.scratchapixel.com/old/lessons/3d-advanced-lessons/in..
http://rosettacode.org/wiki/Bilinear_interpolation
Replace the texel = bitmap... line from JackAsser's post above with one of the routines just linked, and there you go. |
| |
Trap
Registered: Jul 2010 Posts: 223 |
this is excellent. Thank you guys.
I will take a look at all the great info tomorrow.
/Trap |
| |
Axis/Oxyron Account closed
Registered: Apr 2007 Posts: 91 |
Basically what JackAsser said.
If you do the interpolation with floating point or fixed point with atleast 16 fraction bits, your rendering should be subpixel and subtexel correct.
In simple words: When zooming into the image, your texels build correct rotated quads without any artifacts at the texel-borders. And If you move or rotate slowly the texel-borders move smoothly and do not jump full pixel-wise.
If you are there, you need to solve the resampling problem.
There are 2 possible ways: antialias or trilinear filtering.
Antialias is very CPU-intensive, because it just means to calculate the effect in a virtual higher resolution and accumulate all the calculated sub-pixels.
The triliniear filtering approach (or gfx-card-approach) is a combination of bilinear filtering and mip-mapping.
In bilinear filtering a 2x2 array of texels around the UV texel coordinate is fetched from the texture. These 4 texel colors are then linear interpolated based on the fraction of U and V. E.g. first interpolate the 2 left and the 2 right texels based with the V-fraction and then interpolate the 2 results based on the U-fraction.
Linear interpolation just means: result=value1+(value2-value1)*fraction.
In Mip-mapping a pyramid of textures is calculated. Every next mip-map has half the resolution on both axes (E.g. 16x16, 8x8, 4x4, 2x2, 1x1). The correct mip-map is choosen from the zoom-scale. This avoids the usual flickering on zooming out.
In trilinear filtering you just do the bilinear filtering for 2 succeeding mip-maps and again linear interpolate the results based on the fraction of your mip-map choose parameter (zoom-scale). This last interpolation removes the popping that appears when switching between mip-maps.
Major drawback of this algorithm is that the resulting image gets a little bit blurry.
If you use the tools from Microsoft or NVidia to generate your mip-maps, they do some extra magic (something like a sharpening filter) to overcome that problem. |
| |
HCL
Registered: Feb 2003 Posts: 728 |
Excuse me sir, this is far off-topic from anything c-64 related. Impossible to code in 8 bits and far too many multiplications to be calculated in more than a 4x4 pixel screen.
What i'm trying to say is.. i wish i knew stuff like this, and it is very interesting reading!! Why didn't i do some 10 years in the Amiga or PC-sceen!? Then perhaps i would have known something about common computer graphics :P. Give me my life back!! ;) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
even a 060 amiga is not powerfull enough :) well, maybe a cube :) |
Previous - 1 | 2 | 3 - Next |