need help optimising...

Started by
12 comments, last by Zahlman 18 years, 9 months ago
x2a=(int)x2;x2b=x2a+1;
y2a=(int)y2;y2b=y2a+1;



//Used for weightings
fx=x2-x2a; //So this is how far it is from an int.

fy=y2-y2a; //Same

w1=(1-fx)*(1-fy);

w2=(fx)*(1-fy);

w3=(1-fx)*(fy);

w4=(fx)*(fy);

I don't know why your doing this. Mind enlightening me? (hey, i'm optimising your code!)

As for neibouring pixels
pixel[x + 1]
pixel[x - 1]
pixel[x + row]
pixel[x - row]

Where row is the length of one row.

Care has to be taken for the edjes of the image. (shove a border around it, and start, using the border as the neibour for the first iteration).

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Advertisement
Hey nice coder,

The weighted average is a part of a process called "bilinear filtering", basically instead of taking each pixel in the original and rotating it, you take each pixel in the final image and reverse the rotation to find its colour. Most of the time the rotation doesn't give integer coordinates, so to find the equivalent colour at that (non-int) position, you take a weighted average of the pixels around it.
see http://www.flipcode.com/articles/article_bilinearfiltering.shtml

You're right in that its not the fastest way of performing a rotation, but it does give pretty nice results.

The reason i'm trying to get it faster is because i wanted to be able to rotate a little spaceship in any direction realtime. At the moment it could probably handle that, but not if i need to rotate several frames of an animated sprite.
Are you using fast sin/cos functions?

** edit **
If you are using non-optimized sin/cos routines, what I would recommend is that you create yourself some lookup tables:
float sin_lookup[361]; // 0-360 inclusive
float cos_lookup[361]; // 0-360 inclusive

fill them in at runtime via a loop, and then you may instantly gain the sin/cos of any whole angle:
sin_lookup[angle%360];

If you need more accuracy one option is to linearly interpolate between two values in the lookup.
int i_angle = (int)angle;
float dec = angle – _floor(angle);

float sin = sin_lookup[i_angle]*(1-dec) + sin_lookup[i_angle+1]*dec;

HTH


[Edited by - CyberFox on June 24, 2005 1:00:37 PM]
Optimization questions really shouldn't go in For Beginners. :(

Quote:
x2=(cosined*(x1-x0)-sined*(y1-y0)+x0);
y2=(sined*(x1-x0)+cosined*(y1-y0)+y0);


Since x0/y0 are constant and x1/y1 vary linearly, it should be possible to avoid the multiplications here by doing accumulation instead. Outside the loop, initialize:

x2 = sined*y0 - cosined*x0 + x0;y2 = y0 - sined*x0 - cosined*y0;


Then adjust each by the appropriate sined/cosined on each iteration (remembering to reset at the end of each "row").

OTOH, your compiler might be good enough to do that for you.

Other than that, working indirectly through surfaces is quite possibly the biggest speed hit here. Try caching basesprite->pixels (or whatever), and working with that directly - rotate "into" a local Uint32[] of the same size, and copy the data back to the sprite's pixel data.

This topic is closed to new replies.

Advertisement