1// Copyright 2020 Google LLC. 2// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 3#include "tools/fiddle/examples.h" 4REG_FIDDLE_ANIMATED(l_system_plant, 256, 256, false, 0, 3) { 5// L-System 6// https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant 7 8struct rules_t { 9 char c; 10 std::string s; 11}; 12 13rules_t rules[6] = { 14 {'X', "F-[[X]+X]+F[+FX]-X"}, 15 {'F', "FF"}, 16 {'+', "+"}, 17 {'-', "-"}, 18 {'[', "["}, 19 {']', "]"}, 20}; 21 22std::string E(std::string s) { 23 if (s.size() == 0) { 24 return ""; 25 } 26 for (int i=0; i<6; i++) { 27 if (rules[i].c == s[0]) { 28 return rules[i].s + E(s.substr(1)); 29 } 30 } 31 return ""; 32} 33 34struct Pt { 35 SkScalar x; 36 SkScalar y; 37 SkScalar a; 38}; 39 40void draw(SkCanvas* canvas) { 41 canvas->drawColor(SK_ColorLTGRAY); 42 43 SkPaint p; 44 p.setColor(0xFFA6761D); 45 p.setAntiAlias(true); 46 p.setStyle(SkPaint::kStroke_Style); 47 p.setStrokeWidth(1); 48 49 std::vector<struct Pt> ptstack; 50 std::string plant = E(E(E(E(E("X"))))); 51 const double len = 2.5; 52 struct Pt pt = {128, 256, 3.14}; 53 SkPath path; 54 path.moveTo(pt.x, pt.y); 55 56 for (std::string::iterator it=plant.begin(); it!=plant.end(); ++it) { 57 if (*it == 'F') { 58 pt.x += len*sin(pt.a); 59 pt.y += len*cos(pt.a); 60 path.lineTo(pt.x, pt.y); 61 } else if (*it == '+') { 62 pt.a += (0.15 + sin(frame*2.0*3.14159)*0.05); 63 } else if (*it == '-') { 64 pt.a += (-0.15 + sin(frame*2.0*3.14159)*0.05); 65 } else if (*it == '[') { 66 ptstack.push_back(pt); 67 } else if (*it == ']') { 68 pt = ptstack.back(); 69 ptstack.pop_back(); 70 path.moveTo(pt.x, pt.y); 71 } 72 } 73 canvas->drawPath(path, p); 74} 75} // END FIDDLE 76