You may want to consider something like memoize to speed up recursive functions by using more memory. Essentially it stores the results of any call in a cache.
Add the following code
import collections
import functools
class memoized(object):
   '''Decorator. Caches a function's return value each time it is called.
   If called later with the same arguments, the cached value is returned
   (not reevaluated).
   '''
   def __init__(self, func):
      self.func = func
      self.cache = {}
   def __call__(self, *args):
      if not isinstance(args, collections.Hashable):
         # uncacheable. a list, for instance.
         # better to not cache than blow up.
         return self.func(*args)
      if args in self.cache:
         return self.cache[args]
      else:
         value = self.func(*args)
         self.cache[args] = value
         return value
   def __repr__(self):
      '''Return the function's docstring.'''
      return self.func.__doc__
   def __get__(self, obj, objtype):
      '''Support instance methods.'''
      return functools.partial(self.__call__, obj)
Then decorate your function like this
@memoized
def fun(x1, y1, x2, y2, n, r=[]):
    ...
Also be careful with your optional parameter. The list created by r = [] will actually be shared across all calls of f with an r. It is better to do something like this so a new list is created every time.
def fun(x1, y1, x2, y2, n, r=None):
    r = [] if r is None else r
A more Pythonic way of getting the length is like this
print len(fun(200, 400, 200, 0, 9))