Game Maker Get Point On Path - path-finding

I'm combining A* pathfinding with a steering AI so I can make the movement look more smooth and natural. To do this, I'm calculating the path from the enemy to the player and using checkpoints on the path to have the steering AI move to. However, from what I have seen the only way to get the x and y values of a certain point on a path, you need to use path_get_point_x(path, n) to get the x coord for the nth point of the path. But, from what I've seen, the amount of points in a path are far too low for me to accurately move the enemy around obstacles. Sometimes, the enemy goes through obstacles to get to the next point even though the path traces around the obstacle. I noticed there is a variable called path_position that is a number from 0-1 representing how far into the path you are (1 being finished). Is there a way to use that to predict where the player will be at position 0.3 of they're at position 0.25, for example?

Most of the time objects will take the quickest path, or path of least resistance. Check precise collision detection for tiles that are bordering the pathways and see if that helps keep objects out of collision objects. As for a prediction to where they will be you can multiple the speed of the object by the frames per second.

Related

2d game collision detection using displacement vectors

I am trying to implement a collision detection algorithm for my game that uses 2D coordinates (x, y) and quads (rectangles). I am terrible at maths, and prior to making this post I wandered through solutions on stackoverflow, which have left me even more confused as they were stacked with comments saying this doesn't work for this case, or there's a better algorithm than this one, etc...
I did manage to implement a simple AABB collision detection and resolution algorithm in the beginning but later on realized the algorithm doesn't detect cases when the object's speed is high enough for it to phase through objects.
My current thought process was to grab the old position vertices (oldTL, oldTR, oldBL, oldBR) and new position vertices (newTL, newTR, newBL, newBR) of the object, create 4 line segments represented by two points (old), (new) for each pair of vertices, and find out if they intersect any edges on any objects.
I'm very lost and would appreciate any help or feedback I could get...

How do I best map an unorganized point cloud back to it's organized ancestor?

I get an organized point cloud (using pcl and an ASUS Xtion Pro Live), which of course contains NANs and the like. I also get an RGB image of the same scene.
The first step for processing is removing those NANs, which converts the point cloud to unorganized. I then perform a few other steps, but that's not relevant to the question (I think, see P.S.1). What COULD (I'm not sure) be relevant is that I run extract multiple times, and so have quite a few intermediate point clouds. I believe this means I can no longer assume that the points are in the same order they were at the start.
For clarification, I do understand what an unorganized point cloud it and how it differs from unorganized, both theoretically and in terms of how the data is actually stored.
After chopping off various points, I now have a much smaller point cloud which consists only of points in the original point cloud (but much less of them). How do I map these points back to the matching points in the original point cloud? I probably could iterate through the entire cloud to find matches, but this seems hacked together. Is there a better way to do this?
My main aim is to be able to say that 'point A in my final point cloud is of interest to me' and furthermore to map that to pixel K in the RGB image I first obtained. It seems to me that matching the final point cloud with the initial one is the best way to do this, but alternatives are also welcome.
P.S.1 - One of the last few steps in my process is finding a convex hull and then extracting a polygonal prism from the original point cloud. If all else fails, I will just interrogate the (20-50) points on the convex hull to match them with my initial point cloud (minimizing computation) and hence to match them with the original RGB images.
P.S.2 - Random musing - since I know the original size of the RGB image, the origin of the camera relative to the point cloud (or, rather, the position of the points relative to the camera used to take them), and can trivially obtain the camera parameters, could I simply use ray-tracing through each point in my final point cloud to produce an RGB image? The image may need registration with the 'real' RGB image, or it probably won't since nothing will have actually moved except for rounding error.

Some questions about 2D polygon collision response

Hey so after reading this article I've been left with a few questions I hope to resolve here.
My understanding is that the goal of any multi-dimensional collision response is to convert it to a 1D collision be putting the bodies on some kind of shared axis. I've deduced from the article that the steps to responding to a 2d collision between 2 polygons is to
First find the velocity vector of each bodies collision point
Find relative velocity based on each collision point's velocity (see question 1)
Factor in how much of that velocity is along the the "force transfer line (see question 2)"
(which is the only velocity that matters for the collision)
Factor in elasticity
Factor in mass
Find impulse/ new linear velocity based on 2-4
Finally figure out new angular velocity by figuring out how much of the impulse is "rotating around" each object's CM (which is what determines angular acceleration)
All these steps basically figure out how much velocity each point is coming at the other with after each velocity is translated to a new 1D coordinate system, right?
Question 1: The article says relative velocity is meant to find and expression for the velocity with which the colliding points are approaching each other, but to me it seems as though is simply the vector of
CM 1 -> CM 2, with magnitude based on each point's velocity. I don't understand the reasoning behind even including the CMs in the calculations since it is the points colliding, not the CMs. Also, I like visualizing things, so how does relative velocity translate geometrically, and how does it work toward the goal of getting a 1D collision problem.
Question 2: The article states that the only force during the collision is in the direction perpendicular to the impacted edge, but how was this decided? Also how can they're only be force in one direction when each body is supposed to end up bouncing off in 2 different directions.
"All these steps basically figure out how much velocity each point is coming at the other with after each velocity is translated to a new 1D coordinate system, right?"
That seems like a pretty good description of steps 1 and 2.
"Question 1: The article says relative velocity is meant to find and expression for the velocity with which the colliding points are approaching each other, but to me it seems as though is simply the vector of CM 1 -> CM 2, with magnitude based on each point's velocity."
No, imagine both CMs almost stationary, but one rectangle rotating and striking the other. The relative velocity of the colliding points will be almost perpendicular to the displacement vector between CM1 and CM2.
"...How does relative velocity translate geometrically?"
Zoom in on the site of collision, just before impact. If you are standing on the collision point of one body, you see the collision point on the other point approaching you with a certain velocity (in your frame, the one in which you are standing still).
"...And how does it work toward the goal of getting a 1D collision problem?"
At the site of collision, it is a 1D collision problem.
"Question 2: The article states that the only force during the collision is in the direction perpendicular to the impacted edge, but how was this decided?"
It looks like an arbitrary decision to make the surfaces slippery, in order to make the problem easier to solve.
"Also how can [there] only be force in one direction when each body is supposed to end up bouncing off in 2 different directions."
Each body experiences a force in one direction. It departs in a certain direction, rotating with a certain angular velocity. I can't parse the rest of the question.

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.

Calculating rotation along a path

I am trying to animate an object, let's say its a car. I want it go from point
x1,y1,z1
to point x2,y2,z2 . It moves to those points, but it appears to be drifting rather than pointing in the direction of motion. So my question is: how can I solve this issue in my updateframe() event? Could you point me in the direction of some good resources?
Thanks.
First off how do you represent the road?
I recently done exactly this thing and I used Catmull-Rom splines for the road. To orient an object and make it follow the spline path you need to interpolate the current x,y,z position from a t that walks along the spline, then orient it along the Frenet Coordinates System or Frenet Frame for that particular position.
Basically for each point you need 3 vectors: the Tangent, the Normal, and the Binormal. The Tangent will be the actual direction you will like your object (car) to point at.
I choose Catmull-Rom because they are easy to deduct the tangents at any point - just make the (vector) difference between 2 other near points to the current one. (Say you are at t, pick t-epsilon and t+epsilon - with epsilon being a small enough constant).
For the other 2 vectors, you can use this iterative method - that is you start with a known set of vectors on one end, and you work a new set based on the previous one each updateframe() ).
You need to work out the initial orientation of the car, and the final orientation of the car at its destination, then interpolate between them to determine the orientation in between for the current timestep.
This article describes the mathematics behind doing the interpolation, as well as some other things to do with rotating objects that may be of use to you. gamasutra.com in general is an excellent resource for this sort of thing.
I think interpolating is giving the drift you are seeing.
You need to model the way steering works .. your update function should 1) move the car always in the direction of where it is pointing and 2) turn the car toward the current target .. one should not affect the other so that the turning will happen and complete more rapidly than the arriving.
In general terms, the direction the car is pointing is along its velocity vector, which is the first derivative of its position vector.
For example, if the car is going in a circle (of radius r) around the origin every n seconds then the x component of the car's position is given by:
x = r.sin(2πt/n)
and the x component of its velocity vector will be:
vx = dx/dt = r.(2π/n)cos(2πt/n)
Do this for all of the x, y and z components, normalize the resulting vector and you have your direction.
Always pointing the car toward the destination point is simple and cheap, but it won't work if the car is following a curved path. In which case you need to point the car along the tangent line at its current location (see other answers, above).
going from one position to another gives an object a velocity, a velocity is a vector, and normalising that vector will give you the direction vector of the motion that you can plug into a "look at" matrix, do the cross of the up with this vector to get the side and hey presto you have a full matrix for the direction control of the object in motion.

Resources