Sign in to follow this  
nyrhinen

[SDL] Rotating an image.

Recommended Posts

My question today is, "How to rotate an image with SDL?". I've tried SDL_Gfx's rotozoom, but I'd like to make my own function for that. So I started to study math, and I have accomplished a code like this:
#include <math.h>
#include <SDL/SDL.h>
	#define PI 3.14159
	#define SWIDTH 640
	#define SHEIGHT 400
void Putpixel(SDL_Surface *screen, int x, int y, int r, int g, int b) {
	unsigned char *pixel;
	pixel = screen->pixels;
	pixel = pixel + y * SWIDTH * 4;
	pixel = pixel + x * 4;
	*pixel = b; pixel++;
	*pixel = g; pixel++;
	*pixel = r;
}
int sgn (long a) {
	if (a > 0) return +1;
		else if (a < 0) return -1;
			else return 0;
}
void Line(SDL_Surface *screen, int a, int b, int c, int d, int col) {
	long u,s,v,d1x,d1y,d2x,d2y,m,n;
	int  i;
	u   = c-a;
	v   = d-b;
	d1x = sgn(u);
	d1y = sgn(v);
	d2x = sgn(u);
	d2y = 0;
	m   = abs(u);
	n   = abs(v);
	if (m <= n) {
		d2x = 0;
		d2y = sgn(v);
		m   = abs(v);
		n   = abs(u);
	}
	s = (int)(m / 2);
	for (i = 0; i < round(m); i++) {
		Putpixel(screen, a, b, 255, 255, 255);
		s = s + n;
		if (s >= m) {
			s = s - m;
			a = a + d1x;
			b = b + d1y;
		} else {
			a = a + d2x;
			b = b + d2y;
		}
	}
}
int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_VIDEO);
	SDL_WM_SetCaption("Rotating", NULL);
	SDL_Surface *screen = SDL_SetVideoMode(640, 400, 32, SDL_SWSURFACE);
	SDL_Event event;
	int angle = 0, i;
	while (1) {
		SDL_FillRect(screen, NULL, 0);
		SDL_PollEvent(&event);
		if (event.type == SDL_QUIT) break;
			else if (event.type == SDL_KEYDOWN)
				if (event.key.keysym.sym == SDLK_ESCAPE) break;
		Line(screen, 320, 200, -sin(angle*PI/180)*100+320, cos(angle*PI/180)*100+200, 255);
		Line(screen, 320, 200, -sin((angle+90)*PI/180)*100+320, cos((angle+90)*PI/180)*100+200, 255);
		if (angle > 360) angle = 0;
		angle = angle + 1;
		SDL_Delay(1);
		SDL_Flip(screen);
	}
	SDL_FreeSurface(screen);
	SDL_Quit();
	return 0;
}

No comments, sorry. :-) But the code above rotates a corner (two lines), and my goal with that code was to rotate a full square, and then texturise it with lines. Yes, I know, it sounds stupid, but it was the first thing that came to my mind. So any ideas to rotate a texturised image? Or to improve my code above? Thanks already! -nyrhinen

Share this post


Link to post
Share on other sites
The main problem with that method is that unless your vertices are screen-aligned, filling it in with lines won't necessarily fill the box - you'll get missing and duplicated pixels.

Anyway, the idea is to create the new quad by rotating the vertices of the original, then rasterise it using the original as the sample source (texture): Once the quad has been transformed, determine which pixels lie within the new bounds (a couple of linear inequalities will take care of this). For each of these, transform the coordinates back (inverse rotate) to find out which part of the original quad it came from and determine the pixel colour from there.
A pixel-rotate will use a point-sampler, which rounds the result (of the reverse rotation) to the nearest pixel before reading in the colour. This looks pretty rough. A much prettier sampling technique is the bilinear filter, which takes the weighted average of the nearest two pixels in each dimension and averages the result. This will only work with continuous colour scales (so no palettes), will produce colours that don't appear in the original and, if done many times, will blur the image noticeably.

As you can see, this involves a fair bit of work, but it's rewarding when your implementation works. I'm sure other posters can suggest some optimisations for/details on/alternatives to the technique.

Regards
Admiral

Share this post


Link to post
Share on other sites
Quote:
Original post by TheAdmiral
The main problem with that method is that unless your vertices are screen-aligned, filling it in with lines won't necessarily fill the box - you'll get missing and duplicated pixels.

I was aware of that when I started doing this, but I just wanted a basic rotater, not anything fancy.
But about that bilinear-techique, any examples or something?

-nyrhinen

[Edited by - nyrhinen on September 7, 2006 3:06:30 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this