OpenGL Vertical Flip: -360 + -360 = 0? - math

I am working with OpenGL and I wanted to invert the image. So I went here, asked a question and finally I had the following code:
glMatrixMode(GL_PROJECTION);
glScalef(-1,1,1);
glTranslatef(-width(),0,0);
From what I understand from this, the position of every pixel gets inverted, so the pixels that were on the right of the image are now on the same absolute position, but are the left of the image, so I have to move the entire thing back exactly as many pixels as its wide: 360 (which is the size of the "canvas", so in the snippents the function width() is being used)! So to undo this process I would invert the image again and then move it back to where it came from:
glMatrixMode(GL_PROJECTION);
glScalef(-1,1,1);
glTranslatef(width(),0,0);
Nope, blackscreen. I have to do exactly the same thing twice to undo the flipping: I have to move with -360 every time I flip the image. Why?

It's exactly as Daniel Fischer mentioned in the comment. Here is an illustration of the process.
What you must have in mind is that the transformations operate on the transformed coordinate systems.
We start with the image (grey) on the screen (green):
Then we scale the image. So the origin is preserved, but the x-axis is mirrored.
No we have to move the image onto the screen again. Because the x-axis points to the left (but we want to move the image to the right), we have to use a negative offset for the translation:
If we flip the image again, the following happens. The origin is preserved and the x-axis is mirrored:
So we must translate the image by a negative offset:
Another way of undoing the flip is undoing the operations (but in the opposite order):
glTranslatef(width, 0, 0);
glScalef(-1,1,1);
The mathematical reason for that is that inversion reverses the oder. If we have Matrix A = B * C then A^-1 = (C^-1 * B^-1).

Related

TriangleMesh with a partially transparent material gives an unexpected result

Recently, i tried to make transparency work in JavaFX 3D as some of the animations i want to play on meshes use transforms that change the alpha of the mesh each keyframe.
However to my surprise, my TriangleMesh that uses a material which has transparent areas doesn't look as expected.
Current result(depth buffer enabled): https://i.imgur.com/EIIWY1p.gif
Result with depth buffer disabled for my TriangleMeshView: https://i.imgur.com/1C95tKy.gif (this looks much closer to the result i was expecting)
However i don't really want to disable depth buffering because it causes other issues.
In case it matters, this is the diffuse map i used for my TriangleMesh: https://i.imgur.com/UqCesXL.png (1 pixel per triangle as my triangles have a color per face, 128 pixels per column).
I compute UV's for the TriangleMesh like this:
float u = (triangleIndex % width + 0.5f) / width;
float v = (triangleIndex / width + 0.5f) / (float) atlas.getHeight();
and then use these for each vertex of the triangle.
What's the proper way to render a TriangleMesh that uses a transparent material(in my case only part of the image is transparent, as some triangles are opaque)?
After a bit of research, i've found this which potentially explains my issue: https://stackoverflow.com/a/31942840/14999427 however i am not sure whether this is what i should do or whether there's a better option.
Minimal reproducible example(this includes the same exact mesh i showed in my gifs): https://pastebin.com/ndkbZCcn (used pastebin because it was 42k characters and the limit in stackoverflow is 30k) make sure to copy the raw data as the preview in pastebin stripped a few lines.
Update: a "fix" i found orders the triangles every time the camera moves the following way:
Take the camera's position multiplied by some scalar(5 worked for me)
Order all opaque triangles first by their centroids distance to the camera and then after that order all transparent triangles the same way.
I am not sure why multiplying the camera's position is necessary but it does work, best solution i've found so far.
I have not yet found a 'proper fix' for this problem, however this is what worked for me pretty well:
Create an ArrayList that'll store the sorted indices
Take the Camera's position multiplied by some scalar (between 5-10 worked for me), call that P
Order all opaque triangles first by their centroids distance to P and add them to the list
Order all triangles with transparency by their centroids distance to P and add them to the list
Use the sorted triangle indices when creating the TriangleMesh

determine rectangle rotation point

I would like to know how to compute rotation components of a rectangle in space according to four given points in a projection plane.
Hard to depict in a single sentence, thus I explain my needs.
I have a 3D world viewed from a static camera (located in <0,0,0>).
I have a known rectangular shape (an picture, actually) That I want to place in that space.
I only can define points (up to four) in a spherical/rectangular referencial (camera looking at <0°,0°> (sph) or <0,0,1000> (rect)).
I considere the given polygon to be my rectangle shape rotated (rX,rY,rZ). 3 points are supposed to be enough, 4 points should be too constraintfull. I'm not sure for now.
I want to determine rX, rY and rZ, the rectangle rotation about its center.
--- My first attempt at solving this constrint problem was to fix the first point: given spherical coordinates, I "project" this point onto a camera-facing plane at z=1000. Quite easy, this give me a point.
Then, the second point is considered to be on the <0,0,0>- segment, which is about an infinity of solution ; but I fix this by knowing the width(w) and height(h) of my rectangle: I then get two solutions for my second point ; one is "in front" of the first point, and the other is "far away"... I now have a edge of my rectangle. Two, in fact.
And from there, I don't know what to do. If in the end I have my four points, I don't have a clue about how to calculate the rotation equivalency...
It's hard to be lost in Mathematics...
To get an idea of the goal of all this: I make photospheres and I want to "insert" in them images. For instance, I got on my photo a TV screen, and I want to place a picture in the screen. I know my screen size (or I can guess it), I know the size of the image I want to place in (actually, it has the same aspect ratio), and I know the four screen corner positions in my space (spherical or euclidian). My software allow my to place an image in the scene and to rotate it as I want. I can zoom it (to give the feeling of depth)... I then can do all this manually, but it is a long try-fail process and never exact. I would like then to be able to type in the screen corner positions, and get the final image place and rotation attributes in a click...
The question in pictures:
Images presenting steps of the problem
Note that on the page, I present actual images of my app. I mean I had to manually rotate and scale the picture to get it fits the screen but it is not a photoshop. The parameters found are:
Scale: 0.86362
rX = 18.9375
rY = -12.5875
rZ = -0.105881
center position: <-9.55, 18.76, 1000>
Note: Rotation is not enought to set the picture up: we need scale and translation. I assume the scale can be found once a first edge is fixed (first two points help determining two solutions as initial constraints, and because I then know edge length and picture width and height, I can deduce scale. But the software is kind and allow me to modify picture width and height: thus the constraint is just to be sure the four points are descripbing a rectangle in space, with is simple to check with vectors. Here, the problem seems to place the fourth point as a valid rectangle corner, and then deduce rotation from that rectangle. About translation, it is the center (diagonal cross) of the points once fixed.

Determine the resulting angle of a reflected sprite (diagonal mirror)

I am trying to achieve a simple reflected sprite effect. Imagine a diagonal line which goes from one corner of the screen to the other. Then, a sprite (or image) is rotated by a particular amount and placed at some location on one side of the diagonal. What would be the mathematical formula to programmatically rotate another instance of the sprite (or image) that will be placed on the reflected side of the screen? It's easy for me to figure out if the reflection is vertical or horizontal (a simple flip of the image) and I can figure out where to place the resulting sprite, but it seems like a whole different level of complexity trying to determine the resultant sprite's angle.
Any suggestions or programming formulas? I generally stink at trigonometry and can't find any leads. Again, the angle of the line of reflection is known (or can be found) as can the angle of the original sprite. I just want to determine how the reflected sprite will be rotated when displayed.
If I understand you properly, then it should be as simple as making sure that the reflected sprite's angle (with respect to the diagonal line) is the same as the original sprite's angle (again w.r.t. the diagonal line) but negative.
Showing this in an image (with the original sprite on the bottom left and the reflection on the top right):
So if you look at the angles θI1 and θR1, you can see that:
θI1 is the angle between the original image and the diagonal line
θR1 is the angle between the reflected image and the diagonal line
These angles are equal and opposite, i.e. 55° and −55°.
That might not be quite enough for you to work out the rotations needed in the general case though, so I'll go into a bit more detail. Basically, like I said before, the angle between the reflected sprite and the line needs to be equal and opposite to the angle between the original sprite and the line. This is the same as making sure the difference in angle between each sprite and the line, with respect to a common reference direction, is equal and opposite.
Looking again at the image, assume that the common reference direction is to the right. It doesn't matter if you make this something else, as long as you're consistent. Also assume that the green arrows, on each sprite, would point parallel to the reference direction when the sprite has a rotation of 0°.
So with that in mind you can see that the angle of the line θL is 35° (with positive rotation being clockwise).
You can also see that the rotation of the original sprite θI2 is 45°.
So the angle between the original sprite and the line is θI2 − θL, which equals 10°.
Once again, the angle between each sprite and the line needs to be equal and opposite. That is:
θI2 − θL = −1 * (θR2 − θL)
To find the rotation needed for the reflected sprite, just rearrange that equation to this:
θR2 = 2θL − θI2
Putting in the values for θL and θI2 gives:
θR2 = 2*35° − 45° = 25°
So in this example the rotation of the reflected sprite θR2 is calculated to be 25°, which you can see is correct from the image. If you want to double check though, notice that the difference in angle between the reflected sprite and the line (θR2 − θL) is −10°, which is equal and opposite to θI2 − θL. Just remember to flip the reflected sprite before you apply this rotation (assuming the green arrow is the axis you flip it around).

HLSL: Keep Getting An Oval When I Want a Circle! (Pixel Shader)

I'm trying to tint a circle around the player in my 2D side scroller but I keep getting an oval! Here's the part of the code I'm using that matters:
if(length(abs(coords - playerCoords)) < .1)
{
color = color *float4(1,0,1,1);
}
return color;
My screen size is 1280 wide x 720 tall. I know that this is the reason for the distortion, but I don't know enough about my issue in order to come up with or find a solution. Can someone explain to me how to compensate for the screen stretch?
Thanks!
-ATD
multiply the "abs()" term by "float2((720./1280.),1.0)" -- or whatever your y/x aspect ration might be
The coords you are using are normalized in 0-1 space, so just correct them

XNA Track rotated pixel positions

Im making a game in xna where a tank has to move over a landscape.
I need to be able find the bottom of the tank when it is rotated so I can make it move up and down as the player goes over the landscape.
for example if i have a sprite at with its top left corner at 400,300 and i rotate it around its center by 45 degrees around its center, how do i find the new locations of the bottom track.
Thanks
Thanks for the reply Langaurd.
I have looked at the article link before but didnt understand how it works.
Im making a 2d side scrolling game. As the player moves left and right, the tank has to also tilt to follow the contour of the terrain.
I have two vectors that store the back bottom of the track and one that stores the front bottom of the track.
I have tried
Vector2 backBottom = new Vector2(5, 25);
Vector2 frontBottom = new Vector2(5, 32);
backBottom = Vector2.Transform(backBottom+position, Matrix.CreateRotationZ(angle));
frontBottom = Vector2.Transform(frontBottom+position, Matrix.CreateRotationZ(angle));
but that gave me some strange values
Not 100% clear on exactly what it is you are trying to do. You mention a sprite, which is 2D, but your description is in 3D terms. If you are doing a 2D side view, then you can't tell the tank is rotated 45 degrees. If you are doing a 2D top-down view, then you shouldn't really care where the bottom of the tred is.
In any case, two suggestions. If you are die-hard on tracking rotated pixels, then read this article: 2D collision with Transformed Pixels from the creators.xna.com site. However I would recommend tracking vectors. Use two vectors to represent the track locations, and then use Vector2.Transform to rotate them with the tank. You could then use the vectors to check to see if the tracks have hit something, what angle they are at, ect.
You need to define a clearer orientation for you sprite. I would use a Front and Up Vector for the tank. Now you rotate both of them together with the angle your tank drives depending on the terrain. Lets say these vectors are at the center of your sprite. and your sprite is rotated, exactly like your up and front vectors. Now just multiply your Halfheight with -Up vector and you should have your local bottom center, add your tank position and you have your world bottom track position.
Important: Don't mix up a point, which can be expressed by a vector, or a real vector which has no position and only shows the direction. For directions its important to normalize the vector.
Sorry for the vague answer but you question is a little bit vague too.

Resources