# Why is my jump arc preview inaccurate?

I'm trying to draw an arc out of dots that previews a KinematicBody2D's trajectory after a jump but said preview always falls short of the body's actual jump and I cannot figure out why. Below is an example gif of what I'm talking about.

And this is the code I used in the example.

extends Node2D

var arcPoints = 40
var pointsPerSec = 12
var startYvelocity = -500
var velocity = Vector2(200, startYvelocity)
var gravity = 300

var startPosition = Vector2(96, 544)

func _draw():

var totalY = startPosition.y
var velY = startYvelocity
var calcGravity = gravity/pointsPerSec

for p in range(arcPoints):
velY += calcGravity
totalY += velY/pointsPerSec

var point = Vector2(startPosition.x+(velocity.x/pointsPerSec)*(p+1), totalY)
draw_circle(point, 2, 'fafafa')

pass

func _physics_process(delta):
velocity.y += gravity*delta
get_child(0).move_and_slide_with_snap(velocity, Vector2(0.0, 1.0), Vector2(0.0, -1.0))

• In trying to reproduce this in func _draw() I used var fps:float = 1.0 * Engine.iterations_per_second and overall to make more stuff more clear var startVelocity:Vector2 = Vector2(200, 100) and var startPosition:Vector2 = Vector2(96, 544) ... but could not fix it :-( – Clemens Tolboom Mar 22 at 14:11
• @ClemensTolboom I was able to create an accurate arc based on keelhaul's answer. If you want, when I get next have the opportunity, I can add my own answer showing the working script and why it works. – Javlin Joslin Mar 23 at 1:00
• Cool. Not sure to change the accepted answer from @Keelhaul but yeah I like an Godot answer ;-) – Clemens Tolboom Mar 24 at 16:15

By doing a preview with time increments different from your process, you're bound to have differences. For example, consider these extreme cases:

• You simulate a preview with 1 point per second: on the first step, your Yvelocty becomes -500 + 300 = -200, making it as if you started your jump with a speed of only 200 while it should be 500 in reality.
• You process the jump at 1000 frames per second: on the first step, your Yvelocty is -500 + 0.3 = -499.7, almost the "real" starting velocity.

Since actual gravity works in continuous time, you'll never have a "true" path by doing simple increments, even though the process framerate will be good enough not to notice. So you can either:

• Do your preview with the same time increments as your process. However, you don't know it precisely unless you fix your physics framerate, and it's really inefficient.
• Do your preview (and even your process) by applying the math on each point with a simple equation:
$$\y(t) = y + vy * t + \frac{1}{2} a t^2\$$ (Here in your example with y = 544, vy = -500, a = 300)

I let you guess wich solution is the best ;)

I wanted to show what applying Keelhaul's answer to a godot script would look like to try and add clarity to what the issue was. The Following is my modified script.

extends Node2D

var arcPoints = 120.0 #total number of points to draw
var arcFPS = 60.0
var PPF = 2.0 #points per frame

var startYvelocity = -500.0
var velocity = Vector2(200.0, startYvelocity)
var gravity = 300.0

var startPosition = Vector2(96.0, 544.0)

func _draw():

var totalY = startPosition.y
var velY = startYvelocity
var calcGravity = gravity/arcFPS
var stepsCompleted = 0

for p in range(arcPoints*PPF):
velY += calcGravity
totalY += velY/arcFPS
stepsCompleted += 1

if stepsCompleted == PPF:
stepsCompleted = 0
var point = Vector2(startPosition.x+(velocity.x/arcFPS)*(p+1), totalY)
draw_circle(point, 2, 'fafafa')