Down on the Corner : Which corner should we turn?
Description of this geometric pattern animation.
It's a creative coding example work made with the 'Processing'.
I made some animation with the idea by creative coder おかず (@okazz_) how to draw geometric patterns.
シンプルな図形から幾何学的な模様を作る by Processing
https://note.mu/outburst/n/n9fdea683c079
I chose some shapes that have inner lines. These lines have the same margin. So these lines connect each other when the shape rotates.
This code does not display any images on the screen but just generates image files.
You can make animation with these files.
The 'Processing' code example.
Please feel free to use this example code under the terms of the GPL.
To see other works based on my code is my pleasure. And my honor.
/** * Down on the Corner. * Rotate shape animation with step easing. * I like the lines in the shapes. * reference : https://note.mu/outburst/n/n9fdea683c079 * * @author @deconbatch * @version 0.1 * Processing 3.2.1 * 2019.03.17 */ /** * main */ void setup() { size(720, 720); colorMode(HSB, 360, 100, 100, 100); rectMode(CENTER); smooth(); noLoop(); } void draw() { int frmCntMax = 24 * 6; int stopCnt = random(1.0) > 0.5 ? 4 : 2; // stop motion count float hueBase = random(360.0); StepEasing se = new StepEasing(stopCnt - 1); EasingCalc ec = (random(1.0) > 0.5) ? new InFourthPow() : new InOutCubic(); for (int frmCnt = 0; frmCnt < frmCntMax; ++frmCnt) { float easeRatio = se.calculate(ec, map(frmCnt, 0, frmCntMax, 0.0, 1.0)); float hueDiv = 60.0 * sin(PI * easeRatio); background((hueBase + hueDiv) % 360.0, 40.0, 30.0, 100.0); fill((30 + hueBase + hueDiv) % 360.0, 40, 80, 100); strokeWeight(8.0); stroke((hueBase + hueDiv) % 360.0, 40.0, 30.0, 100.0); float cellW = width / 2.0; float shapeW = cellW * (0.5 - 0.5 * sin(PI * (easeRatio % (1.0 / stopCnt)) * stopCnt)); // 2x2 cells for (int cellX = 0; cellX < 2; ++cellX) { for (int cellY = 0; cellY < 2; ++cellY) { int selector = (cellX + cellY) % 2; float rotater = floor(noise(cellX * 0.5, cellY * 0.5) * 5.0) + easeRatio * 4.0; // use noise as array of random. pushMatrix(); translate((cellX + 0.5) * cellW, (cellY + 0.5) * cellW); rotate(HALF_PI * rotater); if (selector == 0) { arc(0, -shapeW, shapeW * 2.0, shapeW * 2.0, 0, PI); arc(0, -shapeW, shapeW, shapeW, 0, PI); line(-shapeW, -shapeW, shapeW, -shapeW); } else { // do not change the triangle size triangle(-cellW * 0.5, -cellW * 0.5, cellW * 0.5, cellW * 0.5, -cellW * 0.5, cellW * 0.5); triangle(-cellW * 0.25, -cellW * 0.25, cellW * 0.25, cellW * 0.25, -cellW * 0.25, cellW * 0.25); } popMatrix(); } } // draw rect at the center pushMatrix(); translate(width * 0.5, height * 0.5); rect(0.0, 0.0, shapeW * 2.0, shapeW * 2.0); line(-shapeW, -shapeW * 0.5, shapeW, -shapeW * 0.5); line(-shapeW, shapeW * 0.5, shapeW, shapeW * 0.5); line(-shapeW * 0.5, -shapeW, -shapeW * 0.5, shapeW); line(shapeW * 0.5, -shapeW, shapeW * 0.5, shapeW); popMatrix(); saveFrame("frames/" + String.format("%04d", frmCnt) + ".png"); } exit(); } /** * StepEasing : calculate easing value with step landing. It just has one easing function yet. * @param _landingCount : 1 - any int value : landing number. */ private class StepEasing { private float landingPoint; private float easePrev; private float easeRatio; StepEasing(int _landingCount) { landingPoint = 1.0 / (_landingCount + 1); reset(); } StepEasing() { landingPoint = 1.0; reset(); } private void reset() { easePrev = 0.0; easeRatio = 0.0; } /** * calculate : calculate easing value with step landing. * @param _t 0.0 - 1.0 : linear value. * @return float 0.0 - 1.0 : eased value with step landing. */ public float calculate(EasingCalc _calc, float _t) { float easeCurr = _calc.calculate(map(_t % landingPoint, 0.0, landingPoint, 0.0, 1.0)); easeRatio += constrain((easeCurr - easePrev) * landingPoint, 0.0, 1.0); easePrev = easeCurr; return easeRatio; } } /** * easeInOutCubic easing function. * @param _t : 0.0 - 1.0 : linear value. * @return float : 0.0 - 1.0 : eased value. */ interface EasingCalc { float calculate(float _t); } private class InOutCubic implements EasingCalc { public float calculate(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; } } private class InFourthPow implements EasingCalc { public float calculate(float _t) { return 1.0 - pow(1.0 - _t, 4); } } /* Copyright (C) 2019- 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/> */