Cosmic Blues.

It draws the stars that move with their (fake) gravity.

It draws the stars that move with their (fake) gravity.

Description of this creative coding animation.

It's a creative coding animation made with Processing. It draws the stars that move with their (fake) gravity.

Fake gravity.

It is not a real physical model. It's just a simple fake gravity vector calculation.
float nD = dist(r.x, r.y, p.x, p.y);
if (r != p && nD > _limit) {
  // calc fake garavity vector
  float vR = atan2(p.y - r.y, p.x - r.x);
  r.x += cos(vR) * range / nD / nD;
  r.y += sin(vR) * range / nD / nD;
}

Discrete moving.

And I did not define speed but step to calculate star moving. So stars may not collide to another star but jump to the other side of that star. It adds some interesting results to this animation.

Example code of Processing.

This code does not display any images on the screen but generates image files in frames directory. You can make an animation with these files.

Please feel free to use this example code. To see other works based on my code is my pleasure. And my honor.


/**
 * Cosmic Blues.
 * It draws the stars that move with their (fake) gravity.
 *
 * Processing 3.5.3
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2020.05.23
 */

/**
 * Node : draw and hold location and color.
 */
public class Node {

  public  float x, y;   // coordinate of node
  private float hueVal; // hue value of node
  private float satVal; // saturation value of node
  private float briVal; // brightness value of node

  Node(float _x, float _y, float _c, float _s, float _b) {
    x = _x;
    y = _y;
    hueVal = _c;
    satVal = _s;
    briVal = _b;
  }

}


void setup() {

  size(720, 720);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  smooth();
  noLoop();

}


void draw() {

  int   sceneMax = 2;      // draw 2 different scenes
  int   frmMax   = 24 * 8; // for 24fps x 8s animation
  int   nodeMax  = 5000;
  float nodeGap  = 5.0;
  float baseHue  = random(360.0);

  for (int sceneCnt = 0; sceneCnt < sceneMax; ++sceneCnt) {

    baseHue += 180.0;
    float limit = random(2.0, 5.0); // bigger : many cluster
    float step  = random(0.1, 1.0); // random(0.2, 1.2);bigger : big cluster
    ArrayList<Node> rnds = plotNodes(nodeMax, nodeGap, baseHue);
    
    for (int frmCnt = 0; frmCnt < frmMax; ++frmCnt) {

      float frmRatio = map(frmCnt, 0, frmMax, 0.0, 1.0);
      float easeRatio = easeInOutCubic(frmRatio);
  
      background(baseHue % 360.0, 100.0, 20.0, 100.0);
      blendMode(ADD);
      drawNodes(rnds);
      blendMode(BLEND);
      casing();
 
      if (frmCnt == 0) {
        for (int i = 0; i < 12; i++) {
          saveFrame("frames/"  + String.format("%02d", sceneCnt) + ".00." + String.format("%04d", i) + ".png");
        }
      }
      saveFrame("frames/"  + String.format("%02d", sceneCnt) + ".01." + String.format("%04d", frmCnt) + ".png");

      moveNodes(rnds, limit * (1.0 - easeRatio * 0.25), step * frmRatio);
    }
  }

  exit();

}


/**
 * moveNodes : move Nodes with (fake) gravity calculation.
 *             NOT A PHYSICAL MODEL.
 * @param ArrayList<Node> _nodes : Nodes to move.
 * @param _limit : max distance that ignore gravity. 
 * @param _step  : moving step
 */
public void moveNodes(ArrayList<Node> _nodes, float _limit, float _step) {

  float range = max(width, height) * _step;

  for (Node r : _nodes) {
    ArrayList<PVector> vectors = new ArrayList<PVector>();
    for (Node p : _nodes) {
      float nD = dist(r.x, r.y, p.x, p.y);
      if (r != p && nD > _limit) {
        // calc fake garavity vector
        float vR = atan2(p.y - r.y, p.x - r.x);
        r.x += cos(vR) * range / nD / nD;
        r.y += sin(vR) * range / nD / nD;
      }
    }
  }

}


/**
 * drawNodes : draw each Node.
 * @param ArrayList<Node> _nodes : Nodes to draw.
 */
public void drawNodes(ArrayList<Node> _nodes) {

  noStroke();
  for (Node n : _nodes) {
    fill(n.hueVal, n.satVal, n.briVal, 100.0);
    ellipse(n.x, n.y, 3.0, 3.0);
  }

}


/**
 * plotNodes : locate Nodes with some distance each other.
 * @param _nodeMax : maximum number of Nodes.
 * @param _gap : gap between each Node.
 * @param _baseHue  : base color of Nodes.
 * @return ArrayList<Node> : holds nodes.
 */
public ArrayList<Node> plotNodes(float _nodeMax, float _gap, float _baseHue) {

  ArrayList<Node> nodes = new ArrayList<Node>();

  for (int i = 0; i < _nodeMax; i++) {

    // locate in round range
    float rRadius = random(0.6, 1.0) * min(width, height) * 0.45;
    float rRadian = random(TWO_PI);
    float rX = width  * 0.5 + rRadius * cos(rRadian);
    float rY = height * 0.5 + rRadius * sin(rRadian);
    
    // add new node
    boolean inner = false;
    for (Node n : nodes) {
      if (dist(rX, rY, n.x, n.y) < _gap) {
        inner = true;
        break;
      }
    }
    if (!inner) {
      int pixIndex = floor(rY * width + rX);
      nodes.add(new Node(
                         rX,
                         rY,
                         (_baseHue + noise(10.0, rX * 0.05, rY * 0.05) * 120.0 + 300.0) % 360.0,
                         noise(20.0, rX * 0.05, rY * 0.05) * 60.0 + 40.0,
                         noise(30.0, rX * 0.05, rY * 0.05) * 20.0 + 50.0
                         ));
    }
  }

  return nodes;

}


/**
 * casing : draw fancy casing
 */
public void casing() {
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(24.0);
  stroke(0.0, 0.0, 00.0, 100.0);
  rect(0.0, 0.0, width, height);
  strokeWeight(1.0);
  stroke(0.0, 0.0, 60.0, 100.0);
  rect(8.0, 8.0, width - 16.0, height - 16.0);
  noStroke();
  noFill();
  noStroke();
}

/**
 * easeInOutCubic easing function.
 * @param  t     0.0 - 1.0 : linear value.
 * @return float 0.0 - 1.0 : eased value.
 */
public float easeInOutCubic(float t) {
  t *= 2.0;
  if (t < 1.0) {
    return pow(t, 3) / 2.0;
  }
  t -= 2.0;
  return (pow(t, 3) + 2.0) / 2.0;
}


/*
Copyright (C) 2020- deconbatch

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>
*/


It draws the stars that move with their (fake) gravity.



No comments :

Post a Comment