2
\$\begingroup\$

I'm making a 2D game. It involves the player swinging around a grapple hook in perfect circular motion, however, I want to make the cooldown for this ability based on predicted end position for the grapple hook. (I'll probably make it later based on the actual duration of the swing, but for learning purposes I want to try to accomplish this)

Image of a circle with three points.

Is there any consistent way to calculate how long it would take for point B to reach point C?

local radius = adventurer.position:Distance(self.hook.position)
local angularSpeed = self.hook.direction == 0 and 1200/radius or -1200/radius
local angle1 = math.atan2(adventurer.position.y - self.hook.obj.position.y, adventurer.position.x - self.hook.obj.position.x)
local angle2 = math.atan2(self.hook.endPosition.y - self.hook.obj.position.y, self.hook.endPosition.x - self.hook.obj.position.x)
return (angle2 - angle1) / angularSpeed

This is how I'm currently accomplishing it, and it works (granted it breaks based on the direction it's facing, but that can be fixed in the future). However, my results come up like this

 0.37500011637114
 0.37499976172673
 0.29999967327458
 0.30000022575076
 0.22499981690334
 0.22500003318263
 0.22499987895093
 0.150000220043
 0.14999986219868
 0.074999761129465
 0.075000182872622
 0.074999642457876
 0.074999641417049

Is there any way to get consistent time? Where the results would be more like

0.10
0.09
0.08
...

Instead of like

0.22
0.22
0.22
0.14
0.14
0.14
0.07
0.07
...
\$\endgroup\$
2
  • \$\begingroup\$ The math looks right. I'd guess the issue is in code not shown: updating the player position. Is it updated using delta time? Then the output will fluxuate based on changes in delta time. Also, if logging isn't done immediately after updating the player position (i.e., from draw), then you might see inconsistencies there too. \$\endgroup\$
    – idbrii
    Commented Mar 14, 2022 at 19:24
  • \$\begingroup\$ First guess is that it might be a floating point precision issue, but LUA should use doubles and you're not using that much precision. Next best guess is that atan2 is using a lookup table with too few entries, leading to the stepped result. Try running a range of very similar numbers through atan2 and see if you get continuous or discrete results. \$\endgroup\$
    – Basic
    Commented Jun 19, 2022 at 21:24

1 Answer 1

0
\$\begingroup\$

If I understood your problem correctly, you are experiencing one of the "catches" of floating point math - it will give you results like these with a lot of decimals at the end. You're likely best off rounding your number at the end - make sure you do this as little as possible and only before you actually need to present this to the user.

As an aside, this is why you should forget about comparing floating point numbers for equality - you will likely get a lot of false negatives even when the result "should" have been the same.

Another thing to keep in mind is that the more towards the right (= smaller parts of the decimal), the less uncertain the numbers become, so you should do your calculations on numbers with as close order of magnitude of possible - if you add a number that's a small fraction of 1 to a number that's a few million, you'll likely get garbage results...

\$\endgroup\$
3
  • \$\begingroup\$ Sorry for being unclear, I edited my answer a bit to explain the question better. I’m trying to get consistent results instead of the number jumping every 0.07 decimals \$\endgroup\$
    – Andrew M
    Commented Jan 20, 2022 at 17:25
  • 1
    \$\begingroup\$ A 32-bit float should be accurate to within 2^-26 or 0.000 000 015 in the range of angle values shown, so I don't think floating point error is sufficient to explain the jumps of ~0.07 observed here, unless both objects are far from the origin and we're getting catastrophic cancellation in the subtraction. \$\endgroup\$
    – DMGregory
    Commented Jun 20, 2022 at 11:46
  • \$\begingroup\$ @DMGregory good point, it does look like too much of a jump to be that, and it seems to be very consistently 0.075 every time +/- what is probably the actual round error (or a small range within which it is nice and continuous?) so the question is where this specific value emerges from \$\endgroup\$ Commented Jun 20, 2022 at 15:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .