class SampleMixin(object):
    def sample(self, samples):
        """Samples a segment or path a given number of times, returning a list of Point objects.
            Remember that for a Bezier path, the points are not guaranteed to be distributed
            at regular intervals along the path. If you want to space your points regularly,
            use the `regularSample` method instead.

        .. figure:: sampling.png
           :scale: 50 %
           :alt: sample versus regularSample

           In the figure, the green ticks are generated by `sample`. These are evenly
           distributed by curve time, but because of the curvature of the curve, there
           are concentrations of samples around the tighter parts of the curve.

           The red ticks are generated by `regularSample`, which evenly spaces the
           samples along the length of the curve.

        """
        step = 1.0 / float(samples)
        t = 0.0
        samples = []
        while t <= 1.0:
            samples.append(self.pointAtTime(t))
            t += step
        if t != 1.0:
            samples.append(self.pointAtTime(1))
        return samples

    def regularSample(self, samples):
        """Samples a segment or path a given number of times, returning a list of Point objects,
        but ensuring that the points are regularly distributed along the length
        of the curve. This is an expensive operation because I am a lazy programmer."""

        return [self.pointAtTime(t) for t in self.regularSampleTValue(samples)]

    def regularSampleTValue(self, samples):
        """Sometimes you don't want the points, you just want a set of time values (t) which
        represent regular spaced samples along the curve. Use this method to get a list of time
        values instead of Point objects."""
        # Build LUT; could cache it *if* we knew when to invalidate
        lut = []
        length = self.length
        if length == 0:
            return []
        step = 1.0 / length
        t = 0
        while t <= 1.0:
            lut.append(
                (t, self.lengthAtTime(t))
            )  # Inefficient algorithm but computers are getting faster
            t += step
        desiredLength = 0.0
        rSamples = []
        while desiredLength < length:
            while len(lut) > 0 and lut[0][1] < desiredLength:
                lut.pop(0)
            if len(lut) == 0:
                break
            rSamples.append(lut[0][0])
            desiredLength += length / samples
        if rSamples[-1] != 1.0:
            rSamples.append(1.0)
        return rSamples
