Calculating vertices of a rotated rectangle
Moderator: Coders of Rage
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: [Solved] Calculating vertices of a rotated rectangle
Omfg, I have a class called Rect in libGyro with a member function Rect::CalculateVertices() that looks nearly identical. And the vertices aren't recalculated unless you have somehow changed them (via setScale(), setPosition(), setRotation()).
Also, we ran into the problem of everybody forgetting to call Rect::CalculateVertices() before rendering, so if they haven't been recalculated, the renderer implicitly does it for you. The only time that we explicitly call CalculateVertices() is for shapes with Collidable regions before the physics.
Also, we ran into the problem of everybody forgetting to call Rect::CalculateVertices() before rendering, so if they haven't been recalculated, the renderer implicitly does it for you. The only time that we explicitly call CalculateVertices() is for shapes with Collidable regions before the physics.
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: [Solved] Calculating vertices of a rotated rectangle
lol, I like how we think thenGyroVorbis wrote:Omfg, I have a class called Rect in libGyro with a member function Rect::CalculateVertices() that looks nearly identical. And the vertices aren't recalculated unless you have somehow changed them (via setScale(), setPosition(), setRotation()).
Also, we ran into the problem of everybody forgetting to call Rect::CalculateVertices() before rendering, so if they haven't been recalculated, the renderer implicitly does it for you. The only time that we explicitly call CalculateVertices() is for shapes with Collidable regions before the physics.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: [Solved] Calculating vertices of a rotated rectangle
Hey that's a good read. ThanksMarauderIIC wrote:I probably used to. Found these in my bookmarks w/ tags "const optimization" : http://www.mi.uni-koeln.de/c/mirror/www ... c0092.html http://stackoverflow.com/questions/2122 ... ation-in-c http://gotw.ca/gotw/081.htmshort0014 wrote:Marauder, I'm curious, do you know anything about how by making a variable const vs nonconstant the compiler can optimize it?
Whoops, I wasn't paying attention to the fact that he was doing that =)qpHalcy0n wrote:Calculate sin and cos once. Those two functions are costlier than anything in that whole shabang there.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: [Solved] Calculating vertices of a rotated rectangle
I have a thought, and it could be because I'm now in my physics class and I'm "falling in love" with vectors because I can see EXACTLY how I would use them.GyroVorbis wrote:Omfg, I have a class called Rect in libGyro with a member function Rect::CalculateVertices() that looks nearly identical. And the vertices aren't recalculated unless you have somehow changed them (via setScale(), setPosition(), setRotation()).
Also, we ran into the problem of everybody forgetting to call Rect::CalculateVertices() before rendering, so if they haven't been recalculated, the renderer implicitly does it for you. The only time that we explicitly call CalculateVertices() is for shapes with Collidable regions before the physics.
My though, or question really is, do you guys (anyone) think its better to only have each object only know its local coordinates, and not its world coordinates? Currently my objects (rectangles) know their world coordinates (if they are out of rotation with the world axis).
The reason I was doing this was so when I went to apply the seperating axis theorem, I could just ask each object (rectangle) for its four corners and do the calculations from there.
However, I am thinking that it may be better (and also easier) for each object to know only its local coordinates, and when I need to figure out where the objects corners are, I can just convert their local coordinates to world coordinates and do the check.
I know it may not seem like anything spectacular, but its this kind of process that is helping me really understand openGL and game design in general. Going through the process of learning all the stuff such as this. On the flip side, its these little things that I am learning that are certainly slowing down any progress I would be seeing !
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Calculating vertices of a rotated rectangle
In our engine, we store both the local and world coordinates.
Imagine a character. He has an "imagebox" and a "collisionbox." In most RPGs, the player is 2 units tall and 1 unit wide. But he's only colliding with the bottom layer with 1 unit by 1 unit.
I have his imagebox and collisionbox in local coordinates, and they are transformed to world coordinates. Also, all of our coordinates/vertices are vectors. A vector is can be visualized conceptually as either a point, or a distance from the origin to a point.
With that in mind, considering everything a vector gives you the advantage of easily vector/matrix manipulating things like coordinates.
You will also learn that collision resolution is much easier when you know the point of impact relative to an object's local coordinates.
But also keep in mind that these things are more than overkill for most 2D engines. If you don't plan on having 2D rotations, scaling, tranformations, blah blah--you're making things a lot more complicated worrying about things like local vs world coordinates (and maybe wasting a bit of space).
Imagine a character. He has an "imagebox" and a "collisionbox." In most RPGs, the player is 2 units tall and 1 unit wide. But he's only colliding with the bottom layer with 1 unit by 1 unit.
I have his imagebox and collisionbox in local coordinates, and they are transformed to world coordinates. Also, all of our coordinates/vertices are vectors. A vector is can be visualized conceptually as either a point, or a distance from the origin to a point.
With that in mind, considering everything a vector gives you the advantage of easily vector/matrix manipulating things like coordinates.
You will also learn that collision resolution is much easier when you know the point of impact relative to an object's local coordinates.
But also keep in mind that these things are more than overkill for most 2D engines. If you don't plan on having 2D rotations, scaling, tranformations, blah blah--you're making things a lot more complicated worrying about things like local vs world coordinates (and maybe wasting a bit of space).
-
- Respected Programmer
- Posts: 387
- Joined: Fri Dec 19, 2008 3:33 pm
- Location: Dallas
- Contact:
Re: Calculating vertices of a rotated rectangle
Ahhh, you are starting to seeeee young grasshoppa :]
Anytime you pass a coordinate via glVertex you are indeed passing an "object space" position. It is via the MODELVIEW transformation (note the MODEL part) which *DEFINES* these positions in "world space" and then ultimately into "view space". In the absence of a world transform (also called modelling transform) then the vertices you pass are indeed in "world space", since the modelling transform is an assumed identity matrix. Kinda see what I'm getting at? Two ways of thinking of and representing the same place.
By storing your coordinates in world space already, you're simply bypassing a step of the transformation pipeline which is the modelling transform. When passing object space coordinates: performing calls such as "translate"..."rotate"..."scale"...you are GIVING the positions definition in the "world" by concatenating several transforms to the view matrix which are modelling transforms. In other words, you are describing their positions relative to every other object in your scene. The view matrix just puts the camera at the origin so everything in world space is then in relation to the camera.
For virtually all practical applications in games, objects will come to you in object space. You're responsible for the rest of the transformation.
Anytime you pass a coordinate via glVertex you are indeed passing an "object space" position. It is via the MODELVIEW transformation (note the MODEL part) which *DEFINES* these positions in "world space" and then ultimately into "view space". In the absence of a world transform (also called modelling transform) then the vertices you pass are indeed in "world space", since the modelling transform is an assumed identity matrix. Kinda see what I'm getting at? Two ways of thinking of and representing the same place.
By storing your coordinates in world space already, you're simply bypassing a step of the transformation pipeline which is the modelling transform. When passing object space coordinates: performing calls such as "translate"..."rotate"..."scale"...you are GIVING the positions definition in the "world" by concatenating several transforms to the view matrix which are modelling transforms. In other words, you are describing their positions relative to every other object in your scene. The view matrix just puts the camera at the origin so everything in world space is then in relation to the camera.
For virtually all practical applications in games, objects will come to you in object space. You're responsible for the rest of the transformation.
- cypher1554R
- Chaos Rift Demigod
- Posts: 1124
- Joined: Sun Jun 22, 2008 5:06 pm
Re: Calculating vertices of a rotated rectangle
Or you could have used ye olde reliable: TransformedVertice = TransformationMatrix * LocalVertice
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Calculating vertices of a rotated rectangle
?cypher1554R wrote:Or you could have used ye olde reliable: TransformedVertice = TransformationMatrix * LocalVertice
That's the point of the topic. That's what he's doing when he's applying glScale() and glRotate() to his glVertex() calls.
edit: Don't forget that if you are only storing local vertices, then transforming those local vertices to world via glScale(), glRotate() for rendering--THEN you calculate the world vertices separately for collision checks--you're doing the calculations twice, and it might be better to store both world and local in this scenario.
- cypher1554R
- Chaos Rift Demigod
- Posts: 1124
- Joined: Sun Jun 22, 2008 5:06 pm
Re: Calculating vertices of a rotated rectangle
The calculations are done twice, yes.GyroVorbis wrote:?cypher1554R wrote:Or you could have used ye olde reliable: TransformedVertice = TransformationMatrix * LocalVertice
That's the point of the topic. That's what he's doing when he's applying glScale() and glRotate() to his glVertex() calls.
edit: Don't forget that if you are only storing local vertices, then transforming those local vertices to world via glScale(), glRotate() for rendering--THEN you calculate the world vertices separately for collision checks--you're doing the calculations twice, and it might be better to store both world and local in this scenario.
The first time it's done with GPU and is used ONLY by openGL to render. I don't think you can just jack the transformed vertex data out for your own purposes. What you can get is the current modelview matrix "glGet(GL_MODELVIEW_MATRIX);" and use it with [TransformedVertice = TransformationMatrix * LocalVertice] to calculate the transformed vertices. This time with CPU and for your own purposes (like collision).
EDIT: Oh wait.. You want to sacrifice memory for a calculation that GPU does with its tip of the smallest toenail? Why?
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Calculating vertices of a rotated rectangle
Uhm, what? The vertices must be stored regardless for physics/collision checking.cypher1554R wrote:EDIT: Oh wait.. You want to sacrifice memory for a calculation that GPU does with its tip of the smallest toenail? Why?
Even if it can do it at the tip of its toenail, you want to make it do that AND recalculate them? Why?
Edit: ALSO, glRotate(), glScale(), and transformations are NOT done on the GPU, they're performed on the CPU. And they aren't done with the "tip of a toenail"--calculating sin/cos for every piece of geometry in a scene as well as applying a transformation matrix isn't exactly speedy. Now make it do that again for physics. Why not just store them?
- cypher1554R
- Chaos Rift Demigod
- Posts: 1124
- Joined: Sun Jun 22, 2008 5:06 pm
Re: Calculating vertices of a rotated rectangle
The vertices must be stored, but not twice and kept all along..GyroVorbis wrote:Uhm, what? The vertices must be stored regardless for physics/collision checking.cypher1554R wrote:EDIT: Oh wait.. You want to sacrifice memory for a calculation that GPU does with its tip of the smallest toenail? Why?
Even if it can do it at the tip of its toenail, you want to make it do that AND recalculate them? Why?
I might be wrong in the way I think.. correct me:GyroVorbis wrote:edit: Don't forget that if you are only storing local vertices, then transforming those local vertices to world via glScale(), glRotate() for rendering--THEN you calculate the world vertices separately for collision checks--you're doing the calculations twice, and it might be better to store both world and local in this scenario.
- I want to keep the local vertices stored all along, let the GPU calculate them and render, use CPU to calculate global positions once more just for your own purposes (collision) - so they are stored for a very short part of the code (one function) leaving more memory space for other needs in other functions.
- You want to keep both local and global vertices stored all along, use GPU just for rendering, use CPU to calculate the vertex for openGL passing and for your own purposes (collision).
If I got it right, then I gotta say I favor my approach for only one reason: Safety.
Your approach requires the code to have a 100% responsibility to update the global vertices for any scene change that may occur. I wouldn't go into that.
the glRotate(), glScale(), and transformations calculate the MODELVIEW_MATRIX (if this matrix mode is set) not the global vertices. That globals calc part is done in GPU during the flushing before the rasterization.GyroVorbis wrote:Edit: ALSO, glRotate(), glScale(), and transformations are NOT done on the GPU, they're performed on the CPU. And they aren't done with the "tip of a toenail"--calculating sin/cos for every piece of geometry in a scene as well as applying a transformation matrix isn't exactly speedy. Now make it do that again for physics. Why not just store them?
My approach calculates them ONLY ONCE in CPU. instead of trig. approach uses matrices, and keeps them stored only for one function (collision check and something like that).
Re: Calculating vertices of a rotated rectangle
http://elysianshadows.com/phpBB3/viewto ... 077#p47077
this is not about GL, but dynamics, and might be pertinent to this topic in general.
this is not about GL, but dynamics, and might be pertinent to this topic in general.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
Dad, "Yea well I have a fan belt in street fighting"
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Calculating vertices of a rotated rectangle
Yeah, you're right about what you're saying vs what I'm saying.Cypher wrote: I might be wrong in the way I think.. correct me:
- I want to keep the local vertices stored all along, let the GPU calculate them and render, use CPU to calculate global positions once more just for your own purposes (collision) - so they are stored for a very short part of the code (one function) leaving more memory space for other needs in other functions.
- You want to keep both local and global vertices stored all along, use GPU just for rendering, use CPU to calculate the vertex for openGL passing and for your own purposes (collision).
If I got it right, then I gotta say I favor my approach for only one reason: Safety.
Your approach requires the code to have a 100% responsibility to update the global vertices for any scene change that may occur. I wouldn't go into that.
Your "scene" could change once a frame, which is how often vertices need to be recalculated anyway. As for "safety, because of responsibility for updating vertices"--the programmer is responsible for making sure he has the correct vertices anyway. If his physics system is going to be correct, he already has to do that.
I really can't argue whether the transformation matrix math is happening in the CPU or GPU (I've been told that the CPU is responsible), but it is really independent of my argument. On something like a Dreamcast, a PSP, or an embedded system it is happening on the CPU (and will eventually happen there anyway for physics). You don't have cute little glAnything() to handle your transforms for you. My method boasts platform independence.
This really is a misconception. If you have a shitload of vertices allocated (on the stack or heap) every frame (then deallocated), you aren't magically saving space. The majority of your data in a program is stored consistently (rather than being allocated and deallocated every function call).Cypher wrote:so they are stored for a very short part of the code (one function) leaving more memory space for other needs in other functions.
If you are doing it your way and use dynamic memory allocation, you could trash the heap (and have really bad memory holes). Or even if you did it with the stack, you still have less room for persistent data (that lingers for more than one frame). So why the hell not just store your vertices?
Oh, I'm sorry, I didn't realize that a rotation matrix was independent of ... trigonometry. XDcypher wrote:instead of trig. approach uses matrices,
Although I have to admit that all-in-all, you aren't exactly going to see a performance difference between both of our approaches (on a PC with OpenGL). If you prefer your way, there's nothing wrong with it. I'm just arguing that my way is better for practical reasons. :D
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: Calculating vertices of a rotated rectangle
is the part that I think is messing me up.GyroVorbis wrote:Well, back on this..Cypher wrote: --the programmer is responsible for making sure he has the correct vertices anyway. If his physics system is going to be correct, he already has to do that.
I cannot seem to calculate the world coordinates correctly. Which has been haunting me all along. I fear I am doing something incorrectly.
I am using the formula for each vertice of the rectangle:
source: http://stackoverflow.com/questions/1469 ... -rectangleCode: Select all
x' = x*cos(t) - y*sin(t) y' = x*sin(t) + y*cos(t) where (x, y) are the original points, (x', y') are the rotated coordinates, and t is the angle measured in radians from the x-axis. The rotation is counter-clockwise as written.
Anyways, the part that sayst is the angle measured in radians from the x-axis.
Each rectangle knows its own rotation angle. My fear is, when I use the above formula, I am using the wrong angle t.
I ask the rectangle for its rotation, and then I use that to calculate where it's vertices should be in world space. I feel like I need to do something to angle t, for this to work correctly because currently the rectangle rotates around the origin in the upper left hand corner (0,0,0).
Any ideas?
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Calculating vertices of a rotated rectangle
That is the equation for rotating something with respect to the origin. You aren't translating your entity before you rotate, are you?
That must be applied to your vertices before any translation.
Also, check to make sure that your local coordinates (since I'm guessing you've decided to store them) are (assuming a rect):
top left - (-0.5, -0.5)
top right - (0.5, -0.5)
bottom left - (-0.5, 0.5)
bottom right - (0.5, 0.5)
AND NOT
top left - (0, 0)
top right - (1, 0)
bottom left - (0, 1)
bottom right - (1, 1)
That must be applied to your vertices before any translation.
Also, check to make sure that your local coordinates (since I'm guessing you've decided to store them) are (assuming a rect):
top left - (-0.5, -0.5)
top right - (0.5, -0.5)
bottom left - (-0.5, 0.5)
bottom right - (0.5, 0.5)
AND NOT
top left - (0, 0)
top right - (1, 0)
bottom left - (0, 1)
bottom right - (1, 1)