Curvature data to coordinates I want to determine a path (x and y coordinates) by using curvature data (radius, with constant distance (length_of_arc) travelled between data points. I want to repeat this calculation every 0.010 seconds and visualize the points in pyhon kivy (at the moment a raw calculation takes 0.006 - 0.014 seconds). 

Assume sample data 

radius = [68.96551724, 69.73500697, 71.78750897, 75.98784195, 81.96721311, 90.74410163, 102.6694045, 120.0480192,
          146.1988304, 187.9699248, 265.9574468, 458.7155963, 1694.915254, -1020.408163, -393.7007874, -244.4987775]


This is the code (inside a class) that I use to calculate the coordinates. Is there a way to increase performance / readability of the code. It is important to note that performance has higher priority.

EDIT: I already tried small angle approximation (sin x \approx x, cos x \approx 1 - 0.5 x^2) but that did only lead to insignificant changes.

# positive curvature is a right bend, negative curvature is a left bend
# scale_factor: used to scale the values for plotting them
# initial_displacement_x and initial_displacement_y: values are displaced such that the plot is in the Center of the screen.
@staticmethod
def calculate_coordinates_from_length_of_arc_and_radius(_radius, length_of_arc, scale_factor,
                                                    initial_displacement_x, initial_displacement_y):
    phi = 0  # accumulation of angle
    number_of_data_points = len(_radius)
    x_accumulated = number_of_data_points * [0]
    y_accumulated = number_of_data_points * [0]
    track_coordinates = 2 * number_of_data_points * [0] # x,y alternating needed for ploting values as line in python kivy

    for data_point in range(number_of_data_points - 1):
        delta_phi = - length_of_arc / _radius[data_point]
        phi = phi + delta_phi
        dx = - _radius[data_point] * (cos(delta_phi) - 1)
        dy = - _radius[data_point] * sin(delta_phi)

        if data_point != 0:
            dx_rotated = cos(phi) * dx - sin(phi) * dy # apply rotation matrix
            dy_rotated = sin(phi) * dx + cos(phi) * dy # apply rotation matrix
        else:
            dx_rotated = dx  # the displacements are not rotated
            dy_rotated = dy  # for the first data point

        x_accumulated[data_point + 1] = x_accumulated[data_point] + dx_rotated
        y_accumulated[data_point + 1] = y_accumulated[data_point] + dy_rotated
        track_coordinates[2 * data_point + 2] = scale_factor * (x_accumulated[data_point] + dx_rotated)
        track_coordinates[2 * data_point + 3] = scale_factor * (y_accumulated[data_point] + dy_rotated)

    for data_point in range(len(track_coordinates)):
        if data_point % 2:
            track_coordinates[data_point] = track_coordinates[data_point] + initial_displacement_x
        elif not data_point % 2:
            track_coordinates[data_point] = track_coordinates[data_point] + initial_displacement_y
    return track_coordinates
If you are doing a lot of numerical calculations in Python and want them to be fast, you should use numpy, a package specifically for this purpose.

It allows you to write your code in a vectorized way, making it easer to understand at the same time:

import numpy as np

@staticmethod
def arc_coordinates(_radius, length_of_arc, scale_factor, x0, y0):
    """
    positive curvature is a right bend, negative curvature is a left bend
    scale_factor: used to scale the values for plotting them
    x0 and y0: values are displaced such that the plot is in the center of the screen.
    """
    radius = np.array(_radius)
    delta_phi = - length_of_arc / radius
    phi = np.cumsum(delta_phi)
    dx = - radius * (np.cos(delta_phi) - 1)
    dy = - radius * np.sin(delta_phi)
    track_coordinates = np.vstack([dx, dy]).T
    track_coordinates[1:, 0] = np.cos(phi[1:]) * dx[1:] - np.sin(phi[1:]) * dy[1:]
    track_coordinates[1:, 1] = np.sin(phi[1:]) * dx[1:] + np.cos(phi[1:]) * dy[1:]
    track_coordinates = scale_factor * np.cumsum(track_coordinates, axis=0) + np.array([[y0, x0]])
    track_coordinates = np.concatenate([np.array([y0, x0]), track_coordinates.flatten()[:-2]])
    return track_coordinates


This gives the same results as your code. Note that it (just like your code) uses the weird convention that the output array is flat, alternating between x and y values, starting with a y-value.

On my machine this is not actually faster than your implementation, though:

%timeit arc_coordinates(radius, 1, 1, 0, 0)
39.4 µs ± 849 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit calculate_coordinates_from_length_of_arc_and_radius(radius, 1, 1, 0, 0)
21.5 µs ± 457 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)


However, this probably has a few possibilities for improvement left (WIP).

I also renamed your function to a (hopefully) also clear but shorter name as well as the initial displacements. I also made your comment detailing the parameters a docstring.