How would I implement strafe using opengl in java? - opengl

This is my gluLookAt setup:
glu.gluLookAt(x,y,z, // eye location
x + Math.cos(Math.toRadians(eyeAngle)),
y,
z - Math.sin(Math.toRadians(eyeAngle)), // point to look at (near middle)
0.f,1.f,0.f); // the "up" direction
The x, y, z are the coordinates and change when turning left and right and moving forward and backward. But I'm having difficulty implementing strafe right and left. Any help would be appreciated.

Finally figured everything out. If you have move forward and turn left and right, then strafe is actually simple. Strafe right, for example, is basically you turning 90 degrees to the right, moving forward, and then turning 90 degrees back to the left.
My forward was:
x += distance*Math.cos(Math.toRadians(eyeAngle));
z += -distance*Math.sin(Math.toRadians(eyeAngle));
You don't want to change the eyeAngle, because you still want to look in the same direction. For strafe right, you want to move as if you turned 90 degrees to the right and then went forward, similarly for left. So right would be my forward method above with an angle 90 to the right of my original eyeAngle, but because you want to keep eyeAngle the same, you don't change the variable, you just add 90 to it.
So, the right strafe method would be:
x += distance*Math.cos(Math.toRadians(eyeAngle+90));
z += -distance*Math.sin(Math.toRadians(eyeAngle+90));
Left would be subtracting 90. It is actually pretty simple after you've got forward and the overall glulookat set up. Thanks for the help everyone, it did aid me in understanding how it all works.

I don't have an idea about the GLU APIs but given X,Y and Z co-ordinates,
a Left relative to it's current Y rotation is,
position of X -= distance*Math.sin(Math.toRadians(Y-90));
position of Z += distance*Math.cos(Math.toRadians(Y-90));
a Right relative to it's current Y rotation is,
position of X -= distance*Math.sin(Math.toRadians(Y+90));
position of Z += distance*Math.cos(Math.toRadians(Y+90));
Try replacing Y with eyeAngle coz thts what is the rotating point.

Related

Ellipse rotated not centered

I am trying to draw a rotated ellipse not centered at the origin (in c++).
so far my code "works":
for (double i = 0; i <= 360; i = i + 1) {
theta = i*pi / 180;
x = (polygonList[compt]->a_coeff / 2) * sin(theta) + polygonList[compt]->centroid->datapointx;
y = (polygonList[compt]->b_coeff / 2) * cos(theta) + polygonList[compt]->centroid->datapointy;
xTmp = (x - polygonList[compt]->centroid->datapointx)* cos(angle1) - (y - polygonList[compt]->centroid->datapointy)*sin(angle1) + polygonList[compt]->centroid->datapointx;
yTmp = (x - polygonList[compt]->centroid->datapointx)* sin(angle1) + (y - polygonList[compt]->centroid->datapointy)*cos(angle1) + polygonList[compt]->centroid->datapointy;
}
PolygonList is a list of "bloc" which will be replaced by an ellipse of same area.
My issue is that the angles are not quite exact, as if I had to put a protractor that'd fit the shape of my ellipse, the protractor would obviously get squeezed, and so would be the angles (is that clear ?)
Here is an example: I am trying to set a point on the top ellipse (E1) which would be lying on a line drawn between the centroid of E1, and any point on the second ellipse (E2).On this example, the point on E2 lies at an angle of ~220-230 degree. I am able to catch this angle, the angle seems ok.
The problem is that if I try to project this point on E1 by using this angle of ~225 degree, I end up on the second red circle on top. it looks like my angle is now ~265 degree, but in fact, if I shape the protractor to fit in my ellipse, I get the right angle (~225) ,cf img 2)
it is a bit hard to see the angle on that re-shaped protractor, but it does show ~225 degree.
My conclusion is that the ellipse is drawn like if I had to drew a circle and then I'd compress it, which changes the distance between the angles.
Could someone tell me how I could fix that ?
PS: to draw those ellipses I just use a for loop which plots a dot at every angle (from 0 to 360). we clearly see on the first picture that the distance between the dots are different whether we are at 0 or at 90 degree.
your parametrisation is exactly that, a circle is a case of ellipse with both axes are equal. It sounds like you need use rational representation of ellipse instead of standard: https://en.m.wikipedia.org/wiki/Ellipse
So, I've asked the question above so that I could find a possible overlap between 2 ellipses by checking the distance between any point on E2 and its projection on E1: if the distance between the centroid of E1 and the projected dot on E1 is larger than the distance between the centroid of E1 to a dot on E2 I'll assume an overlap. I reckon this solution has never been tried (or I haven't search enough) and should work fine. But before working I needed to get those angles right.
I have found a way to avoid using angles and projected dots, by checking the foci:
the sum of the distance between the focus A and B to any point around an axis is constant (let's call it DE1 for E1).
I then check the distance between my foci and any point on E2. If that distance becomes less than DE1, I'll assume a connection.
So far it seems to work fine :)
I'll put that here for anyone in need.
Flo

Find a point inside a rotated rectangle

Ok so, this should be super simple, but I'm not a smart man. Technically I want to know whether a point resides inside a rectangle, however the rectangle can be in different states. In my current context when I want to draw a rectangle rotated by, lets say, 45° clockwise, what I do is rotate the entire x,y axis centered at the top-left corner of the rectangle and then I just draw the rectangle as if nothing has happened. Same goes if I want to draw the rectangle at a random coordinate. Given that is the coordinate system who gets tossed and rotated, the rectangle always thinks it's being drawn at (0,0) with 0°, therefore, the best way to find if a given point is inside the rectangle would be to find the projection for the point based on the translation + rotation of the rectangle. But I have no idea how to do that.
This is what I currently do in order to find out if a point is inside a rectangle (not taking into consideration rotation):
bool Image::isPointInsideRectangle(int x, int y, const ofRectangle & rectangle){
return x - xOffset >= rectangle.getX() && x - xOffset <= rectangle.getX() + rectangle.getWidth() &&
y - yOffset >= rectangle.getY() && y - yOffset <= rectangle.getY() + rectangle.getHeight();
}
I already have angleInDegrees stored, as long as I could use it to project the (x,y) point I receive I should be able find out if the point is inside the rectangle.
Cheers!
Axel
The easiest way is to un-rotate x,y in the reverse direction relative to the origin and rotation of the rectangle.
For example, if angleInDegrees is 45 degrees, you would rotate the point to test -45 degrees (or 315 degrees if your rotation routine only allows positive rotations). This will plot the x,y on the same coordinate system as the unrotated rectangle.
Then, you can use the function you already provided to test whether the point is within the rectangle.
Note that prior to rotating x,y, you will probably need to adjust the x,y relative to the point of rotation - the upper-left corner of the rectangle. Since the rotation is relative to that point rather than the overall coordinate origin 0,0. You can compute the difference between x,y and the upper-left corner of your rectangle (which won't change during rotation), then simply rotate the adjusted point by -angleToRotate, then add the origin point difference back into the unrotated point to get absolute coordinates on your coordinate system.
Editted:
#include <cmath>
bool Image::isPointInsideRectangle(int x, int y, const ofRectangle & rectangle){
return x*cosd(deg) - y*sin(deg) + xOffset >= rectangle.getX()
&& x*cosd(deg) - y*sin(deg) + xOffset <= rectangle.getX() + rectangle.getWidth()
&& x*sind(deg) + y*cosd(deg) + yOffset >= rectangle.getY()
&& x*sind(deg) + y*cosd(deg) + yOffset <= rectangle.getY() + rectangle.getHeight();
Like you have already told, you could translate the coordinates of your point into the space of the rectangle. This is a common task in many software products which work with geometry. Each object have it own coordinate space and works as it would be at position (0, 0) without rotation. If your rectangle is at position v and rotated about b degree/radian, than you can translate your point P into the space of the rectangle with the following formula:
| cos(-b) -sin(-b) | | P_x - v_x |
| | ⋅ | |
| sin(-b) cos(-b) | | P_y - v_y |
Many of the most important transformations can be represented as matrices. At least if you are using homogeneous coordinates. It is also very common to do that. Depending of the complexity and the goals of your program you could consider to use some math library like glm and use the transformations of your objects in form of matrices. Then you could write something like inverse(rectangle.transformation()) * point to get point translated into the space of rectangle.

Problems understanding gluLookAt xyz rotation in FPS scenario

I'm having trouble with gluLookAt.
My camera can rotate along the X and Y axis by piping in relative mouse motion events. The problem is the Z axis - I don't know how to calculate it.
So, my camera can look up, down, left and right. But I can't work out how to completely rotate through 360 degrees!
Could anyone help?
EDIT:
So, here's a trivial example of my code so far:
Point3 test(0,0,0);
Matrix4 camera = Camera::getInstance().getCameraM();
if ((event.motion.xrel > 200) || (event.motion.yrel > 200))
{
break;
}
float mx = (event.motion.xrel);
float my = -(event.motion.yrel);
mx /= 20;
my /= 20;
test.setX(test.getX()+mx);
test.setY(test.getY()+my);
Camera::getInstance().lookAt(Point3(0,0,15),test,Vector3(0,-1,0));
Camera::lookAt simply wraps up the glu lookAt function.
gluLookAt (...) produces an orthogonal view-space. You already know one of the two axes when you call it (Y-axis is given as up), the Z-axis is computed given the direction from eye to center and then finally the X-axis is the cross product between Y and Z.
By the way, you cannot completely rotate through 360 degrees. At +/- 90 degrees off of horizontal you run into a singularity, where there are two possible ways to represent the same angle. If you interpolate rotation through that Euler angle, then you can wind up flipping your orientation. Effectively if two of your three axes become parallel (which happens when you look straight up or straight down) then things get really messy with Euler angles.

confused about a simple formula to move player to mouse position

I encountered a simple formula on the internet to move a player to mouse position based on calculating the distance between characters X position and Mouse X position and dividing it by the distance between the two entities like below
//the below statement moves the player to the left towards the mouse pointer
if(player.position.x > Mouse_Position_X)
player.setPosition(player.position.x - ( ( player.position.x - Mouse_Position_X)/distance * 2.0f ));
...
..
.
// similar statements for other three checks to move player to right, top and bottom
// distance value is found out by a getDistance function which calculates the distance between two entites(player and mouse pointer in this case)
I would like to know what the above formula does as compared to a simple formula like below
which also moves the player to the left.
if(player.position.x > Mouse_Position_X)
player.setPosition(player.position.x - 2.0f);
Why would we subtract the players current position with the mouse position and divide it by their distance?
Thanks a lot!
The first formula also depends on some variable distance which is not defined. It seems to move the player's position somewhat in the direction of the mouse coordinate.

Movement of a sprite according to rotation

I hope this is an acceptable question for this forum, as it's more of a maths question than a programming question.
I am developing a basic space shooter game using the cocos2d framework, where the user controls a spaceship and shoots asteroids/enemies, and the enemies also shoot back at the spaceship (original eh?).
The 'lasers' that are fired by the enemies are a tube like shape, and generally only travel form right to left on the x axis. This is easy to achieve, and the movement is created with this line of code:
currentEnemyProjectile.position = ccp(currentEnemyProjectile.position.x - ((screenSize.width/kLaserSpeed)* dtSixty), currentEnemyProjectile.position.y);
I also have one particular enemy, which resides in the middle of the screen and rotates to fire its projectiles at the spaceship, so if the space ship is at a different y position than the enemy then the projectile sprite will be rotated and then will move to the spaceship's position, so it will need to also move through the y axis.
I'm currently using code to achieve this:
float xDiff = ((screenSize.width/kLaserSpeed)* dtSixty);
float yDiff = (xDiff / 57) * currentEnemyProjectile.rotation;
currentEnemyProjectile.position = ccp(currentEnemyProjectile.position.x - xDiff, currentEnemyProjectile.position.y + yDiff);
I just worked this out as a temporary fix, I know it is not the optimal way of doing things. It sort of works, but as I am working out the y offset from the movement along the x axis, the projectiles will move faster if they have further to travel along the y axis. Ideally they should move slower along the x axis if they are moving further upwards or downwards, so that the rate of travel is constant for any trajectory. (I hope I've explained that well enough)
It's been roughly 10 years since I last had a maths lesson, so my geometry/trigonometry is rather hazy/non-existent, can anyone shed any light on how this can be done?
Also, it's worth noting that I would like to do this without the use of cocos2d actions. I would rather move my sprites each frame as I have been currently doing as I manipulating the flow of time as part of the game, so I need more control than the cocos2d actions can offer.
Thanks in advance for any help.
To find a position using a starting position, an angle, and a distance, the formula is as follows:
ccp( x + ( distance * sin( angle ) ), y + ( distance * cos( angle) ) )
Keep in mind that the angle for this formula will have to be in radians, not degrees. You can convert degrees into radians like this:
radians = degrees * PI / 180
Try this. I realized since you know the vector to the player, you don't need the trig. You only need to calculate v and h once so you may want to save those values and not calculate them on every frame.
// Vector from enemy to player
CGPoint v = enemy.position - player.position;
// distance from enemy to player (sqrt of the dot product of v with v)
float h = sqrt(v.x*v.x+v.y*v.y);
// Desired distance to move along v
delta = ((screenSize.width/kLaserSpeed)* dtSixty);
// delta/h is the % moved along v, find the % moved in the x and y direction
xDiff = v.x * delta/h;
yDiff = v.y * delta/h;