PDA

View Full Version : Projecting a rectangle onto a circle

Beafy
31-Jan-2007, 11:27
Well, this is more of a 2D than a 3D question, but anyways...
As part of a university project, I'm trying to transform a rectangular 2D surface into a circular surface.
Basically, I have a level (the game I want to do this with is Pingus, a Lemmings clone btw.), and want to wrap it around in a circle.
The way I do this right now is I segment the whole map from left to right into several large triangles, with the tips of all triangles at the top of the map, and the long sides on the bottom.
Naturally, all the space between the triangles won't be represented in the output then, but that's something I can fix in the game logic.
I then use the contents of these triangles as a texture to fill in a circle. Now, since the distance from the bottom to the top of each triangle is shortest in the middle, and longest at the outer edges, I throw away all the data that's "higher" than the height in the middle of the triangle.
All in all, this leads to a donut shaped form, which is perfectly acceptable. However, the perspective isn't quite correct. The pixels are more sheared than rotated. When I make a sketch and look at what happens with the texture coordinates I use, I can see why this happens, but I have no idea how to fix it.

Maybe anyone here has a nice idea, or even knows of a much better approach?

I'll attach a screen shot as soon as I get on my other PC

Thank you for any help.

Beafy
31-Jan-2007, 11:43
Here's an image of how it looks right now (don't mind the obvious cuts in the scene. The level isn't designed with my my idea in mind, since I'm still at an early prototype stage...):

http://img504.imageshack.us/my.php?image=pingus200701311135051yx6.png

Also, here's an image to the Pingus sprites, so you can see how the would look like in a normal state:

http://img100.imageshack.us/my.php?image=walkergp7.png

[maven]
31-Jan-2007, 13:40
This (http://en.wikipedia.org/wiki/Map_projection) is the inverse problem.

From your description of what you're doing, it sounds more like you're projecting onto a cone instead of a half-sphere...

Captain Chickenpants
31-Jan-2007, 14:08
Hmm, the having to split it into triangles and having a gap between them sounds like a shotrcut that might produce the kind of artifact you are seeing.
I think it should be quite straightforward to work out a coordinate mapping function to handle it properly.

If you are trying to get from a rectangular image to a circular image then you need to iterate the circular image pixels.

For each dest pixel
Find Polar coordinate for current dest pixel.
Src X = angle * imagewidth / 360
Src Y = magnitude * imageheight
Set Dest pixel = source at calculated coords.

I think that would work...
You would need to clamp the coordinates as otherwise it will try and fetch from outside your source image.
To avoid having the top of your src image mapped to a single point in the center of the circle just pretend the image is taller and add a constant offset to the SrcY

CC

Simon F
31-Jan-2007, 14:20
;919764']This (http://en.wikipedia.org/wiki/Map_projection) is the inverse problem.

From your description of what you're doing, it sounds more like you're projecting onto a cone instead of a half-sphere...

Actually, what I think he wants to do is apply the rectangular texture to a cylinder, i.e a fairly straightforward , piecewise-linear mapping. He should then align the central axis of the cylinder with the Z axis and position the base of cylinder on the centre of the screen.

That way, you will get the hyberbolic mapping (i.e. perspective correct texturing) to evenly squeeze the image towards the "centre" of the screen without missing any pixels.

(Of course, some MIP mapping would also help)

Beafy
31-Jan-2007, 14:24
CC and Maven, thanks for commenting. The thing is: I want to avoid everything becoming thinner towards to center, and fatter towards the radius. This can't be possible without throwing stuff away when going to the upper part of the image.
I know it's unusual to just disregard parts of the level, but I have to work in the confines of what is already there in Pingus, so it's not exactly an optimal situation. If I would write it from scratch, I would use polar coordinates in the game, but unfortunately that's just not practical right now...

Any additional insight is most welcome :-)

Edit: The general idea is that Pingus should become a table top game, so that there can be 4 people standing around it, and that the orientation of the gameworld fits for everyone. The Pingus should enter the game somewhere on the outer radius of the circle, and have to work themselves toward the center (You can see the idea in the screenshot above).

Beafy
31-Jan-2007, 14:28
Actually, what I think he wants to do is apply the rectangular texture to a cylinder, i.e a fairly straightforward , piecewise-linear mapping. He should then align the central axis of the cylinder with the Z axis and position the base of cylinder on the centre of the screen.

That way, you will get the hyberbolic mapping (i.e. perspective correct texturing) to evenly squeeze the image towards the "centre" of the screen without missing any pixels.

(Of course, some MIP mapping would also help)

Simon, thank you for your comment. The first part I believe describes pretty much what I want to accomplish. However, I actually want to avoid squeezing towards the center (see my previous post).

Simon F
31-Jan-2007, 16:12
Simon, thank you for your comment. The first part I believe describes pretty much what I want to accomplish. However, I actually want to avoid squeezing towards the center (see my previous post).
But you must, surely, squeeze the image in at least one dimension! If the Y of your original game maps to the radius of your circle/ring, then the X dimension must be compressed as you get closer to the centre.

You don't have [to compress in Y, but, IMHO, it would look better if you did maintain a gradual but uniform XY squash.

Basic
31-Jan-2007, 16:41
If you rename the X- and Y-coordinates of the original rectangular surface as R and PHI, and map it to your new X- and Y-coordinate as:

X = a*exp(b*R+c)*cos(PHI) + x0
Y = a*exp(b*R+c)*sin(PHI) + y0
Then you'll shrink stuff towards the center, but it won't deform.

If you still don't like that, then I'd recommend drawing the pingu sprite directly into the final image.

Beafy
31-Jan-2007, 21:04
I made a sketch of how I do it right now:

http://img297.imageshack.us/my.php?image=sketchug4.png

Please don't laugh, it all seemed really simple when I thought it up last week :-)

Rendering the Pingu Sprites on top of everything would be a last resort solution, but then I'd have to redo collision detection and everything, so I'd rather not do it...
With the solution above, I was hoping that all I had to take care of was moving the Pingus from one triangle to the next, and drawing them correctly across boundaries.

Davros
31-Jan-2007, 21:16

is this sprites ???
if so wouldnt you be better to create a mask, iirc you then bitwise and, then bitwise xor
you then end up with a circular sprite

Beafy
31-Jan-2007, 21:26