'Adaptively gets segments for plotting.
The adaptive sampling is done by recursively checking if three
points are almost collinear. If they are not collinear, then more
points are added between those points.
References
[1] Adaptive polygonal approximation of parametric curves,
Luiz Henrique de Figueiredo.'

def get_segments(self):

    if (self.only_integers or (not self.adaptive)):
        return super(LineOver1DRangeSeries, self).get_segments()
    else:
        f = lambdify([self.var], self.expr)
        list_segments = []
        def sample(p, q, depth):
            '    Samples    recursively    if    three    points    are    almost    collinear.\n                                                                For    depth    <    6,    points    are    added    irrespective    of    whether    they\n                                                                satisfy    the    collinearity    condition    or    not.    The    maximum    depth\n                                                                allowed    is    12.\n                                                                '
            np = import_module('numpy')
            random = (0.45 + (np.random.rand() * 0.1))
            xnew = (p[0] + (random * (q[0] - p[0])))
            ynew = f(xnew)
            new_point = np.array([xnew, ynew])
            if (depth > self.depth):
                list_segments.append([p, q])
            elif (depth < 6):
                sample(p, new_point, (depth + 1))
                sample(new_point, q, (depth + 1))
            elif ((p[1] is None) and (q[1] is None)):
                xarray = np.linspace(p[0], q[0], 10)
                yarray = list(map(f, xarray))
                if any(((y is not None) for y in yarray)):
                    for i in range((len(yarray) - 1)):
                        if ((yarray[i] is not None) or (yarray[(i + 1)] is not None)):
                            sample([xarray[i], yarray[i]], [xarray[(i + 1)], yarray[(i + 1)]], (depth + 1))
            elif ((p[1] is None) or (q[1] is None) or (new_point[1] is None) or (not flat(p, new_point, q))):
                sample(p, new_point, (depth + 1))
                sample(new_point, q, (depth + 1))
            else:
                list_segments.append([p, q])
        f_start = f(self.start)
        f_end = f(self.end)
        sample([self.start, f_start], [self.end, f_end], 0)
        return list_segments
