sclass Stripes implements MakesBufferedImage {
  int w, h;
  double angle; // radians
  new L<Color> colors;
  new DoubleList positionsInDirection;
  new L<DoublePt> pixelPositions;
  
  *() {}
  *(int *w, int *h, double *angle, DoubleList *positionsInDirection) {}
  *(int *w, int *h, double *angle, DoubleList *positionsInDirection, L<Color> *colors) {}
  
  public int getWidth() { ret w; }
  public int getHeight() { ret h; }
  
  public BufferedImage getBufferedImage() {
    var img = newBufferedImage(w, h, first(colors));
    var g = graphics(img);
    translateGraphics(g, w*.5, h*.5);
    rotateGraphicsClockwise_radians(g, angle);
    double bigNumber = (w+h)*2;
    int n = numberOfStripes()-1;
    for (int i = 0; i < n; i++) {
      double x1 = positionsInDirection.get(i);
      double x2 = getOr(positionsInDirection, i+1, bigNumber);
      Color color1 = or(cyclicGet(colors, i+1), Color.black);
      /*Color color2 = or(cyclicGet(colors, i+1), Color.white);
      if (eq(color1, color2))*/
        g.setColor(color1);
      /*else
        g.setPaint(new GradientPaint((float) x1, 0, color1, (float) x2, 0, color2));*/
        
      fillPrecisePolygon(g, ll(doublePt(x1, -bigNumber), doublePt(x2, -bigNumber),
        doublePt(x2, bigNumber), doublePt(x1, bigNumber)));
    }
    ret img;
  }
  
  int numberOfStripes() { ret l(positionsInDirection)+1; }
}