The following CalculateProjectilePath function returns a Vector3[] path that a cannonball follows when fired, for a Unity game. Treat the path as a list of Bezier curve control points and change the function to return a Bezier curve instead. Also, since it's a Bezier curve, the number of control points could probably be reduced (but not TOO much).

public static class CannonballTrajectory
{
    private const double g = 9.8; // Acceleration due to gravity (m/s^2)

    public static Vector3[] CalculateProjectilePath(Vector3 aimVector, double muzzleVelocity)
    {
        Vector3[] path = new Vector3[100];

        for (int i = 0; i < 100; i++)
        {
            float t = i * 0.1f; // Time elapsed in seconds
            float x = aimVector.x * muzzleVelocity * t;
            float y = aimVector.y * muzzleVelocity * t - 0.5f * g * t * t;
            float z = aimVector.z * muzzleVelocity * t;
            path[i] = new Vector3(x, y, z);
        }

        return path;
    }
}