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
