コエンザイムのブログ

ジェネレーティブアートが好きです

ModulatedEllipseクラスを試作しました

パーリンノイズで変形させた楕円を表示するModulatedEllipseクラスを試作しました。

ModulatedEllipseクラスを使った図形の描画例

コンストラクタでは中心のx位置、y位置、幅、高さを指定します。

setNoiseSmoothRatio()でノイズの滑らか度を指定できます。範囲は0.0〜1.0で、値が高いほど滑らかになります。

setNoiseEffectRatio()では効果の度合いを指定できます。範囲は0.0〜1.0で、値が高いほど効果が強くなります。

また、setNoiseSymmetry()で効果を左右対称にできます。trueで左右対称になり、falseで左右非対称になります。

以下はソースコードです。開発環境はMacBook Air、Processingです。

ModulatedEllipseSample.pde

// ModulatedEllipseSample

final int cMyWidth = 1280;
final int cMyHeight = 720;

ModulatedEllipse e;

void settings()
{
  size(cMyWidth, cMyHeight);
}

void setup()
{
  noLoop();
}

void draw()
{
  float cellWidth = width / 6;
  float cellHeight = height / 3;

  e = new ModulatedEllipse(0, 0, cellWidth - 10, cellHeight - 10);

  int i;
  float x = cellWidth / 2;
  float y = cellHeight / 2;
  float ratio = 0.0;
  e.setNoiseEffectRatio(0.3);
  for (i = 0; i < 6; i++)
  {
    e.setPosition(x, y);
    e.setNoiseSmoothRatio(ratio);
    e.draw();
    fill(0);
    text("SmoothRatio:" + ratio, x - cellWidth / 2, y - cellHeight / 2 + 10);
    text("EffectRatio:0.3", x - cellWidth / 2, y - cellHeight / 2 + 10 + 15);
    fill(255);

    x += cellWidth;
    ratio += 0.2;
  }
  
  x = cellWidth / 2;
  y += cellHeight;
  ratio = 0.0;
  e.setNoiseSmoothRatio(0.7);
  for (i = 0; i < 6; i++)
  {
    e.setPosition(x, y);
    e.setNoiseEffectRatio(ratio);
    e.draw();
    fill(0);
    text("SmoothRatio:0.7", x - cellWidth / 2, y - cellHeight / 2 + 10);
    text("EffectRatio:" + ratio, x - cellWidth / 2, y - cellHeight / 2 + 10 + 15);
    fill(255);

    x += cellWidth;
    ratio += 0.2;
  }

  x = cellWidth / 2;
  y += cellHeight;
  ratio = 0.0;
  e.setNoiseSmoothRatio(0.3);
  e.setNoiseEffectRatio(0.7);
  for (i = 0; i < 2; i++)
  {
    e.setNoiseSymmetry(!((i % 2) == 0));
    e.setPosition(x, y);
    e.draw();
    fill(0);
    text("SmoothRatio:0.3", x - cellWidth / 2, y - cellHeight / 2 + 10);
    text("EffectRatio:0.7", x - cellWidth / 2, y - cellHeight / 2 + 10 + 15);
    text("Symmetry:" + !((i % 2) == 0), x - cellWidth / 2, y - cellHeight / 2 + 10 + 15 + 15);
    fill(255);

    x += cellWidth;
  }
}

ModulatedEllipse.pde

// ModulatedEllipse

class ModulatedEllipse
{
  float mCenterX = 0;
  float mCenterY = 0;
  float mDiameterH = 100;
  float mDiameterV = 100;
  float mNoiseSmoothRatio = 1.0;
  float mNoiseRoughnessCoefficient = 0.0;
  float mNoiseEffectRatio = 0.5;
  boolean mNoiseSymmetryFlg = false;

  ModulatedEllipse(float x, float y, float h, float v)
  {
    mCenterX = x;
    mCenterY = y;
    mDiameterH = h;
    mDiameterV = v;
  }

  void setPosition(float x, float y)
  {
    mCenterX = x;
    mCenterY = y;
  }

  void setNoiseSmoothRatio(float r)
  {
    mNoiseSmoothRatio = r;
    mNoiseRoughnessCoefficient = map((1.0 - mNoiseSmoothRatio), 0, 1.0, 0.005, 0.1);
  }
  
  void setNoiseEffectRatio(float r)
  {
    mNoiseEffectRatio = r;
  }
  
  void setNoiseSymmetry(boolean f)
  {
    mNoiseSymmetryFlg = f;
  }
  
  void draw()
  {
    float h = mDiameterH / 2.0;
    float v = mDiameterV / 2.0;
    
    int i = 1;
    beginShape();
    for (float theta = 0.0; theta <= TWO_PI; theta += 0.005)
    {
      curveVertex(
        mCenterX + cos(-HALF_PI + theta) * h * (1.0 - noise(i * mNoiseRoughnessCoefficient) * mNoiseEffectRatio), 
        mCenterY + sin(-HALF_PI + theta) * v * (1.0 - noise(i * mNoiseRoughnessCoefficient) * mNoiseEffectRatio));
      if ((theta <= PI) || (!mNoiseSymmetryFlg))
      {
        i++;
      }
      else
      {
        i--;
      }
  }
    endShape(CLOSE);
  }
}

Auto Generated Gridをつくりました

Auto Generated Gridをつくりました。ジェネレーティブアートです。中心位置から、上下左右のいずれか一方向に罫線を引くことを繰り返しています。線の色は一定の確率で変更されるようにしました。

opensea.io

以下はソースコードです。開発環境はMacBook Air、Processingです。

// Grid
import  java.time.LocalDateTime;
import  java.time.ZoneId;
import  java.time.format.DateTimeFormatter;

final boolean cSAVE_FLG = false;
final int cSAVE_NUM = 1;
final int cSTART_NUM = 0;
final int cDIGIT_NUM = 2;

//// For Logo image size
//final int cMyWidth = 350;
//final int cMyHeight = 350;
//final String cFILE_NAME = "Grid_Logo_";

//// For Featured image size
//final int cMyWidth = 600;
//final int cMyHeight = 400;
//final String cFILE_NAME = "Grid_Featured_";

//// For Banner image size
//final int cMyWidth = 1400;
//final int cMyHeight = 400;
//final String cFILE_NAME = "Grid_Banner_";

// For HD
final int cMyWidth = 1280;
final int cMyHeight = 720;
final String cFILE_NAME = "Grid_";

//// For Full HD
//final int cMyWidth = 1920;
//final int cMyHeight = 1080;
//final String cFILE_NAME = "Grid_";

//// For Test
//final int cMyWidth = 800;
//final int cMyHeight = 450;
//final String cFILE_NAME = "Grid_";

final boolean cLOOP_FLG = true;
final float cFRAME_RATE = 0.3;

void settings() {
  size(cMyWidth, cMyHeight);
}

void setup()
{
  if (cSAVE_FLG)
  {
    noLoop();
  }
  else if (cLOOP_FLG)
  {
    frameRate(cFRAME_RATE);
  }
  else
  {
    noLoop();
  }
}

void draw()
{
  int loopMax = 1;
  
  if (cSAVE_FLG)
  {
    loopMax = cSAVE_NUM;
  }

  for (int i = 0; i < loopMax; i++)
  {
    myDraw();
    if (cSAVE_FLG)
    {
      LocalDateTime utcDateTime = LocalDateTime.now(ZoneId.of("UTC"));
      DateTimeFormatter dateFrmt = DateTimeFormatter.ofPattern("uuuuMMdd");
      DateTimeFormatter timeFrmt = DateTimeFormatter.ofPattern("HHmmss,SSSSSS");
      String dateStr = dateFrmt.format(utcDateTime);
      String timeStr = timeFrmt.format(utcDateTime);
      //println(cFILE_NAME + nf(cSTART_NUM + i, cDIGIT_NUM)
      //  + "_" + dateStr + "T" + timeStr + "Z" + ".png");
      save(cFILE_NAME + nf(cSTART_NUM + i, cDIGIT_NUM) 
        + "_" + dateStr + "T" + timeStr + "Z" + ".png");
    }
  }
}

void myDraw()
{
  int i;
  int x = (width - 1) / 2;
  int y = (height - 1) / 2;
  int gridUnit = width / 20 - 2;
  int hRndMax = 19;
  
  colorMode(HSB, hRndMax - 1, 100, 100);
  stroke(int(random(hRndMax)), 50, 100);
  strokeWeight(3);
  strokeCap(ROUND);
  
  background(0);
  
  for(i=0; i < 770; i++)
  {
    switch(int(random(4)))
    {
      case 0:
        if (y >= 0)
        {
          if(int(random(10)) == 0) { stroke(int(random(hRndMax)), 50, 100); }
          line(x, y, x, y - gridUnit);
          y -= gridUnit;
        }
        else
        {
          i--;
        }
        break;
      case 1:
        if (x >= 0)
        {
          if(int(random(10)) == 0) { stroke(int(random(hRndMax)), 50, 100); }
          line(x, y, x - gridUnit, y);
          x -= gridUnit;
        }
        else
        {
          i--;
        }
        break;
      case 2:
        if (y <= height)
        {
          if(int(random(10)) == 0) { stroke(int(random(hRndMax)), 50, 100); }
          line(x, y, x, y + gridUnit);
          y += gridUnit;
        }
        else
        {
          i--;
        }
        break;
      case 3:
        if (x <= width)
        {
          if(int(random(10)) == 0) { stroke(int(random(hRndMax)), 50, 100); }
          line(x, y, x + gridUnit, y);
          x += gridUnit;
        }
        else
        {
          i--;
        }
        break;
    }
  }
}

Generativemasksのウクライナ版を入手しました

Generativemasksを持っていると、寄付することにより、そのマスクのウクライナ版をつくれるとのことで、やってみました。無事つくれました。

opensea.io

Auto Generated Circlesをつくりました

Auto Generated Circlesをつくりました。ジェネレーティブアートです。ランダムな円を300個を重ねました。色のblendModeをDIFFERENCEにして重ねたら、おもしろい雰囲気になりました。

opensea.io

以下はソースコードです。開発環境はProcessingです。

// Circles
import  java.time.LocalDateTime;
import  java.time.ZoneId;
import  java.time.format.DateTimeFormatter;

final boolean cSAVE_FLG = false;
final int cSAVE_NUM = 20;
final int cSTART_NUM = 60;
final int cDIGIT_NUM = 2;

//// For Logo image size
//final int cMyWidth = 350;
//final int cMyHeight = 350;
//final String cFILE_NAME = "Circles_Logo_";

//// For Featured image size
//final int cMyWidth = 600;
//final int cMyHeight = 400;
//final String cFILE_NAME = "Circles_Featured_";

//// For Banner image size
//final int cMyWidth = 1400;
//final int cMyHeight = 400;
//final String cFILE_NAME = "Circles_Banner_";

// For HD
final int cMyWidth = 1280;
final int cMyHeight = 720;
final String cFILE_NAME = "Circles_";

//// For Full HD
//final int cMyWidth = 1920;
//final int cMyHeight = 1080;
//final String cFILE_NAME = "Circles_";

//// For Test
//final int cMyWidth = 800;
//final int cMyHeight = 450;
//final String cFILE_NAME = "Circles_";

final boolean cLOOP_FLG = true;
final float cFRAME_RATE = 0.3;

void settings() {
  size(cMyWidth, cMyHeight);
}

void setup()
{
  background(255);
  noStroke();
  blendMode(DIFFERENCE);

  if (cSAVE_FLG)
  {
    noLoop();
  }
  else if (cLOOP_FLG)
  {
    frameRate(cFRAME_RATE);
  }
  else
  {
    noLoop();
  }
}

void draw()
{
  int loopMax = 1;
  
  if (cSAVE_FLG)
  {
    loopMax = cSAVE_NUM;
  }

  for (int i = 0; i < loopMax; i++)
  {
    myDraw();
    if (cSAVE_FLG)
    {
      LocalDateTime utcDateTime = LocalDateTime.now(ZoneId.of("UTC"));
      DateTimeFormatter dateFrmt = DateTimeFormatter.ofPattern("uuuuMMdd");
      DateTimeFormatter timeFrmt = DateTimeFormatter.ofPattern("HHmmss,SSSSSS");
      String dateStr = dateFrmt.format(utcDateTime);
      String timeStr = timeFrmt.format(utcDateTime);
      //println(cFILE_NAME + nf(cSTART_NUM + i, cDIGIT_NUM)
      //  + "_" + dateStr + "T" + timeStr + "Z" + ".png");
      save(cFILE_NAME + nf(cSTART_NUM + i, cDIGIT_NUM) 
        + "_" + dateStr + "T" + timeStr + "Z" + ".png");
    }
  }
}

void myDraw()
{
  final int n = 300;

  int diameter;
  int i;
  for(i = 0; i < n; i++)
  {
    fill(int(random(360)), int(random(360)), int(random(360)));
    diameter = int(random(height));
    ellipse(int(random(width)), int(random(height)), diameter, diameter);
  }
  
  fill(255);
  rect(0, 0, width, height);
}

Auto Generated Curvesをつくりました

Auto Generated Curvesをつくりました。ジェネレーティブアートです。ランダムなペジェ曲線420本を重ねました。

opensea.io

以下はソースコードです。開発環境はProcessingです。

// Curves
import  java.time.LocalDateTime;
import  java.time.ZoneId;
import  java.time.format.DateTimeFormatter;

final boolean cSAVE_FLG = false;
final int cSAVE_NUM = 20;
final int cSTART_NUM = 80;
final int cDIGIT_NUM = 2;

//// For Logo image size
//final int cMyWidth = 350;
//final int cMyHeight = 350;
//final String cFILE_NAME = "Curves_Logo_";

//// For Featured image size
//final int cMyWidth = 600;
//final int cMyHeight = 400;
//final String cFILE_NAME = "Curves_Featured_";

//// For Banner image size
//final int cMyWidth = 1400;
//final int cMyHeight = 400;
//final String cFILE_NAME = "Curves_Banner_";

// For HD
final int cMyWidth = 1280;
final int cMyHeight = 720;
final String cFILE_NAME = "Curves_";

//// For Full HD
//final int cMyWidth = 1920;
//final int cMyHeight = 1080;
//final String cFILE_NAME = "Curves_";

//// For Test
//final int cMyWidth = 800;
//final int cMyHeight = 450;
//final String cFILE_NAME = "Curves_";

final boolean cLOOP_FLG = true;
final float cFRAME_RATE = 0.3;

void settings() {
  size(cMyWidth, cMyHeight);
}

void setup()
{
  strokeWeight(3);
  noFill();
  colorMode(HSB, 360, 100, 100, 100);
  if (cSAVE_FLG)
  {
    noLoop();
  }
  else if (cLOOP_FLG)
  {
    frameRate(cFRAME_RATE);
  }
  else
  {
    noLoop();
  }
}

void draw()
{
  int loopMax = 1;
  
  if (cSAVE_FLG)
  {
    loopMax = cSAVE_NUM;
  }

  for (int i = 0; i < loopMax; i++)
  {
    myDraw();
    if (cSAVE_FLG)
    {
      LocalDateTime utcDateTime = LocalDateTime.now(ZoneId.of("UTC"));
      DateTimeFormatter dateFrmt = DateTimeFormatter.ofPattern("uuuuMMdd");
      DateTimeFormatter timeFrmt = DateTimeFormatter.ofPattern("HHmmss,SSSSSS");
      String dateStr = dateFrmt.format(utcDateTime);
      String timeStr = timeFrmt.format(utcDateTime);
      //println(cFILE_NAME + nf(cSTART_NUM + i, cDIGIT_NUM)
      //  + "_" + dateStr + "T" + timeStr + "Z" + ".png");
      save(cFILE_NAME + nf(cSTART_NUM + i, cDIGIT_NUM) 
        + "_" + dateStr + "T" + timeStr + "Z" + ".png");
    }
  }
}

void myDraw()
{
  background(random(255));
  float hue = random(360);
  float hue1 = hue;
  float hue2 = int(hue + 327) % 360;
  float hue3 = int(hue + 180) % 360;

  for (int i = 0; i < 420; i++)
  {
    int rand = int(random(10));
    if (rand <= 1)
    {
      hue = hue3;
    }
    else if (rand == 2)
    {
      hue = hue2;
    }
    else
    {
      hue = hue1;
    }
    stroke(hue, random(101), random(33, 97), random(10, 101));
    bezier(random(width), random(height), random(width), random(height), random(width), random(height), random(width), random(height));
  }
}