| Hal Canary | 8800042 | 2020-01-15 11:51:12 -0500 | [diff] [blame] | 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" | 
 | 4 | REG_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 |  | 
 | 8 | struct rules_t { | 
 | 9 |     char c; | 
 | 10 |     std::string s; | 
 | 11 | }; | 
 | 12 |  | 
 | 13 | rules_t rules[6] = { | 
 | 14 |     {'X', "F-[[X]+X]+F[+FX]-X"}, | 
 | 15 |     {'F', "FF"}, | 
 | 16 |     {'+', "+"}, | 
 | 17 |     {'-', "-"}, | 
 | 18 |     {'[', "["}, | 
 | 19 |     {']', "]"}, | 
 | 20 | }; | 
 | 21 |  | 
 | 22 | std::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 |  | 
 | 34 | struct Pt { | 
 | 35 |   SkScalar x; | 
 | 36 |   SkScalar y; | 
 | 37 |   SkScalar a; | 
 | 38 | }; | 
 | 39 |  | 
 | 40 | void 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 |