animating a plane(keyframe or may be path), ideally want ship to display its speed just like it can display its name (if checked true from object display settings) or at screen bottom(view3d) where selected object and frame number displays. started writing a simple function to get speed first. even this isn't working correctly, may be because view doesn't get refreshed as i run and it doesn't actually go to previous frame and capture location.

import bpy

def calcSpeed():
    ship = bpy.context.object
    cf = bpy.context.scene.frame_current
    pf = bpy.context.scene.frame_current - 1
    pl = ship.location
    cl = ship.location
    speedVector = pl - cl
    print (pf,cf)
    print (pl,cl)

any ideas or pseudo code will really help, huge thanks for time and support.


1 Answer 1


Using pl - cl will give you a vector that tells you how much you have moved on each axis, this is not normally the same as distance travelled which is the length of the diagonal line between the two points. You may recognise the equation c2 = a2 + b2 used to calculate triangle lengths which can be adapted to 3d points. If your object is moving on only one axis then you can do simple calculation of the locations on the one axis.

def distance(a, b) :
    """distance between two 3D points"""
    return sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2)

To draw the speed in the 3Dview, have a look at the bgl and blf modules. You can find some examples here

If you have animated the planes movement then you should get better results by using fcurve.evaluate(frame) to get the object location.

import bpy

ship = bpy.context.object
ship_curves = ship.animation_data.action.fcurves

def distance(a, b) :
    """distance between two 3D points"""
    return sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2)

x_curve = ship_curves.find('location', index=0)
y_curve = ship_curves.find('location', index=1)
z_curve = ship_curves.find('location', index=2)

for cur_frame in range(0,12):
    cur_x = x_curve.evaluate(cur_frame)
    cur_y = y_curve.evaluate(cur_frame)
    cur_z = z_curve.evaluate(cur_frame)
    cur_loc = (cur_x, cur_y, cur_z)

    prev_x = x_curve.evaluate(cur_frame-1)
    prev_y = y_curve.evaluate(cur_frame-1)
    prev_z = z_curve.evaluate(cur_frame-1)
    prev_loc = (prev_x, prev_y, prev_z)

    travelled = distance(cur_loc, prev_loc)

    print('Travelled {:>8.3f} since the last frame.'.format(travelled))

You must log in to answer this question.

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