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

447
LINES

< > BotCompany Repo | #1000541 // Magnets

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

Libraryless. Click here for Pure Java version (1693L/12K/37K).

1  
!636
2  
3  
import java.awt.*;
4  
import java.awt.image.*;
5  
import javax.imageio.*;
6  
import static java.lang.Math.*;
7  
8  
!standard functions
9  
!image classes
10  
!FrameWithImages
11  
!quicknew
12  
!* ctr
13  
!721 // thread {
14  
15  
class P { double x, y; *(double *x, double *y) {} }
16  
17  
interface Reproducer {
18  
  public main.Params reproduce(RGBImage original);
19  
}
20  
  
21  
interface ReproducerMaker {
22  
  public Reproducer make();
23  
}
24  
25  
main {
26  
  static int imageWidth = 200;
27  
  
28  
  !include #1000522 // helper functions for image reproduction
29  
  
30  
  static double pi = PI;
31  
  
32  
  static double rotate_x(P p, double angle) {
33  
    angle = angle*pi/180;
34  
    return p.x*cos(angle)-p.y*sin(angle);
35  
  }
36  
  
37  
  static class Magnet extends Params {
38  
    double cx, cy, angle;
39  
    RGB col1 = new RGB(Color.black), col2 = new RGB(Color.white);
40  
    
41  
    RGB def(double x, double y) {
42  
      P p = new P(x-cx, y-cy);
43  
      x = rotate_x(p, -angle);
44  
      return x < 0 ? col1 : col2;
45  
    }
46  
    
47  
    Magnet copy() {
48  
      new Magnet p;
49  
      baseClone(p);
50  
      p.cx = cx;
51  
      p.cy = cy;
52  
      p.angle = angle;
53  
      p.col1 = col1;
54  
      p.col2 = col2;
55  
      return p;
56  
    }
57  
    
58  
    public String toString() {
59  
      return "M " + formatDouble(cx, 2) + " " + formatDouble(cy, 2) + " " + (int) angle + " " + col1 + " " + col2;
60  
    }
61  
62  
    RGBImage render() {
63  
      int w = originalImage.getWidth(), h = originalImage.getHeight();
64  
      RGBImage image = new RGBImage(w, h, Color.white);
65  
      paint(image, this);
66  
      return image;
67  
    }
68  
  }
69  
70  
  static abstract class Params {
71  
    RGBImage originalImage;
72  
    abstract RGBImage render();
73  
    abstract Params copy();
74  
    
75  
    void baseClone(Params p) {
76  
      p.originalImage = originalImage;
77  
    }
78  
    
79  
    RGBImage rendered;
80  
    RGBImage getImage() {
81  
      if (rendered == null)
82  
        rendered = render();
83  
      return rendered;
84  
    }
85  
    
86  
    double score = 2.0;
87  
    double getScore() {
88  
      if (score == 2.0)
89  
        score = calcScore();
90  
      return score;
91  
    }
92  
    
93  
    double calcScore() {
94  
      return diff(originalImage, getImage());
95  
    }
96  
    
97  
    boolean isBetterThan(Params p) {
98  
      return getScore() < p.getScore();
99  
    }
100  
  }
101  
  
102  
  static class SlantedSplit extends Params {
103  
    double splitPointL, splitPointR;
104  
    RGB col1, col2;
105  
    boolean swap;
106  
    
107  
    SlantedSplit copy() {
108  
      SlantedSplit p = new SlantedSplit();
109  
      baseClone(p);
110  
      p.splitPointL = splitPointL;
111  
      p.splitPointR = splitPointR;
112  
      p.col1 = col1;
113  
      p.col2 = col2;
114  
      p.swap = swap;
115  
      return p;
116  
    }
117  
    
118  
    public String toString() {
119  
      return (swap ? "SlantedHSplit " : "SlantedVSplit ") + splitPointL + " " + splitPointR + " " + col1 + " " + col2;
120  
    }
121  
122  
    RGBImage render() {
123  
      int w = originalImage.getWidth(), h = originalImage.getHeight();
124  
      RGBImage image = new RGBImage(w, h, Color.white);
125  
      slantedSplit(image, this);
126  
      return image;
127  
    }
128  
  }
129  
  
130  
  static class RandomMagnet implements Reproducer {
131  
    int n = -1;
132  
    public Params reproduce(RGBImage original) {
133  
      ++n;
134  
      new Magnet p;
135  
      p.originalImage = original;
136  
      p.cx = random();
137  
      p.cy = random();
138  
      p.angle = random()*360;
139  
      if (n % 2 == 0) {
140  
        p.col1 = randomColor();
141  
        p.col2 = randomColor();
142  
      } else {
143  
        p.col1 = probeRandomPixel(original);
144  
        p.col2 = probeRandomPixel(original);
145  
      }
146  
      return p;
147  
    }
148  
  }
149  
  
150  
  static class RandomSlantedSplit implements Reproducer {
151  
    int n = -1;
152  
    public Params reproduce(RGBImage original) {
153  
      ++n;
154  
      SlantedSplit p = new SlantedSplit();
155  
      p.swap = random(2) == 0;
156  
      p.originalImage = original;
157  
      p.splitPointL = random();
158  
      p.splitPointR = random();
159  
      if (n % 2 == 0) {
160  
        p.col1 = randomColor();
161  
        p.col2 = randomColor();
162  
      } else {
163  
        p.col1 = probeRandomPixel(original);
164  
        p.col2 = probeRandomPixel(original);
165  
      }
166  
      return p;
167  
    }
168  
  }
169  
  
170  
  static class VaryBest implements Reproducer {
171  
    Reproducer base;
172  
    Params best;
173  
    
174  
    VaryBest(Reproducer base) {
175  
      this.base = base;
176  
    }
177  
    
178  
    public Params reproduce(RGBImage original) {
179  
      Params p = base.reproduce(original);
180  
      if (best == null || p.isBetterThan(best))
181  
        best = p;
182  
      Params variation = vary(best);
183  
      //System.out.println("Best: " + best.getScore() + ", variation: " + variation.getScore());
184  
      if (variation.isBetterThan(best)) {
185  
        //System.out.println("Using variation, diff=" + (best.getScore()-variation.getScore()));
186  
        best = variation;
187  
      }
188  
      return best;
189  
    }
190  
    
191  
    Params vary(Params p) {
192  
      if (p instanceof SlantedSplit) {
193  
        SlantedSplit n = ((SlantedSplit) p).copy();
194  
        int s = random(3);
195  
        if (s == 0)
196  
          varySplitPoint(n);
197  
        else if (s == 1)
198  
          n.col1 = varyColor(n.col1);
199  
        else
200  
          n.col2 = varyColor(n.col2);
201  
        return n;
202  
      }
203  
      
204  
      if (p instanceof Magnet) {
205  
        Magnet n = ((Magnet) p).copy();
206  
        int s = random(3);
207  
        if (s == 0) {
208  
          s = random(3);
209  
          if (s == 0)
210  
            n.cx = varyN(n.cx);
211  
          else if (s == 1)
212  
            n.cy = varyN(n.cy);
213  
          else {
214  
            //double old = n.angle;
215  
            n.angle = (n.angle+360+random(-5, 5)) % 360;
216  
            //System.out.println("angle: " + formatDouble(old, 1) + " -> " + formatDouble(n.angle, 1));
217  
          }
218  
        } else if (s == 1)
219  
          n.col1 = varyColor(n.col1);
220  
        else
221  
          n.col2 = varyColor(n.col2);
222  
        return n;
223  
      }
224  
      
225  
      return null;
226  
    }
227  
    
228  
    void varySplitPoint(SlantedSplit p) {
229  
      if (random(2) == 0)
230  
        p.splitPointL = Math.max(0, Math.min(1, p.splitPointL+random(-0.1, 0.1)));
231  
      else
232  
        p.splitPointR = Math.max(0, Math.min(1, p.splitPointR+random(-0.1, 0.1)));
233  
    }
234  
    
235  
    double varyN(double x) {
236  
      return Math.max(0, Math.min(1, x+random(-0.1, 0.1)));
237  
    }
238  
    
239  
    float varyChannel(float x) {
240  
      return Math.max(0f, Math.min(1f, (float) (x+random(-0.1, 0.1))));
241  
    }
242  
    
243  
    RGB varyColor(RGB rgb) {
244  
      int s = random(3);
245  
      if (s == 0)
246  
        return new RGB(varyChannel(rgb.r), rgb.g, rgb.b);
247  
      else if (s == 1)
248  
        return new RGB(rgb.r, varyChannel(rgb.g), rgb.b);
249  
      else
250  
        return new RGB(rgb.r, rgb.g, varyChannel(rgb.b));
251  
    }
252  
  }
253  
254  
  static class Gridded extends Params {
255  
    int w, h;
256  
    Params[] array;
257  
    
258  
    Gridded(int w, int h) {
259  
      this.w = w;
260  
      this.h = h;
261  
      array = new Params[w*h];
262  
    }
263  
    
264  
    Gridded copy() {
265  
      Gridded p = new Gridded(w, h);
266  
      baseClone(p);
267  
      for (int i = 0; i < w*h; i++)
268  
        p.array[i] = array[i].copy();
269  
      return p;
270  
    }
271  
    
272  
    public String toString() {
273  
      StringBuilder buf = new StringBuilder("grid{");
274  
      for (int i = 0; i < w*h; i++) {
275  
        if (i != 0)
276  
          buf.append(", ");
277  
        buf.append(array[i]);
278  
      }
279  
      return buf + "}";
280  
    }
281  
    
282  
    public RGBImage render() {
283  
      int ow = originalImage.getWidth(), oh = originalImage.getHeight();
284  
      RGBImage img = new RGBImage(ow, oh, Color.white);
285  
      for (int y = 0; y < h; y++)
286  
        for (int x = 0; x < w; x++) {
287  
          int x1 = x*ow/w, y1 = y*oh/h;
288  
          int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h;
289  
          RGBImage part = array[y*w+x].render();
290  
          main.copy(part, 0, 0, img, x1, y1, part.getWidth(), part.getHeight());
291  
        }
292  
      return img;
293  
    }
294  
  }
295  
  
296  
  static class Grid implements Reproducer {
297  
    int w, h;
298  
    Reproducer[] bases;
299  
    
300  
    Grid(ReproducerMaker maker, int w, int h) {
301  
      this.w = w;
302  
      this.h = h;
303  
      bases = new Reproducer[w*h];
304  
      for (int i = 0; i < w*h; i++)
305  
        bases[i] = maker.make();
306  
    }
307  
    
308  
    RGBImage getGridElement(RGBImage originalImage, int i) {
309  
      int ow = originalImage.getWidth(), oh = originalImage.getHeight();
310  
      int y = i / w;
311  
      int x = i % w;
312  
      int x1 = x*ow/w, y1 = y*oh/h;
313  
      int x2 = (x+1)*ow/w, y2 = (y+1)*oh/h;
314  
      return originalImage.clip(x1, y1, x2-x1, y2-y1);
315  
    }
316  
      
317  
    public Params reproduce(RGBImage original) {
318  
      Gridded gridded = new Gridded(w, h);
319  
      gridded.originalImage = original;
320  
      for (int i = 0; i < w*h; i++) {
321  
        RGBImage img = getGridElement(original, i);
322  
        Params p = bases[i].reproduce(img);
323  
        if (p == null)
324  
          return null;
325  
        gridded.array[i] = p;
326  
      }
327  
      return gridded;
328  
    }
329  
  }
330  
  
331  
  static ReproducerMaker baseMaker = new ReproducerMaker() {
332  
    public Reproducer make() {
333  
      //return new VaryBest(new RandomSlantedSplit());
334  
      return new VaryBest(new RandomMagnet());
335  
    }
336  
  };
337  
    
338  
  // main reproduce function
339  
  static Reproducer reproducer;
340  
341  
  static String imageID = "#1000326"; // Bryan Cranston!
342  
  static RGBImage originalImage;
343  
  static FrameWithImages fwi;
344  
  static double zoom = 1;
345  
    
346  
  psvm {
347  
    for (int i = 0; i < args.length; i++) {
348  
      String arg = args[i];
349  
      if (isSnippetID(arg))
350  
        imageID = arg;
351  
      else if (arg.equals("zoom"))
352  
        zoom = Double.parseDouble(args[++i]);
353  
      else if (arg.equals("w") || arg.equals("width")) {
354  
        String w = args[++i];
355  
        imageWidth = w.equals("original") ? -1 : Integer.parseInt(w);
356  
      } else
357  
        System.out.println("Unknown argument: " + arg);
358  
    }
359  
360  
    fwi = new FrameWithImages(1);
361  
    fwi.hop();
362  
    
363  
    thread {
364  
      originalImage = loadImage(imageID);
365  
      if (imageWidth < 0)
366  
        imageWidth = originalImage.getWidth();
367  
      else
368  
        originalImage = resizeToWidth(originalImage, imageWidth);
369  
      fwi.setZoom(zoom);
370  
      fwi.setInnerSize(originalImage);
371  
      
372  
      int gx = originalImage.getWidth()/8, gy = originalImage.getHeight()/8;
373  
      reproducer = new Grid(baseMaker, gx, gy);
374  
      
375  
      reproduceOpenEnd(originalImage);
376  
    }
377  
    
378  
    /*
379  
    new Magnet m;
380  
    m.cx = m.cy = 0.5;
381  
    m.angle = 30;
382  
    
383  
    while (true) {
384  
      m.angle = (m.angle+1) % 360;
385  
      //System.out.println("Angle: " + m.angle);
386  
      RGBImage img = new RGBImage(100, 100, Color.gray);
387  
      paint(img, m);
388  
      fwi.setImage(0, img);
389  
    }
390  
    */
391  
  }
392  
  
393  
  
394  
  static void reproduceOpenEnd(RGBImage original) {
395  
    Params best = null;
396  
    long lastPrint = 0, lastN = 0;
397  
    for (long ntry = 1; ; ntry++) {
398  
      long now = System.currentTimeMillis();
399  
      if (now >= lastPrint+1000) {
400  
        long tps = (ntry-lastN)*1000/(now-lastPrint);
401  
        lastPrint = now;
402  
        lastN = ntry;
403  
        String s = "Try " + ntry + "(" + tps + "/s)";
404  
        if (best == null)
405  
          System.out.println(s);
406  
        else {
407  
          System.out.println("Best: " + best);
408  
          System.out.println(s + ", score: " + formatDouble(best.getScore()*100, 3) + "%, structure size: " + structureSize(best, Params.class));
409  
        }
410  
      }
411  
      Params p = reproducer.reproduce(original);
412  
      if (best == null || p != null && p.getScore() < best.getScore()) {
413  
        //System.out.println("New best! " + p.getScore());
414  
        best = p;
415  
        fwi.setImage(0, p.getImage());
416  
      }
417  
      
418  
      if (p != null && p.getScore() == 0.0)
419  
        break;
420  
    }
421  
  }
422  
  
423  
  static void paint(RGBImage img, Magnet m) {
424  
    int w = img.getWidth(), h = img.getHeight();
425  
    for (int y = 0; y < h; y++)
426  
      for (int x = 0; x < w; x++) {
427  
        double nx = x/(double)(w-1);
428  
        double ny = y/(double)(h-1);
429  
        img.setPixel(x, y, m.def(nx, ny));
430  
      }
431  
  }
432  
  
433  
  static void slantedSplit(RGBImage img, SlantedSplit p) {
434  
    int w = img.getWidth(), h = img.getHeight();
435  
    for (int yy = 0; yy < h; yy++)
436  
      for (int xx = 0; xx < w; xx++) {
437  
        double x = ((double) xx)/(w-1);
438  
        double y = ((double) yy)/(h-1);
439  
        if (p.swap) {
440  
          double temp = x; x = y; y = x;
441  
        }
442  
        double splitPoint = mix(p.splitPointL, p.splitPointR, x);
443  
        RGB col = y <= splitPoint ? p.col1 : p.col2;
444  
        img.setPixel(xx, yy, col);
445  
      }
446  
  }
447  
}

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1000541
Snippet name: Magnets
Eternal ID of this version: #1000541/1
Text MD5: 66d2c6768f5aa7ea4551cfc04b36a020
Transpilation MD5: b4efe870ebabf77f0d2a98e80e12e58f
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-08-14 13:56:21
Source code size: 12324 bytes / 447 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 713 / 797
Referenced in: [show references]