Open TokageItLab opened 1 day ago
Negative delta is intended to move towards the opposite angle (as stated by the docs), so this is indented behavior, it wasn't originally in the old PR though. I think it was assumed that the oscillation that occurred at the midway point would've been considered a bug so I "fixed" it after being given a different implementation by @kleonc, originally I even suggested adding 180 degrees to the target as a workaround for that in the old PR. So if the oscillation should to be the correct behavior that can be changed.
Going in the opposite direction and reaching the wrong target are two different things. The opposite direction might mean a path that is not the shortest, but at least should not reach the wrong target in term of rotation.
I think it was assumed that the oscillation that occurred at the midway point would've been considered a bug so I "fixed" it after being given a different implementation by @kleonc
Does the oscillation mean when the shortest path switches due to target movement? If so, such a problem should not occur if positive delta is interpreted as a counterclockwise rotation statically instead of an angle toward the shortest path, although compatibility will be broken. You can consider making it an optional argument rotate_toward(float p_from, float p_to, float p_delta, bool p_shortest = true)
or a separate API like rotate_toward_counterclockwise()
to prevent compatibility breakdown.
This is the code snippet of rotate_toward()
static _ALWAYS_INLINE_ double rotate_toward(double p_from, double p_to, double p_delta) {
double difference = Math::angle_difference(p_from, p_to);
double abs_difference = Math::abs(difference);
// When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance).
return p_from + CLAMP(p_delta, abs_difference - Math_PI, abs_difference) * (difference >= 0.0 ? 1.0 : -1.0);
}
So I guess it is intentional.
My take is that move_towards()
with negative delta moves the value as far from p_to
as possible, so the author wanted the angle to go as far from p_to
as possible.
@PhairZ I'm pointing out that the intent was wrong from the beginning. The direction of rotation is correct, but the destination angle is wrong.
@TokageItLab I think i disagree. -delta is intended to go as far as possible from target, not in the opposite direction. working around it is also not that much of a hassle since you can just multiply target by the sign of delta.
@PhairZ In that case, simply pass the inverted target as an argument, instead of inverting delta, as mentioned above. This can be accomplished in a few lines of code, so it does not have much worth of utility function.
Conversely, arbitrarily rotating the longest path cannot be accomplished in a few lines of code, so the behavior makes sense as a utility function.
Alright, I'll open a PR on this issue. It's up to the contributers to merge it or not.
You can consider making it an optional argument
rotate_toward(float p_from, float p_to, float p_delta, bool p_shortest = true)
or a separate API likerotate_toward_counterclockwise()
to prevent compatibility breakdown.
Negative delta usage seems like something that'd be very rarely used regardless, plus since getting the old behavior is rather easy this shouldn't be necessary. Otherwise if there are complaints that could just be addressed in a follow-up.
@ettiSurreal What I mean by compatibility breakdown is that we are talking about oscillation issues, not inverted targets.
The behavior of a negative delta reaching an inverted target definitely should be removed, and since there is a migration way of just inverting the target instead of the delta, there is no need to add an option for that.
There are two ways to go about what to treat as "positive" delta (shortest rotation is positobe, or mathematical positive radian is positive), and I think both are valid.
Tested versions
4.3
System information
Any
Issue description
rotate_toward()
is implemented by https://github.com/godotengine/godot/pull/80225, but set the incorrect target when delta is negative.move_toward()
when delta is negative, does not reach the original target and goes infinitely negative. It is correct.rotate_toward()
can still reach the original target even if delta is negative, but it will erroneously reach the inversed target.It makes complete no sense to reach the inverted target. If you wanted to do that, you could simply invert the to instead of delta when passing the argument in the first place. Also, if using negative delta result is reaching the inverted target, it means that you cannot use negative delta for rotating turrets with fixed rotation direction and the like.
Output:
rad neg by -0.31415926535898 x1
is-0.31415926535898
, not0.31415926535898
it is correct. Butrad neg by -0.31415926535898 x100
must be1.5707963267949
, not-1.5707963267949
. cc @ettiSurrealSteps to reproduce
Use
rotate_toward()
with negative delta to reach the original target.Minimal reproduction project (MRP)
wrong_rotate_toward_calc.zip