// Copyright 2020 Google LLC. // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. #include "tools/fiddle/examples.h" REG_FIDDLE_ANIMATED(l_system_plant, 256, 256, false, 0, 3) { // L-System // https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant struct rules_t { char c; std::string s; }; rules_t rules[6] = { {'X', "F-[[X]+X]+F[+FX]-X"}, {'F', "FF"}, {'+', "+"}, {'-', "-"}, {'[', "["}, {']', "]"}, }; std::string E(std::string s) { if (s.size() == 0) { return ""; } for (int i=0; i<6; i++) { if (rules[i].c == s[0]) { return rules[i].s + E(s.substr(1)); } } return ""; } struct Pt { SkScalar x; SkScalar y; SkScalar a; }; void draw(SkCanvas* canvas) { canvas->drawColor(SK_ColorLTGRAY); SkPaint p; p.setColor(0xFFA6761D); p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(1); std::vector ptstack; std::string plant = E(E(E(E(E("X"))))); const double len = 2.5; struct Pt pt = {128, 256, 3.14}; SkPath path; path.moveTo(pt.x, pt.y); for (std::string::iterator it=plant.begin(); it!=plant.end(); ++it) { if (*it == 'F') { pt.x += len*sin(pt.a); pt.y += len*cos(pt.a); path.lineTo(pt.x, pt.y); } else if (*it == '+') { pt.a += (0.15 + sin(frame*2.0*3.14159)*0.05); } else if (*it == '-') { pt.a += (-0.15 + sin(frame*2.0*3.14159)*0.05); } else if (*it == '[') { ptstack.push_back(pt); } else if (*it == ']') { pt = ptstack.back(); ptstack.pop_back(); path.moveTo(pt.x, pt.y); } } canvas->drawPath(path, p); } } // END FIDDLE