@Override
  public final void draw(final Graphics2D g, final int no,
      final double rotation) {
    if(!doCaching) {
      setSeed(no);
      drawSegment(g);
      return;
    }
    final Rectangle2D bbox = getBoundingBox(SEG_NORM, rotation);
    if(oldBBox == null || !oldBBox.equals(bbox)) {
      invalidate();
      oldBBox = bbox;
    }
    final double dx = bbox.getMinX();
    final double dy = bbox.getMinY();
    final int width = doScale ? (int) Math.ceil(bbox.getWidth()
        * CACHE_SCALE) : (int) Math.ceil(bbox.getWidth());
    final int height = doScale ? (int) Math.ceil(bbox.getHeight()
        * CACHE_SCALE) : (int) Math.ceil(bbox.getHeight());
    final int bucket = getNextBucket(no);
    if(cache[bucket] == null) {
      setSeed(bucket);
      final BufferedImage img = new BufferedImage(width, height,
          BufferedImage.TYPE_INT_ARGB);
      final Graphics2D gfx = img.createGraphics();
      gfx.setColor(g.getColor());
      gfx.setStroke(g.getStroke());
      gfx.setRenderingHints(g.getRenderingHints());
      gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
          RenderingHints.VALUE_ANTIALIAS_ON);
      if(doScale) {
        gfx.scale(CACHE_SCALE, CACHE_SCALE);
      }
      gfx.translate(-dx, -dy);
      drawSegment(gfx);
      gfx.dispose();
      cache[bucket] = doScale ? img.getScaledInstance(
          (int) Math.ceil(bbox.getWidth()),
          (int) Math.ceil(bbox.getHeight()), Image.SCALE_SMOOTH)
          : img;
    }
    g.translate(dx, dy);
    g.drawImage(cache[bucket], 0, 0, null);
    // g.setColor(new Color(0x10ff00ff, true));
    // g.fill(new Rectangle2D.Double(0, 0, width, height));
  }