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.
Related
Goal:
Move a 3D object as if it is in 2D space (screen). So if the user moves the mouse left the object should move left (the same should apply for all other directions: right, up, down).
Description:
I am working with OpenTK (OpenGL - 3D space)
Since the object itself should always rotate around it's center I first apply the rotation then the translation matrix.
What works
With trying out I was able to get the translation for the x-Axis and y-Axis (both 2d space) working separately.
// works for x-Axis movement
var rotation = _control.Rotation;
// vector is a 2d vector that contains the vector from the mouse drag start position
// (so the pixels the mouse was moved from the drag start to its current position)
// factor is a value that depends on the current zoom value - can be ignored for the problem itself
var xTranslationVector = new Vector3(
vector.X * (float)Math.Cos(rotation.Y) * factor,
0,
vector.X * (float)Math.Sin(rotation.Y) * factor);
// initial value is the original translation on drag start
_control.Translation = initialValue + xTranslationVector;
// vector for y-Axis
var yTranslationVector = new Vector3(0,
-vector.Y * (float) Math.Cos(rotation.X) * factor,
vector.Y * (float) Math.Sin(rotation.X) * factor);
// _control.Translation = initialValue + yTranslationVector;
Both work when used independent from each other.
Questions
How do I need to combine the xTranslationVector and yTranslationVector so that it would work as expected (multiplication doesn't work because any vector component could be 0 which results in no movement at all; addition does not work when the object is rotated around some axis partially)
I would like to understand what I am doing there, what are the mathematical terms i should look for to find explanations?
How can I do the same for rotation (f.e. the object is rotated 45° degrees around the y axis and I want to rotate - currently the object would tilt around it's x axis but i would like to tilt it always as if the object was not rotated around it's x axis - sorry not sure how to word this well)
Game Maker Studio 2 has a downloadable demo of a dungeon top down game. In it there is a collision check script. The part of it for walking left is as follows:
x += -4;
var tx = (x-16)>>5; /* check right edge (my note: this gets the tile x-index
for the wall on the left, as each tile is 32 pixels wide. I think they
copied the part for walking right and didn't fix the comment)*/
var ty1 = ((y+16)>>5);
var ty2 = ((y-16)>>5);
// collision data never has flips etc...
var tile1 = tilemap_get(WallMap, tx,ty1 )& tile_index_mask;
var tile2 = tilemap_get(WallMap, tx,ty2 )& tile_index_mask;
if(( tile1!=0 ) || (tile2!=0))
{ x = (x&~31)+16; }
(I replaced some variables and macros with their value. The +16 parts are for sprite adjustment. The sprite origin of the player (x,y) is set 16 pixels away from its edges).
The last line is what bothers me.
31 in bit is 00000000000000000000000000011111.
~31 in bit then is 11111111111111111111111111100000.
so x&~31 should really just set the last 5 digits of the x bit to 0.
But x=0,y=0 is the upper left part of the room. The smaller x is, the closer it is to the left side.
So what I gather from this is that when x collides with a wall on its left while walking left, this function sets its origin closer to the left, into the wall. Which doesn't make sense.
To my understanding, the last line should have been { x = (x&~31)+32+16; }, to snap the player origin to the left side of the wall tile, move it 32 pixels to the right side of the wall, then 16 pixels more to adjust to the sprite width.
Yet running the game, it works as intended. Trying to walk left into a wall keeps you in place. Where am I mistaken?
I don't think this issue is really about the bitwise aspect of it. The way I interpret this code, is that x represents the "origin" of the sprite and x - 16 its left edge. Then tx = (x-16)>>5 computes the x coordinate of the tile that the left edge is in, which is collision tested and so forth.
However, at that same moment, the origin of the sprite is still in the tile that you're standing on (the movement offset is smaller than half the sprite width, so the tentative movement does not move the origin into a different tile in one step), and that is the x which is used in (x&~31)+16. Therefore, x&~31 rounds down to the left border of the tile you're standing on, not the left border of the wall tile.
I'm implementing a homing bullet that targets the nearest enemy.
I'm able to calculate the angle between the player's forward vector and the vector from the player to the target by doing a dot product.
If I put the result to acos(), it will give me the angle between the 2 vectors in terms of radian.
Now I want my object to rotate and face toward the enemy as it is flying. But here comes the problem, how do I know which side to rotate to? I know the angle between the 2 vectors, but I dot producted value doesnt tell me whether or not the target is on the left side or right side of the player.
I'm wondering if I'm taking a longer route, and I might not be aware of a easier way to determine how much and to which side I need to rotate to face the target.
You can calculate dot product for side vector like this:
vector Side( Front.Y, -Front.X );
float dotSide = dot( Target, Side );
if( dotSide <= 0 )
{
// one side
}
else
{
// another side
}
If I understand you right, you want to get the direction, in which your spaceship vecS should rotate in order to look at the target vecT.
I would suggest to calculate the angle alpha, which vecS and the x-axis enclose, as well as the angle beta, which vecT and the x-axis enclose.
If alpha is greater than beta you would rotate to the right, otherwise to the left.
Here is the pseudocode to calculate the angle and the proper rotation direction:
// Pseudocode:
alpha = arctan( vecS.y / vecS.x );
beta = arctan ( vecT.y / vecS.x );
if(alpha > beta)
// Rotate right by alpha - beta
else
// Rotate left by alpha - beta
This is more of a programming problem than a technical question but since it relates to programming and math, I'm hoping to get some helpful feedback.
I have two rectangles: rectangle1 and rectangle2.
Both are defined by four float values:
float left;
float right;
float top;
float bottom;
For the sake of this example, say that each rectangle is 100 x 100 and that rectangle1 is:
float left = 100.0;
float right = 200.0;
float top = 500.0;
float bottom = 600.0;
And rectangle2 is:
float left = 150.0;
float right = 250.0;
float top = 550.0;
float bottom = 650.0;
When a collision occurs, I am trying to determine which side of rectangle1 hit which side of rectangle2 using the eight float values.
If my question was answered, I might be able to determine something like the following when a collision occurs:
rectangle1's right side hit rectangle2's left side
So far, I have tried using simple math to determine the distance between each possibility:
float distance1 = rectangle2.left - rectangle1.right;
float distance2 = rectangle2.top - rectangle1.bottom;
float distance3 = rectangle2.right - rectangle1.left;
float distance4 = rectangle2.bottom - rectangle1.top;
And then taking the minimum of those values to determine which side of each rectangle was involved in the collision. It doesn't seem so simple, though. There were two basic problems with this attempt:
1) The rectangles will already be overlapping by the time the collision code is reached.
2) If multiple rectangles are stacked on top of each other, the calculation will produce strange results (ie, even if rectangle1 is moving in the upper right direction and should hit both rectangles on their left side, it may actually hit one rectangle on the bottom and the other on the left.)
(This is because the rectangles are overlapping when the collision code is reached AND because distance1 and distance4 will be close or equal in this case.)
Is there a better way to answer this question using simple math? Any help would be appreciated.
And, before it's mentioned, this is not homework but a real problem I'm trying to solve for my game.
If you can correctly identify the collision, then to determine the faces draw a line joining the center of the 2 rectangles and check for intersection with the faces of each rectangle. At any given time the line will intersect 2 faces as long as the 2 rectangles are not overlapping or to be precise, as long as the center of 1 is not inside the other.
When they are overlapping, you can get 1 or 0 intersection.
case 0: 1 rectangle is totally inside the other so you can decide how you want to decide which sides are hitting, may be choose the one closest to each center.
case 1: rectangle is totally or partially inside the other. In either case, continue to extend your line joining the centers until you cross the outer (containing) rectangle. If u cross the contained rectangle before again, just change the hit face to the newly crossed face.
Hope its not too confusing :)
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.