// シームレス画像生成用の割合変化を求めるテスト // グラデーション画像として表示する PImage img; int kind; int kind_max; // 初期化 void setup() { size(512, 512); kind = 0; kind_max = 6; img = makeImg0(width, height, kind); } // 描画 void draw() { image(img, 0, 0); } // マウスクリック時の処理 void mouseClicked() { // クリックするたびに数式を変える if (mouseButton == LEFT) { kind++; if (kind > kind_max) kind = 0; } else { kind--; if (kind < 0) kind = kind_max; } img = makeImg0(width, height, kind); } // グラデーション画像を生成 PImage makeImg0(int w, int h, int kind) { img = createImage(w, h, RGB); img.loadPixels(); for (float y=0; y < h; y++) { for (float x = 0; x < w; x++) { img.pixels[int(y * w + x)] = color(getV0(x, y, w, h, kind)); } } img.updatePixels(); return img; } // 合成の割合を求める(gimpのソースを参考にしてる) float getWeight(float x, float y, float w, float h) { // from gimp filter gimp-2.8.16/plug-ins/common/tile-seamless.c float a = (abs(x - w) - 1) / (w - 1); float b = (abs(y - h) - 1) / (h - 1); if (a < 0.00000001 && b > 0.99999999) return 1.0; if (a > 0.99999999 && b < 0.00000001) return 0.0; return 1.0 - (a * b / (a * b + (1.0 - a) * (1.0 - b))); } // 合成の割合を求める(gimp - MathMap を参考にしてる) float getWeight2(float x, float y, float w, float h) { // from MathMap make seamless in gimp // x,y座標値を0.0から1.0の値に変換 float vx = x / (w - 1); float vy = y / (h - 1); float x1 = max(0, vx - vy); float x2 = min(1, vx + (1 - vy)); return (vx - x1) / (x2 - x1); } // 数式 float getV0(float x, float y, float w, float h, int kind) { float v = 0; float ww = w - 1; float hh = h - 1; // x,y座標の値を、0.0 - 1.0 に変換 float vx = x / ww; float vy = y / hh; switch(kind) { case 0: v = 1 - (vx + vy) / 2; break; case 1: v = 1 - vx * vy; break; case 2: v = 1 - easeInOutCubic(vx * vy, 0, 1.0, 1.0); break; case 3: v = 1 - min(vx, vy); break; case 4: v = 1 - abs(vy - vx); break; case 5: // gimp + MathMap の処理 v = 1.0 - getWeight2(x, y, w, h); break; case 6: // gimp の make seamlessフィルタの処理 v = 1.0 - getWeight(x, y, w, h); break; } v *= 255; return v; } // イージング float easeInOutCubic(float t, float beg, float chg, float dur) { t /= (dur / 2.0); if (t < 1.0) return (chg / 2.0 * t * t * t + beg); t -= 2.0; return chg / 2.0 * (t * t * t + 2.0) + beg; }