Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

367
LINES

< > BotCompany Repo | #668 // Reproducing Heisenberg v8 (slanted lines)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (2543L/17K/54K).

!752

static RGBImage originalImage;
static int imageWidth = 200;

!include #1000522 // helper functions for image reproduction

p {
  String imageID = "#1000326"; // Bryan Cranston!
  if (args.length != 0) imageID = args[0];
  final String _imageID = imageID;
  
  JFrame frame = new JFrame("A JavaX Frame");
  final new ImageSurface imageSurface;
  frame.add(imageSurface);
  frame.setBounds(100, 100, 300, 300);
  frame.setVisible(true);
  exitOnFrameClose(frame);
  
  thread {
    originalImage = loadImage(_imageID);
    originalImage = resizeToWidth(originalImage, imageWidth);
    reproduceOpenEnd(originalImage, imageSurface);
  }
}

static abstract class Params {
  RGBImage originalImage;
  abstract RGBImage render();
  abstract Params copy();
  
  void baseClone(Params p) {
    p.originalImage = originalImage;
  }
  
  RGBImage rendered;
  RGBImage getImage() {
    if (rendered == null)
      rendered = render();
    return rendered;
  }
  
  double score = 2.0;
  double getScore() {
    if (score == 2.0)
      score = calcScore();
    return score;
  }
  
  double calcScore() {
    return diff(originalImage, getImage());
  }
  
  boolean isBetterThan(Params p) {
    return getScore() < p.getScore();
  }
}

static class SlantedSplit extends Params {
  double splitPointL, splitPointR;
  RGB col1, col2;
  boolean swap;
  
  SlantedSplit copy() {
    SlantedSplit p = new SlantedSplit();
    baseClone(p);
    p.splitPointL = splitPointL;
    p.splitPointR = splitPointR;
    p.col1 = col1;
    p.col2 = col2;
    p.swap = swap;
    return p;
  }
  
  public String toString() {
    return (swap ? "SlantedHSplit " : "SlantedVSplit ") + splitPointL + " " + splitPointR + " " + col1 + " " + col2;
  }

  RGBImage render() {
    int w = originalImage.getWidth(), h = originalImage.getHeight();
    RGBImage image = new RGBImage(w, h, Color.white);
    slantedSplit(image, this);
    return image;
  }
}

static class Solid extends Params {
  RGB col;
  
  Solid copy() {
    Solid p = new Solid();
    baseClone(p);
    p.col = col;
    return p;
  }
  
  public String toString() {
    return "Solid " + col;
  }

  RGBImage render() {
    int w = originalImage.getWidth(), h = originalImage.getHeight();
    return new RGBImage(w, h, col);
  }
}

interface Reproducer {
  public Params reproduce(RGBImage original);
}

static class RandomSlantedSplit implements Reproducer {
  int n = -1;
  public Params reproduce(RGBImage original) {
    ++n;
    SlantedSplit p = new SlantedSplit();
    p.swap = random(2) == 0;
    p.originalImage = original;
    p.splitPointL = random();
    p.splitPointR = random();
    if (n % 2 == 0) {
      p.col1 = randomColor();
      p.col2 = randomColor();
    } else {
      p.col1 = probeRandomPixel(original);
      p.col2 = probeRandomPixel(original);
    }
    return p;
  }
}

static class RandomSolid implements Reproducer {
  int n = -1;
  public Params reproduce(RGBImage original) {
    ++n;
    Solid p = new Solid();
    p.originalImage = original;
    if (n % 2 == 0) {
      p.col = randomColor();
    } else {
      p.col = probeRandomPixel(original);
    }
    return p;
  }
}

static class VaryBest implements Reproducer {
  Reproducer base;
  Params best;
  
  VaryBest(Reproducer base) {
    this.base = base;
  }
  
  public Params reproduce(RGBImage original) {
    Params p = base.reproduce(original);
    if (best == null || p.isBetterThan(best))
      best = p;
    Params variation = vary(best);
    //System.out.println("Best: " + best.getScore() + ", variation: " + variation.getScore());
    if (variation.isBetterThan(best)) {
      //System.out.println("Using variation, diff=" + (best.getScore()-variation.getScore()));
      best = variation;
    }
    return best;
  }
  
  Params vary(Params p) {
    if (p instanceof SlantedSplit) {
      SlantedSplit n = ((SlantedSplit) p).copy();
      int s = random(3);
      if (s == 0)
        varySplitPoint(n);
      else if (s == 1)
        n.col1 = varyColor(n.col1);
      else
        n.col2 = varyColor(n.col2);
      return n;
    } else if (p instanceof Solid) {
      Solid n = ((Solid) p).copy();
      n.col = varyColor(n.col);
      return n;
    }
    return null;
  }
  
  void varySplitPoint(SlantedSplit p) {
    if (random(2) == 0)
      p.splitPointL = Math.max(0, Math.min(1, p.splitPointL+random(-0.1, 0.1)));
    else
      p.splitPointR = Math.max(0, Math.min(1, p.splitPointR+random(-0.1, 0.1)));
  }
  
  float varyChannel(float x) {
    return Math.max(0f, Math.min(1f, (float) (x+random(-0.1, 0.1))));
  }
  
  RGB varyColor(RGB rgb) {
    int s = random(3);
    if (s == 0)
      return new RGB(varyChannel(rgb.r), rgb.g, rgb.b);
    else if (s == 1)
      return new RGB(rgb.r, varyChannel(rgb.g), rgb.b);
    else
      return new RGB(rgb.r, rgb.g, varyChannel(rgb.b));
  }
}

static class Alternate implements Reproducer {
  int n = -1;
  Reproducer[] list;
  
  Alternate(Reproducer... list) {
    this.list = list;
  }
  
  public Params reproduce(RGBImage original) {
    ++n;
    return list[n % list.length].reproduce(original);
  }
}

interface ReproducerMaker {
  public Reproducer make();
}

static class Gridded extends Params {
  int w, h;
  Params[] array;
  
  Gridded(int w, int h) {
    this.w = w;
    this.h = h;
    array = new Params[w*h];
  }
  
  Gridded copy() {
    Gridded p = new Gridded(w, h);
    baseClone(p);
    for (int i = 0; i < w*h; i++)
      p.array[i] = array[i].copy();
    return p;
  }
  
  public String toString() {
    StringBuilder buf = new StringBuilder("grid{");
    for (int i = 0; i < w*h; i++) {
      if (i != 0)
        buf.append(", ");
      buf.append(array[i]);
    }
    return buf + "}";
  }
  
  public RGBImage render() {
    int ow = originalImage.getWidth(), oh = originalImage.getHeight();
    RGBImage img = new RGBImage(ow, oh, Color.white);
    for (int y = 0; y < h; y++)
      for (int x = 0; x < w; x++) {
        int x1 = x*ow/w, y1 = y*oh/h;
        int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h;
        RGBImage part = array[y*w+x].render();
        main.copy(part, 0, 0, img, x1, y1, part.getWidth(), part.getHeight());
      }
    return img;
  }
}

static class Grid implements Reproducer {
  int w, h;
  Reproducer[] bases;
  
  Grid(ReproducerMaker maker, int w, int h) {
    this.w = w;
    this.h = h;
    bases = new Reproducer[w*h];
    for (int i = 0; i < w*h; i++)
      bases[i] = maker.make();
  }
  
  RGBImage getGridElement(RGBImage originalImage, int i) {
    int ow = originalImage.getWidth(), oh = originalImage.getHeight();
    int y = i / w;
    int x = i % w;
    int x1 = x*ow/w, y1 = y*oh/h;
    int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h;
    return originalImage.clip(x1, y1, x2-x1, y2-y1);
  }
    
  public Params reproduce(RGBImage original) {
    Gridded gridded = new Gridded(w, h);
    gridded.originalImage = original;
    for (int i = 0; i < w*h; i++) {
      RGBImage img = getGridElement(original, i);
      Params p = bases[i].reproduce(img);
      if (p == null)
        return null;
      gridded.array[i] = p;
    }
    return gridded;
  }
}

static ReproducerMaker baseMaker = new ReproducerMaker() {
  public Reproducer make() {
    return new VaryBest(
      new Alternate(
        new RandomSolid(), new RandomSlantedSplit()
      ));
  }
};
  
// main reproduce function
static Reproducer reproducer =
  new Alternate(
    baseMaker.make(),
    new Grid(baseMaker, 4, 4),
    new Grid(baseMaker, 16, 8)
  );

static Params reproduce(RGBImage original) {
  int w = original.getWidth(), h = original.getHeight();
  return reproducer.reproduce(original);
}

static void reproduceOpenEnd(RGBImage original, ImageSurface imageSurface) {
  Params best = null;
  long lastPrint = 0, lastN = 0;
  for (long ntry = 1; ; ntry++) {
    long now = System.currentTimeMillis();
    if (now >= lastPrint+1000) {
      long tps = (ntry-lastN)*1000/(now-lastPrint);
      lastPrint = now;
      lastN = ntry;
      String s = "Try " + ntry + " (" + tps + "/s)";
      if (best == null)
        System.out.println(s);
      else {
        System.out.println("Best: " + best);
        System.out.println(s + ", score: " + formatDouble(best.getScore()*100, 2) + "%, structure size: " + structureSize(best, Params.class));
      }
    }
    Params p = reproduce(original);
    if (best == null || p != null && p.getScore() < best.getScore()) {
      //System.out.println("New best! " + p.getScore());
      best = p;
      imageSurface.setImage(p.getImage());
    }
    
    if (p != null && p.getScore() == 0.0)
      break;
  }
}

static void slantedSplit(RGBImage img, SlantedSplit p) {
  int w = img.getWidth(), h = img.getHeight();
  for (int yy = 0; yy < h; yy++)
    for (int xx = 0; xx < w; xx++) {
      double x = ((double) xx)/(w-1);
      double y = ((double) yy)/(h-1);
      if (p.swap) {
        double temp = x; x = y; y = x;
      }
      double splitPoint = mix(p.splitPointL, p.splitPointR, x);
      RGB col = y <= splitPoint ? p.col1 : p.col2;
      img.setPixel(xx, yy, col);
    }
}

Author comment

Began life as a copy of #666

download  show line numbers  debug dex  old transpilations   

Relations

Travelled to 17 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, qbtsjoyahagl, teubizvjbppd, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #668
Snippet name: Reproducing Heisenberg v8 (slanted lines)
Eternal ID of this version: #668/1
Text MD5: 047e0a72771688706b364ff7cc410545
Transpilation MD5: 7601c0de9c41269da6d58cf9be3f07b1
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-08-20 15:27:16
Source code size: 9414 bytes / 367 lines
Pitched / IR pitched: No / No
Views / Downloads: 762 / 791
Referenced in: [show references]