/* This processing sketch demonstrates the construction of the KoBIS logo and its similarities to the model for describing the inflorescence of the sunflower. Copyright (C) 2015 Christopher Schölzel 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 */ /** type value for H. Vogels model */ int VOGEL = 0; /** type value for KoBIS logo */ int KOBIS = 1; /** golden angle in degrees */ float goldenAngle = 137.5077640; /** * Fibonacci function * @param n index in fibonacci sequenc * @returns fibonacci sequence at index n */ int fib(int n) { if (n <= 1) return n; int last = 0; int cur = 1; int tmp = 0; for(int i = 1; i < n; i++) { tmp = cur; cur = cur + last; last = tmp; } return cur; } /** number of steps between nodes on first set of spirals */ int spiral1 = fib(6); /** number of steps between nodes on second set of spirals */ int spiral2 = fib(7); /** total number of nodes */ int np = spiral1*spiral2; /** type of the model (KOBIS or VOGEL) */ int type = KOBIS; /** distance factor (either an additive delta for KOBIS or a multiplicative factor for VOGEL) */ float dfac = 1.5; /** angle step length from one node to the next */ float astep = goldenAngle; /** list of nodes */ ArrayList points; /** if true, mouse movements will set the value of dfac and astep */ boolean move = false; /** Setup function to initialize size and node list */ void setup() { size(400,400); points = new ArrayList(); for(int i = 0; i < np; i++) { points.add(new PVector(0,0)); } } /** * Draws connections between nodes. * * Node number i will be connected with node number i - spiral1 and * node number i - spiral2. */ void drawConnections() { for(int i = 0; i < points.size(); i++) { PVector p = points.get(i); int[] spirals = new int[]{spiral1, spiral2}; for (int sp : spirals) { int i2 = i - sp; if(i2 >= 0) { PVector p2 = points.get(i2); line(p.x, p.y, p2.x, p2.y); } } } } /** * Calculates the positions of the nodes according to the given model. */ void layoutPoints() { float cx = width/2; float cy = height/2; float angle = 0; float dist = 10; for(PVector p : points) { dist += dfac; angle += radians(astep); if(type == VOGEL) { dist = dfac * sqrt(angle); } p.x = cx + cos(angle)*dist; p.y = cy + sin(angle)*dist; } } /** * Draws a hexagonal shape around the point (x,y) with * a width of w and a height of h. * @param x the x-coordinate of the center of the hexagon * @param y the y-coordinate of the center of the hexagon * @param w the width of the hexagon * @param h the height of the hexagon */ void hexagon(float x, float y, float w, float h) { float da = TWO_PI / 6.0; beginShape(); for(int i = 0; i < 6; i++) { vertex(x + cos(i*da)*w, y + sin(i*da)*h); } endShape(CLOSE); } /** * Draws the nodes at their current position. */ void drawPoints() { for(int i = 0; i < points.size(); i++) { PVector p = points.get(i); float d = type == KOBIS ? 3 + i / 8.0 : 10; fill(getColor(i)); hexagon(p.x, p.y, d, d); } } /** Processing draw function that draws nodes and their connections. */ void draw() { background(255); layoutPoints(); drawConnections(); drawPoints(); } /** * Switches between interactive and static mode when mouse is clicked. * In interactive mode, the mouse position determines the values of * astep and dfac. */ void mouseClicked() { move = !move; if(move) { loop(); } else { noLoop(); } } /** * Changes the values of astep and dfac based on the mouse position and * propagates these changes to the javascript environment. * * This function is only active during interactive mode. */ void mouseMoved() { if(!move) return; astep = 360.0 * mouseX / width; dfac = (type == KOBIS ? 4.0 : dd2df(4.0)) * mouseY / height; updateJS(); }