Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Baguettator on Sat 05/02/2022 22:24:03

Title: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sat 05/02/2022 22:24:03
Hi there !

My question could be very stupid, but I have no idea of how ags handles that...

Imagine I have a DynamicSprite "f" that is a square ("rectangle" ?) with these attributes : f.Width=30, f.Height=34.

If I do : f.Rotate(90)

It makes : f.Width=34 and f.Height=30.

Right :)

BUT, if I do : f.Rotate(45)

What will be the width and height of f ?
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sat 05/02/2022 22:31:42
The width and height will be minimal necessary rectangle to accomodate the rotated image.

But why do you need to know how AGS does this? Do you want to know about the algorithm, or do you simply want to know resulting width and height? In the last case you may read DynamicSprite's Width and Height properties after rotation.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sat 05/02/2022 22:34:51
OK thanks !

I just wanted to know the formula to calculate the new height/width of the dynamic sprite.

Is the formula well-known ? I have to use it in scripts, with many things that have different heights and widths, so I need the generical approach.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sat 05/02/2022 22:37:11
Quote from: Baguettator on Sat 05/02/2022 22:34:51
I just wanted to know the formula to calculate the new height/width of the dynamic sprite.

But why do you need this formula? Are you resizing sprites yourself before rotating?
The manual sais that for DynamicSprite.Rotate "AGS will automatically calculate the new size required to hold the rotated image" if you pass no width and height.
That is, if you write just "f.Rotate(45);" it will be resized itself as necessary.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sat 05/02/2022 22:44:53
Because I use a script to calculate coordinates for tokens (to place on maps, like a tabletop game). And I have "stored" the possible coordinates for the different tiles.

So for example I can place my square at the 1st position of the tile A, with a "up" rotation, and it will automatically set it to x and y coordinates according to my script.

But if I rotate the tile, I have to rotate the tokens too. So they change their rotation (up becomes right for a 90° rotation, or becomes down for a 180° rotation, etc), and their coordinates. To change their coordinates, I need to know their width and height. I have to script it during a time when DynamicSprites are NOT created yet. So I can't use DynamicSprite.Width etc

Is the formula too complex ?
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sat 05/02/2022 22:48:00
Quote from: Baguettator on Sat 05/02/2022 22:44:53
But if I rotate the tile, I have to rotate the tokens too. So they change their rotation (up becomes right for a 90° rotation, or becomes down for a 180° rotation, etc), and their coordinates. To change their coordinates, I need to know their width and height. I have to script it during a time when DynamicSprites are NOT created yet. So I can't use DynamicSprite.Width etc

Is the formula too complex ?


Oh, sorry. I was wondering if you are doing some unnecessary work for sprite rotation.

Formula is this (math):
Code (ags) Select

new_width = (cos(angle) * old_width + sin(angle) * old_height);
new_height = (sin(angle) * old_width + cos(angle) * old_height);


In AGS script that would be:
Code (ags) Select

new_width = FloatToInt(Math.Cos(angle) * IntToFloat(old_width) + Math.Sin(angle) * IntToFloat(old_height));
new_height = FloatToInt(Math.Sin(angle) * IntToFloat(old_width) + Math.Cos(angle) * IntToFloat(old_height));


The angle above is in radians. If you have angle in degrees, you need to first convert it using Maths.DegreesToRadians.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sat 05/02/2022 22:59:28
That said, but I still wonder if this is necessary.

Could you save positions of the token centers instead of top-left corners? Then you won't have to calculate these coordinate changes, and realign the sprites only after they change.
This depends on what kind of map you have though.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sat 05/02/2022 23:08:24
Thanks a lot Crimson !

I already scripted all the tokens with their top-left corner coordinate (which is the way AGS works for buttons, and tokens are represented by buttons), and it should be very long to change it now... Maybe one day :) Surely it should be better, but it works perfectly for now.

I'm working on the rotation of the tile, will see if it works with the new formula.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sat 05/02/2022 23:13:12
I presume that if I only talk about 45° multipliers (45, 135, 225 and 315), these dynamicsprites should have the same width/heights ?
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sat 05/02/2022 23:13:56
Quote from: Baguettator on Sat 05/02/2022 23:13:12
I presume that if I only talk about 45° multipliers (45, 135, 225 and 315), these dynamicsprites should have the same width/heights ?

That should be correct, all mirror angles should result in the same size.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sun 06/02/2022 01:15:53
Quote from: Baguettator on Sat 05/02/2022 23:08:24
I already scripted all the tokens with their top-left corner coordinate (which is the way AGS works for buttons, and tokens are represented by buttons), and it should be very long to change it now...

I made a mistake. You do not have to use center positions. You may keep existing top-left positions (non rotated), and then adjust tile's position after it is rotated like this:

Code (ags) Select

new_x = old_x + (old_width - new_width) / 2;
new_y = old_y + (old_height - new_height) / 2;

EDIT: fixed by /2

This will work generally if the tile is resized for any reason.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Snarky on Sun 06/02/2022 06:43:32
Shouldn't you divide those widths and heights by 2, CW?
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Crimson Wizard on Sun 06/02/2022 08:05:34
Quote from: Snarky on Sun 06/02/2022 06:43:32
Shouldn't you divide those widths and heights by 2, CW?

Right.
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sun 06/02/2022 10:43:12
Hmm I didn't follow you in your thoughts... I used your formula (with cos and sin) to calculate the width/height of the token after rotating (45° or multipliers), then I simply do that :

Code (ags) Select
//34=width when it's not rotated, 30 is the height when not rotated
int l=FloatToInt(Maths.Cos(Maths.DegreesToRadians(45.0))*IntToFloat(34) + Maths.Sin(Maths.DegreesToRadians(45.0))*IntToFloat(30));
int h=FloatToInt(Maths.Sin(Maths.DegreesToRadians(45.0))*IntToFloat(34) + Maths.Cos(Maths.DegreesToRadians(45.0))*IntToFloat(30));
int x, y; // x is the original x position for the top leftcorner of the token, y is the y position of the top leftcorner
int xporte, yporte; // Also the original coordinates of the token
// The tile width and height are equal to 250
if (nouveau==right) // the tile rotates to right, so 90°
{
  xporte=250-y-h;
  yporte=x;
}
else if (nouveau==down) // the tile rotates to down, so 180°
{
  xporte=250-x-l;
  yporte=250-y-h;
}
else if (nouveau==left) // the tile rotates to left, so 270°
{
  xporte=y;
  yporte=250-x-l;
}
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Sat 23/04/2022 14:16:18
Hmm Khalibri, what are you talking about ? What do you want to do ?
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Baguettator on Fri 18/08/2023 14:31:54
Hi here, I continue this thread with a new math problem I need help to solve :

let's say I have a square (same width and height). Into this square, I have a point at (x,y) coordinates (the coordinates are from square's size, so the top left corner coordinates are 0,0).

If I rotate the square by "a" degrees, how can I calculate the new coordinates for the point ? (the point rotates with the square, as if they were the same thing). Is there a formula that works generally for any "a" value ? I guess there is, but I don't know which :(
Title: Re: Rotating Sprites : how does it change the size ?
Post by: Khris on Sun 20/08/2023 15:43:33
You need a 2D rotation matrix:

(https://wikimedia.org/api/rest_v1/media/math/render/svg/d4a02e6b5990244f4427309f6732239b9633d62d)

int[] RotatedPoint(int xi, int yi, int deg) {
  float x = IntToFloat(xi);
  float y = IntToFloat(yi);
  float r = Maths.DegreesToRadians(deg);
  float c = Math.Cos(r), s = Math.Sin(r); // cosine and sine
  int r[] = new int[2];
  // matrix times vector
  r[0] = FloatToInt(c * x - s * y, eRoundNearest);
  r[1] = FloatToInt(s * x + c * y, eRoundNearest);
  return r;
}

This function rotates a 2D point around the origin, so if your square is supposed to rotate around its center, you need to subtract half the side length from your coordinates before calling it, then add it back.

Example code:
  // square size s
  // shift origin to square's center
  x -= s / 2;
  y -= s / 2;
  int p[] = RotatedPoint(x, y, 5); // 5 degrees clockwise
  // shift origin back to top left
  x = p[0] + s / 2;
  y = p[1] + s / 2;