| // 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<struct Pt> ptstack; | |
| std::string plant = E(E(E(E(E("X"))))); | |
| const double len = 2.5; | |
| struct Pt pt = {128, 256, 3.14}; | |
| SkPathBuilder 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.detach(), p); | |
| } | |
| } // END FIDDLE |