rotating pixel field

Hey,

I wrote a script that generates n random pixel positions and draws them to the screen. Works well. Now i tried to rotate them. Rotating does work too. But it does not work as i planned it.

paramters 'angle' and 'timestep' work somehow, but not as they should do. the function 'move' is supposed to rotate the pixelfield 'angle' degrees in a given direction, addicted to the 'timestep' parameter. 'timestep' is needed time for drawing in one single game loop.

angle_step = timestep * angle

1
2
3
4
5
6
7
8
9
10
11
// x

ppdPoint[i]->x = 

pRotationPoint->x + cos(angel_step) * (ppdPoint[i]->x - pRotationPoint->x) - sin(angel_step) * (ppdPoint[i]->y - pRotationPoint->y);

// y

ppdPoint[i]->y =

pRotationPoint->y + sin(angel_step) * (ppdPoint[i]->x - pRotationPoint->x) + cos(angel_step) * (ppdPoint[i]->y - pRotationPoint->y);


rotation point is the middle of the screen. when i set angle to 10 it should rotate 10 degrees / second. Instead it's rotating very very fast and all stars are moving nearer to the center of the screen, so after x rounds there is just 1 pixel left in the middle of the screen. there is a kind of gravition.

I'm working with SDL2. What I did find out:

FPS is <= 60, 'cause of the 'SDL_RENDERER_PRESENTVSYNC' flag. When i skip that flag, for any reason the 'gravition' would take more time. FPS is <= 1400 then, 'though i got a natural game loop (i hope):

1
2
3
4
5
6
7
8
9
10
11
12
while(pBuild->getExecuteFlag())
{
  pBuild->draw();
  pBuild->update(time_dif, pTimeWindow->TimeStampB);

  time_dif = (pTimeWindow->TimeStampB - pTimeWindow->TimeStampA);
  time_dif *= 0.001;
  pTimeWindow->TimeStampA = pTimeWindow->TimeStampB;
  pTimeWindow->TimeStampB = SDL_GetTicks();

  pBuild->count_fps(pTimeWindow->TimeStampB);
}


So maybe (timestep * angle) isn't the right way?
Your rotation code looks fine... although I'm curious as to whether or not that is the code that you actually have in your program (you spelled 'angle_step' wrong)... so maybe the code you posted here is correct but the code you have on your machine is wrong?

when i set angle to 10 it should rotate 10 degrees / second. Instead it's rotating very very fast


sin/cos's argument is in radians, not degrees. Multiply your angle by pi/180 to convert.

so after x rounds there is just 1 pixel left in the middle of the screen. there is a kind of gravition.


I don't see what would be causing this other than maybe rounding error. Are you using floats or doubles?
Pls ignore english spelling mistakes ...
It's not my mother tongue x)
But for the code, there are no compiler errors, so the code works, yes

double angle_step = timestep * (angle * (PI / 180))

Thanks for that. That seems to be the right speed.

ppdPoint[i] is a double **. I also got a ppPoint **, that is SDL_Point(), that uses integer.
I use ppPoint only for drawing. ppdPoint always does the calculating.

ppPoint and ppdPoint are both class members.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// x

ppdPoint[i]->x = 

pRotationPoint->x + cos(angel_step) * (ppdPoint[i]->x - pRotationPoint->x) - sin(angel_step) * (ppdPoint[i]->y - pRotationPoint->y);

// y

ppdPoint[i]->y =

pRotationPoint->y + sin(angel_step) * (ppdPoint[i]->x - pRotationPoint->x) + cos(angel_step) * (ppdPoint[i]->y - pRotationPoint->y);

// übergeben

ppPoint[i]->x = ppdPoint[i]->x;
ppPoint[i]->y = ppdPoint[i]->y;


So, I always use ppdPoint for calculating, and then I transfer values to ppPoint.

Pls ignore english spelling mistakes ...
It's not my mother tongue x)


My point was less about spelling mistakes, and more about what you have locally and what you are posting being different.

Maybe the code you are posting works fine, but the code you have locally is still broken. If that is the case... if what you have is broken and you are posting different code that isn't broken... then it will be impossible for anyone to spot the problem.


EDIT:

example:

1
2
3
4
double angle_step = timestep * (angle * (PI / 180))
//...

pRotationPoint->x + cos(angel_step) * (ppdPoint[i]->x - pRotationPoint->x) - sin(angel_step) * (ppdPoint[i]->y - pRotationPoint->y);


One of these is 'angle_step' and one of these is 'angel_step'. So this code would not compile. Which means this cannot be the code in your program.

If you do not post the code from your program, we cannot see the errors in it.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void CPixelField::move(double timestep, int flag)
{
  double angle_step = timestep * (angle * (PI / 180));

  if(timestep > 0)
  {
    switch(flag)
    {
      case PIXELFIELD_ROTATE_LEFT:
      {
        for(int i = 0 ; i < number_of_pixels ; i++)
	{
	  // x

	  ppdPoint[i]->x = 

	  pRotationPoint->x + cos(angle_step) * (ppdPoint[i]->x - pRotationPoint->x) -
	  sin(angle_step) * (ppdPoint[i]->y - pRotationPoint->y);

	  // y

	  ppdPoint[i]->y =

	  pRotationPoint->y + sin(angle_step) * (ppdPoint[i]->x - pRotationPoint->x) +
	  cos(angle_step) * (ppdPoint[i]->y - pRotationPoint->y);

	  // übergeben

	  ppPoint[i]->x = ppdPoint[i]->x;
	  ppPoint[i]->y = ppdPoint[i]->y;
        }
      } break;
    };
  }
}


That's the whole function. There is just one "angle_step" var.
Hmmm... I don't see what could be causing this.

Are you sure ppdPoint[i]->x is a double?
Yes, it definitely is.
Cannot remember, when I used float last time. It's double.

I think it must be a rounding rerror.
If this is a double... you would have to do this a lot for the rounding error to be noticeable. So I'm not convinced that's the problem.

But I don't see anything else. The code you posted looks fine.

Would it be possible for you to upload the whole thing somewhere?
Sure. It's a Visual Studio 2013 project.

http://www.wp1105995.server-he.de/project.zip
Cool. Thanks.

I'll check it out when I get home from work.
Well after downloading and installing 3 libs (SDL, SDL_Image, SDL_TTF) I started getting runtime errors with libfreetype. So I'm giving up. Sorry. Too many dependencies to deal with... I've already spent enough time on it.
@PadMad

I downloaded, and ran, your program. The Release version, showed a diagonal line on screen, along with the pointer cursor. The line sometimes flickered into two lines, but that's all it did. But, when I ran the Debug version, and put all the dll files, font dir, etc. into that directory, the star field showed up as a rectangle, and rotated around and around. Quite mesmerizing. The rectangle of stars kept getting smaller and smaller, till it was just a point of light in a black background. Very nice.
I'm using Visual Studio 2012 Express, on a 64 bit computer.
Sorry, could've sent the dependencies with, but thanks for tryin' disch.
I'm currently working with debug only. Didn't handle the release Version yet. The question is, why it is getting smaller and smaller @ whitenite1.

'cause that is not what it's supposed to do.
Last edited on
Hey,

Just wanted to let you know, that i solved the problem. It was a double type problem. even double becomes imprecise after some rotations. So what u do (in theory it's recommended) is, you don't move the points. The points' coords stay static. You just change the angle and add it to the coordinates of a point. Then u remember the last angle, and then u calculate a new angle and add it to the old angle. So no rotation is gone and it looks great.
Topic archived. No new replies allowed.