123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|128|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> On Topic -> How do I rotate a array(tiles) in reverse?

Posted : Thursday, 22 July 2021, 05:22
Pakz

How do I rotate a array(tiles) in reverse?


For a sprite editor I was looking to create a function that rotates a selection by any angle. I have a working rotation but this loses cells in the grid. On stackexchange I think it was there was mention you should use a reverse rotation. Where you get the final rotated cells and from these find the cells from the original non rotated grid.

I think I might be able to just copy the selected data into a image and rotate that and copy the pixels back, but maybe having the code that does it itself might be more flexible.

Below is the cos and sin magic that rotates a grid right now. The grid is 32by32. The -16 is so it rotates from the center.


How would I do a reverse rotation so there is no lost pixels?

edit:There was mention of interpolation, but god knows what that is.
Posted : Thursday, 22 July 2021, 05:54
Jayenkai
You more or less have it.. (Assuming I'm understanding your question correctly)

Remove the floats, they're getting in the way.. Make it Floor(), so you get exact tile references.
The trick to filling up the whole map is that for each x/y of the Rotation, you check the x/y of the mathematically worked out position on the original Tilemap.
Fill up the whole Rotation that way, so that no tiles are empty.
You will still lose some data, but that's just due to the small resolution. It's never going to be perfect.

  --v


-=-=-
''Load, Next List!''
Posted : Thursday, 22 July 2021, 06:20
rychan
Regarding interpolation, you could check each tile for a NULL or invalid value, then if found, do the following:

1: Look at the surrounding valid tiles values ( 1 up down, left , right and diagonals)
2: Total up the values in each of those valid tiles.
3: Divide it by the number of valid tiles.

Then you should arrive at your interpolated tile value.

-=-=-
Web / Game Dev, occasionally finishes off coding games also!

Refresh Games - Game Dev Blog
Posted : Thursday, 22 July 2021, 06:39
Pakz
Yours works different than mine. It might be something becouse of the radians in the c language? When I rotate a small rectangle in the center with yours it does not loose tiles. When I do it with mine there are blanks.

I keep staring at it but am at a loss.


raylib clanguage:


edit: I just missed rychan's comment. Wil be looking at that.
Posted : Thursday, 22 July 2021, 07:02
Pakz
Ok, that interpolating seemed to be something I can use! It is like it is blurring the image if I think I understand it correctly?

Not sure how I should do this with palette values. Maybe just pick one of the surrounding colors?

edit: I think the palette color that is there most in the surrounding cells would be a candidate.
Posted : Thursday, 22 July 2021, 07:32
Jayenkai
Your issue is with this line..

rotated[x2][y2]=map[x][y];

X2 and y2 are barely ever going to run through every single rotated tile.

But X and Y DO run through every tile.
Instead of passing through every unrotated tile, then approximating where it should go. And having spaces along the way...
... for every rotated tile, approximate where you're taking it from (do the maths bit) then take that, and place it into the rotated map every single tile.

rotated[x][y]=map[x2][y2];

-=-=-
''Load, Next List!''
Posted : Thursday, 22 July 2021, 07:47
Pakz
Yes! that solved it. Thanks!
Posted : Thursday, 22 July 2021, 08:13
rychan
Yeah, it's essentially blurring it.

Can the palette values be converted into HEX or RGB?

If so then you might be able to do a (best match / shortest distance from) other palette entries when converted to HEX or RGB.

-=-=-
Web / Game Dev, occasionally finishes off coding games also!

Refresh Games - Game Dev Blog
Posted : Thursday, 22 July 2021, 17:00
shroom_monk
All this stuff comes down to signal processing, and thinking a bit more precisely about what the 2d array of numbers that is your sprite actually represents. It can seem a bit counter-intuitive at first to think about for traditional sprites, but those values in your array don't necessarily represent the 'entire' image - they're just 'samples' of the colour at a specific position. Typically you'll just take this to mean that the pixel at integer coordinates (x,y) just has a specific colour, and that's usually enough! But as soon as you want to scale or rotate the sprite, you have to consider how you sample the fractional coordinates. e.g. what is the colour at coordinates (10.5, 12.8)

There are many different sampling methods, and no single one is the 'correct' choice - it depends what you're going for artistically. For example, say you zoom in on a sprite, and need to fill in the gaps 'between' pixels from your original image - what approach do you take? You could just pick the exact colour of the nearest neighbour to your fractional coordinates, and get the more traditional 'blocky' view as a result. Or you could interpolate between the nearest pixels to the fractional coordinates (e.g. by average the values), resulting in a more blurred result.

When it comes to rotation, you have no choice but to sample fractional coordinates! Attempting to treat the original image as a set of discrete points, rotate those around, and then alias those back onto the pixel grid isn't going to work for exactly the reason Jay describes, hence why you need to go 'backwards' and sample the fractional positions directly. When doing that sampling, once again you could just pick the nearest neighbour colour (which is what Jay's code does) or use interpolation to sample 'between' the raw colours and get something smoother. The nearest neighbour approach is likely to look blockier and may have weird artefacts depending on the angle (especially if scaling is also involved), but won't give you any colours not in your original image. Interpolation is likely to look cleaner as it plays much better with how your eye works, but will give you colours not in your original image. The choice of which to use is pretty much just one of artistic preference.

Anyway, this is pretty much just me repackaging what others have already said in slightly more technical terms (and poorly, at that - it's late, it's too warm, and this really needs some diagrams to make much sense), but it can be useful (and interesting!) to think about when writing code to transform images like this. The wider internet almost certainly has better resources on signal processing and sampling (though naturally the wikipedia articles tend to be quite dense and jargon strewn!).

-=-=-
A mushroom a day keeps the doctor away...

Keep It Simple, Shroom!