Rotation Problem

So i have this problem when rotating entities in my program. It seems some tiles are omitted from the rotation in any degree value that is not 90,180,270, or 360. Which I kinda expected, but I can’t figure out how to fix it. ???

http://zippy.gfycat.com/UnlawfulWelcomeAnteater.gif

I am rotating a 2d array of tiles:


for (int x = 0; x < texture.getTexture().getWidth(); x++) {
			for (int y = 0; y < texture.getTexture().getHeight(); y++) {
				
				Vector2 rotate = rotate(new Vector2(x-width/2,y-height/2));//Rotate points about center
				float x1 = Math.round(rotate.x+width/2);//round and translate
				float y1 = Math.round(rotate.y+height/2);//round and translate
				Tile t = Game.get(this.rx / Tile.gridSize + x1, this.ry
						/ Tile.gridSize + y1);//get grid tile
				Color c = texture.pixelData[x][y];//get grid color
				if (c.a > 0 && t != null) {
					t.type = Type.BLOCKED;//make sure tile is solid
					t.r1 = c.r;//assign color to tile
					t.g1 = c.g;
					t.b1 = c.b;
				}
				within[x][y] = t;//assign tile to list
			}
		}

rotation method:


public Vector2 rotate(Vector2 point){ 
		return point.rotate(rotation);
}

Any help would be awesome!

You’d probably want to change the texture filter on the sprite or apply some sort of anti-aliasing (don’t know how though).

It’s not texturing, he’s moving the tile data around, not an image.

It is aliasing though. You’ll probably need to do some kind of error accumulation like in brensenham. Your tile positions are being rounded into the wrong locations.

A crappier “I don’t want to think about it” solution could be something like


placeTile(t, spot) 
    if spot already occupied
        add [t, spot] to open list
    else
        place t in spot

// after all placements attempted, resolve

for [t, spot] in open list
    place t in unoccupied spot closest to where t was 'supposed' to have gone (spot)

Would probably work but is terrible. Also needs a nearest-neighbor-search friendly data structure.
(Technically you would also have to check conflicts to see “who is closer to being right,” not just “who got there first,” but meh)

EDIT: what (code) is Game.get()?

In addition to the above, you might take a look here and here. As mentioned above, with the method you’re using, it seems likely pixels may be missed due to rounding. In the aforementioned links it’s suggested to iterate over the destination pixels rather than the source pixels, and rotate backwards to find the corresponding source pixel. In this case you may sample some source pixels more than once (and may skip others), but you’ll be sure to hit every destination pixel. I haven’t implemented image rotation myself so can’t speak from experience, but iterating over the destination instead of the source is something you could try in addition to the above suggestions.

Yeah, that would be way better.

Thanks for the replies! I’m going to look over these sources and try this stuff out!
@BurntPizza Game.get return the tile located at the coordinates specified

Well yeah, but it appears to be taking floats. Does it round, or floor? etc.

Oh, Yeah it casts the float to an integer. I do it this way to keep some clutter out of the main code.


public static Tile get(float x, float y) {
		Tile got = null;
		try {
			got = tiles[(int) x][(int) y];
		} catch (ArrayIndexOutOfBoundsException e) {
			return null;
		}
		return got;
	}

Are this.rx etc. floats or is that integer division? The fact that you are rounding x1, y1 but then truncating the also possibly truncated results might be hiding some of your error.
And catching AIOOBE is nasty.

rx and ry are the rounded (to the grid) versions of the entities position to ensure the pixel stay locked into the grid. They are float values.
[edit]

Yeah I know, I’ll fix that when I actually start optimizing

It’s not texturing, he’s moving the tile data around, not an image.
[/quote]
Since I did not know the framework he used, I only gave what could have been the answer from personal experiences. The framework I use changes the result depending on the filter you set the texture to use (in-engine, not the actual image). So Filter_Nearest sometimes would produce a result such as that.

No biggie, but he did say “I am rotating a 2d array of tiles” etc. :point:

Facepalm I didn’t read it as well as I thought, my apologies.