Find RayCast Vector and move away from it in Godot - math

I am making a game in Godot and I want one of my enemies to move away from the ground when it detects a collision with RayCasts.
I set up my RayCasts like this:
I tried using this code:
for i in dodge.get_children():
if i.is_colliding():
var velocity = Vector2().rotated(deg2rad(i.rotation_degrees))
move_and_collide(velocity * -charge_speed * delta)
Where dodge holds all the RayCasts and I go through all its children and check for collisions. I then tried rotating the Vector2 by the rotation of the RayCasts, since that is how I rotated them instead of using Cast To, and tried moving it by that Vector, but it didn't work. It didn't even move in the wrong direction. It didn't move at all.
How would I go about solving this?

Look at this line:
var velocity = Vector2().rotated(deg2rad(i.rotation_degrees))
Here you create a new Vector with Vector2(). Which is equivalent to Vector2(0.0, 0.0).
When you rotate Vector2(0.0, 0.0), regardless of the angle, it will remain Vector2(0.0, 0.0).
As a result velocity will be Vector2(0.0, 0.0).
Then in this line you scale velocity:
move_and_collide(velocity * -charge_speed * delta)
If you multiply zero, I mean Vector2(0.0, 0.0), by any number it is still Vector2(0.0, 0.0).
And so it will move according to Vector2(0.0, 0.0), i.e. not at all.
So you need to change that starting Vector2(). It could be Vector.RIGHT or Vector.UP, or more likely Vector.DOWN. How do you know? Well, it is the direction of the RayCast2D if you don't rotate them.
Or, alternatively, you could use cast_to also. I believe it is like this:
var velocity = i.global_transform.basis_xform(i.cast_to).normalized()
Using basis_xform should apply the rotation (and any skewing), but not the translation. I also added normalized because I don't know if the result will be an unit vector, so it is to make sure it is.

Related

Create a formula for velocity based on rotation in 2d?

So I have a bit of a math problem. Here are the pieces.
Input:
Rot = Rotation (degrees). This is the rotation of the "player". This is also the yaw.
Vel.X = This is the left/rightward movement that would be happening if it weren't rotated
Vel.Z = Same as last except its up/down movement
Output:
Result.X = This is the actual movement that should be happening along the x axis considering rotation
Result.Z = Same as last
Basically the scenario is that a player is standing on a platform with "Rot" rotation. When directional keys are pressed velocity is added accordingly to the "Vel" value. However if rotation isn't 0 this wont produce the right result because when the player rotates moving left becomes relative.
Could you please tell me a formula that would find the proper x and y movement that would result in the player moving around relative to its rotation?
This problem is probably the most basic rotation question in game programming.
Using your Vel.X and Vel.Z values, you have what you might think of as the vector you wish to rotate in the x/z plane (instead of x/y - but same idea). Whether velocity or position, the approach is the same. With a simple google search we find that for 2D vector rotation, the formula is:
Result.X = Vel.X * cos(Rot) - Vel.Z * sin(Rot);
Result.Z = Vel.X * sin(Rot) + Vel.Z * cos(Rot);

Dynamic Shape Creation(Processing)

I'm trying to create a program that creates a custom pattern. I have it so that if sides = 3, it's a triangle 4 = rect and anything else above that has a formula so that, if you really wanted, you could have 25 sides. I'm using lines, rotation and rotation to plant, turn, draw repeat.
angleMeasure = (180 * (sides-2) ) /sides;
println(angleMeasure);
println(radians(angleMeasure));
//creating the 5+ shape
pushMatrix();
translate(width/2, height/2); //translating the whole shape/while loop
while(counter < sides){
line(0,0,170,0);
translate(170,0);//THIS translate is what makes the lines go in the direction they need too.
rotate(angleMeasure);
counter = counter + 1;
This works almost correctly. The last and first lines don't connect. Suggestions? Maybe it's a problem with the math, but println reveals a correct angle measure in degrees. Here's what it looks like: http://i.stack.imgur.com/TwYMj.png
EDIT: Changed the rotate from rotate(angleMeasure) to rotate(angleMeasure * -1). This rotated the whole shape and made it clear that the angle on the very first line is off. See:http://i.stack.imgur.com/Z1KmY.png
You actually need to turn by angle=360°/sides. And convert this angle into radians.
Thus for a pentagram you need angle=72°. The number you computed is 108, which interpreted as radians is 34 full turns plus an angle of about 67°. This falls 5° short of the correct angle, so that you obtain a somewhat correct picture with slightly too wide inner angles, resulting in the gap (and not a crossing as when the angle were larger than the correct angle).

Moving a object based on its rotation in three.js

I'm trying to move a cube in three.js based on its rotation but not sure on how to go about it.
As of now I can rotate the cube's z-rotation with the A & D keys. And with the W key I would like it to move forward relative to its rotation.
From 2D I would so something along the lines of:
float angle = GradToRad(obj.rotation);
obj.x = obj.x + cos(angle) * velocity;
obj.y = obj.y + sin(angle) * velocity;
Here's an image of the current implementation.
How can I apply something similar in three.js?
Objects can be considered to be facing their positive-Z axis. So to move an object forward, relative to it's own coordinate system, you can use
Object3D.translateZ( distance );
three.js r.57
It might be easiest to express both rotation and translation in a single (homogenous projective) 4×4 matrix. The Object3D.matrix member in three.js already does that, although you might have to set matrixAutoUpdate to false to use that directly. Then you can move use the translate method to move the object in its own reference frame.
Your 2D method is exactly how I did it in three.js. For the Y position I'm using a terrain collision technique (which still needs work);

openGL - I want the camera to get closer to the object, how?

I used the Qt equivalent to the gluLookAt to set my view matrix and I've been moving it by translating it everywhere in the scene.. now I want to get close with the camera to an object.
I know the position of the object, both in object coords and in each other coords (I have the model matrix for that object), but how to get the position of the camera?
To animate the camera to get closer and closer to the object I suppose I should take two points:
The point where the object is
The point where the camera is
and then do something like
QVector3D direction_to_get_closer = point_where_object_is - point_where_camera_is
How do I get the point where the camera is? Or, alternatively if this is not needed, how do I get the vector to the direction the camera has to follow (no rotations, I just need translations, this is going to simplify things) to reach the object?
gluLookAt(eye, target, headUp) takes three parameters, the position of the camera/eye, the position of the object you want to look at, and a unitvector to controll roll/head up direction.
To zoom closer, you can move the eye/camera position by some fraction of your vector direction_to_get_closer. For instance,
point_where_camera_is += 0.1f * direction_to_get_closer; // move 10% closer
Its more useful to move by a constant amount instead of 10% of the current distance (or else you will move very fast when the distance is great, and then increasingly slower). Therefore, you should use the normalized direction:
QVector3D unitDir = direction_to_get_closer.normalized();
point_where_camera_is += 0.1f * unitDir; // move 0.1 units in direction
The camera transform will break if point_where_camera_is becomes equal to point_where_object_is.
A better way, if you don't need to zoom, translate/rotate the new "zoomed" point_where_camera_is is to interpolate between to positions.
float t = some user input value between 0 and 1 (0% to 100% of the line camToObj)
QVector3D point_on_line_cam_obj = t * point_where_camera_is + (1-t) * point_where_object_is;
This way, you can stop the user from zooming into the object by limiting t, also, you can go back to the start position with t=0;

Moving object from point a to b (in 2D) that can only move forward and rotate itself

So I have a ship, that has thrusters at the bottom and that can only use these to move forward. It can also rotate itself around its center. Its thrusters gives it acceleration, so it doesn't move at a constant velocity. What I want to do is to tell it "move to point B".
I have come up with a solution but it doesn't work very well and it doesn't rotate smoothly, it moves jerkily and it doesn't end up exactly where it should be, so I have to have a big margin of error.
Is this a normal problem, and if so is there a "standard" way of doing it? Is this an easy problem? I want to make it look like the ship is steering itself to that point, using the constraints (thrusters, rotation) the player has. This excludes just lerping it from point A to B. Or does it?
I'd love some help in solving this problem. Positions are stored in vectors, and it's a 2D problem. Just for reference I'm including my solution, which basically is accelerating the ship until and rotating it to point to the point. I think my implementation of this idea is the problem:
Vector diff = vector_sub(to_point, pos);
float angle = vector_getangle(diff);
float current_angle = vector_getangle(dir);
float angle_diff = rightrange(angle) - rightrange(current_angle);
float len = vector_getlength(diff);
// "Margin of error"
float margin = 15.0;
// Adjust direction, only if we're not stopping the next thing we do (len <= margin)
if ( len > margin && fabs(angle_diff) > 2.0 )
{
dir = vector_setangle(dir, current_angle + (angle_diff)*delta*(MY_PI) - MY_PI/2);
}
else if ( len > margin )
{
dir = vector_normalize(diff);
}
// accelerate ship (if needed)
acc.x = acc.y = speed;
acc = vector_setangle(acc, vector_getangle(dir));
if ( len <= margin )
{
// Player is within margin of error
}
If you are not looking for a very general solution that works online, then there is a simple solution. What I mean by online is continuously re-calculating the actions along the complete trajectory.
Assuming the ship is at rest at start, simply rotate it towards your target point (while still at rest). Now, your ship can reach the target by accelerating for t seconds, rotating back while in motion (for 0.5 seconds as per your constraint), and decelerating for another t seconds. If the distance between current point and destination is d, then the equation you need to solve is:
d = 0.5*a*t^2 + 0.5*a*t + 0.5*a*t^2
The first term is distance traveled while accelerating. The second term is distance traveled while rotating (v*t_rot, v=a*t, t_rot=0.5). The final term is the distance traveled while decelerating. Solve the above for t, and you have your trajectory.
If the ship is moving at start, I would first stop it (just rotate in opposite direction of its speed vector, and decelerate until at rest). Now we know how to reach destination.
The problem with offline trajectory calculation is that it is not very accurate. There is a good chance that you will end up in the vicinity of the target, but not exactly on top of it.
Let's make the problem a little more interesting: the ship cannot rotate without acceleration. Let's call this acceleration vector a_r, a vector that is at a certain angle against the ship's direction (somewhat like having a thruster at an angle at the back). Your task now is to rotate the ship and accelerate in such a direction that the speed component perpendicular to the vector connecting the current position to the target is canceled out. Instead of trying to calculate the vectors offline, I would go with an online approach with this.
The easiest thing to do would be to add the following algorithm calculated at every time interval:
Calculate the vector pointing from ship to destination.
Split your current speed vector into two components: towards the destination, and perpendicular to it.
If perpendicular speed is zero, skip 4
Start rotating towards the negative of the perpendicular vector's direction. If already looking away from it (not exact opposite, but just looking away), also fire main thruster.
This will oscillate a bit, I suspect it will also stabilize after a while. I must admit, I don't know how I would make it stop at destination.
And the final approach is to model the ship's dynamics, and try to linearize it. It will be a non-linear system, so the second step will be necessary. Then convert the model to a discrete time system. And finally apply a control rule to make it reach target point. For this, you can change your state-space from position and speed to error in position and (maybe) error in speed, and finally add a regulation control (a control loop that takes the current state, and generates an input such that the state variables will approach zero).
This last one is fairly difficult in the maths compartment, and you'd probably need to study control engineering a bit to do it. However, you'll get much better results than the above simplistic algorithm - which admittedly might not even work. In addition, you can now apply various optimization rules to it: minimize time to reach target, minimize fuel consumption, minimize distance traveled, etc.

Resources