"Homing" function . Half cirle, not full.

R

RedSorcery

Guest
The way my homing bullet works now is, it'll smoothly arch towards the target if the target is in front of it.
If the bullet is behind the target, it needs to travel in a greater arc to catch up to the target. This will sometimes, given the right combo of rotation speed and speed, make the bullet circle around the target. Sometimes several rounds before hitting it. This is not my desired behavior.

I tried a few ideas with increasing the speed the closer it gets to the target, but there is always a "magic" combo of speed/rotation speed/distance that makes the bullet circle around the target.

Im looking for a way to make the bullet arc towards the target, without crossing its center y position. I have posted some amazing photoshop images to describe my idea.

Here is the current code:
GML:
if name == "Homing Missile"{ //if this is a seeking missile
    if (alarm0){alarm[0] = 60; alarm0 = false;}//timer to delay when homing missile "activates"
    if (alarm1){alarm[1] = 1; alarm1 = false;}//increase/decrease rocket speed
    dist = distance_to_point(target_x, target_y); //Keep track of distance to target/point
    //MOVE AND ROTATE TOWARDS TARGET
    rot_spd += (dist_max/dist); //Rotate faster the closer to target *GAME MAKER FORUM: THIS JUST HAPPENS TO BE THE FORMULA I TRIED AT THE TIME I POSTED THIS
    var target_point = point_direction(x, y, target_x, target_y); //what is the targets direction relative to bullet
    image_angle += sin(degtorad(target_point - image_angle))*rot_spd; //rotate image towards
    direction = image_angle;//move object in the direction its angle (facing)
    //TRACK TARGET LAST POSITION
    if instance_exists(target){ //if target exists
        target_x = target.x; //keep updating its last X position
        target_y = target.y; //keep updating its last Y position
    }
}else x += bullet_spd; //if this is any other weapon, use the designated speed
bullet homing 1.pngbullet homing 2.png
 

TailBit

Member
if the angle difference towards the target don't improve enough from the last time it turned, then that could be a indication for it that it is circling it .. and you can then delay the rotation or do some other countermeasures .. maybe it just spins til it face the target without turning, then turn the speed back up? or just slow down til the angle difference improves ?

Or .. it it gets behind it .. then it could just find the circle center point of the half moon and just trace it perfectly until it faces its target

Or .. just check the angle_difference .. maybe measure how big the half circle is and speed of the missile to calculate how many steps you want the missile to turn, then just take the angle_difference and flatten it out over those steps
GML:
tdir = point_direction(target);
diff = angle_difference(dir,tdir); // could be that I got them in the wrong order here
direction += diff / steps_to_adjust * current_step
 
Last edited:

samspade

Member
The way my homing bullet works now is, it'll smoothly arch towards the target if the target is in front of it.
If the bullet is behind the target, it needs to travel in a greater arc to catch up to the target. This will sometimes, given the right combo of rotation speed and speed, make the bullet circle around the target. Sometimes several rounds before hitting it. This is not my desired behavior.

I tried a few ideas with increasing the speed the closer it gets to the target, but there is always a "magic" combo of speed/rotation speed/distance that makes the bullet circle around the target.

Im looking for a way to make the bullet arc towards the target, without crossing its center y position. I have posted some amazing photoshop images to describe my idea.

Here is the current code:
GML:
if name == "Homing Missile"{ //if this is a seeking missile
    if (alarm0){alarm[0] = 60; alarm0 = false;}//timer to delay when homing missile "activates"
    if (alarm1){alarm[1] = 1; alarm1 = false;}//increase/decrease rocket speed
    dist = distance_to_point(target_x, target_y); //Keep track of distance to target/point
    //MOVE AND ROTATE TOWARDS TARGET
    rot_spd += (dist_max/dist); //Rotate faster the closer to target *GAME MAKER FORUM: THIS JUST HAPPENS TO BE THE FORMULA I TRIED AT THE TIME I POSTED THIS
    var target_point = point_direction(x, y, target_x, target_y); //what is the targets direction relative to bullet
    image_angle += sin(degtorad(target_point - image_angle))*rot_spd; //rotate image towards
    direction = image_angle;//move object in the direction its angle (facing)
    //TRACK TARGET LAST POSITION
    if instance_exists(target){ //if target exists
        target_x = target.x; //keep updating its last X position
        target_y = target.y; //keep updating its last Y position
    }
}else x += bullet_spd; //if this is any other weapon, use the designated speed
View attachment 35006View attachment 35007
The real issue is that's not really how homing works. In a pure homing system either the missile would have enough steering power to do a better job of seeking the object and not overshoot in a straight line, or it wouldn't, in which case it would probably arc around in a slow orbit, getting close and closer.

To achieve something like the first picture, your missile would need something like state, where its homing ability gets better after it passes the object, or something like that.
 
The two pictures show two vastly different approaches to tracking/course correction. This is a bit of an explanation of what is going on:
screenshot(18).png screenshot(19).png

Unfortunately, I can't be of any help explaining how to achieve the latter. You're doing literal rocket science at that point.
 

rytan451

Member
Let's simplify the problem. Let's find a way to determine if the missile can reach the target, if it turns at a maximum angle per frame.

Let theta be the angle between the homing missile's direction and the line between the homing missile and the target. (So, if you add theta to the direction of the homing missile, it will point straight to the target.) Let d be the distance between the missile and the target.

Let the point O be the center of the circular arc. Let A be the starting point of the missile, and B the the target. Let d be the distance between the missile and the target.

Since A and B are both on a circle around O, AO = BO, and therefore triangle ABO is isosceles.

We find that the measure of angle BAO = 90 - theta degrees. Because ABO is isosceles, we find that the measure of angle ABO is the same. Therefore, since the sum of internal angles in a triangle is 180 degrees, the measure of angle AOB is 2*theta.

Now, let us attempt to find the radius AO.

Let r = AO.

We know that the length AB = d (by definition of d).

By the law of cosines, we have that 2r^2 - 2r^2 cos(2 theta) = d^2. We solve for r:

r^2(2 - 2cos(2 * theta)) = d^2
r^2 = d^2/(2 - 2 cos(2 * theta))
r = d / sqrt(2 - 2 cos(2 * theta))

Notice that r is undefined when cos(theta) = 1, and is real for all other values of theta. This occurs in two special cases. The first is the special case where the missile is already flying straight towards the target. If this is the case, then you can just use a very simple "move at a constant velocity towards the target". The second is where the missile is flying directly away from the target. This case will be covered outside the spoiler.

Thus, since we know the distance r of the center of the arc from the missile, and we know the direction the center of the arc is in relative to the missile (perpendicular to the direction of the missile), we know the position of center of the arc.

From here, it should be relatively trivial to move the missile at a constant speed along a circle. Here's the basic math:

Given that the missile moves at s units per frame, and it is traveling along a circular arc of radius r, it moves at s/r radians per frame around the center. In degrees, this is (180*s)/(r*pi). This means that it rotates at that same rate.

TL;DR:

If the missile is pointing straight towards the target or straight away from the target, it can reach the target.

Let s be the distance the missile moves per frame.
Let d be the distance between the missile and the target.
Let theta be the angle between the missile's direction and the direction of the target.
Let r = d / sqrt(2 - 2 * cos(2 * theta))
If the missile were to reach the target by traveling on a circle, it must be capable of turning at a rate of (180*s)/(r*pi) degrees per frame, or s/r radians per frame.

If the missile is not capable of turning at that rate, then the missile should fly straight forwards. This will eventually give it the space to maneuver to hit the target. If you turn, you end up circling the target, so don't turn.
If the missile is capable of turning at that rate, then you should turn the missile towards the target at your given rate and keep flying.
 
Top