POV-Ray : Newsgroups : povray.general : L-Systems in Povray : Re: L-Systems in Povray Server Time
25 Apr 2024 10:28:24 EDT (-0400)
  Re: L-Systems in Povray  
From: ingo
Date: 4 Jun 2023 04:50:00
Message: <web.647c4eab453cebfc17bac71e8ffb8ce3@news.povray.org>
Never tried a L-system in POV-Ray, so gave it a go this morning. It's a bit
crude and simple but works.

First a long string is generated from the axiom and a dict with rules. Then the
resulting string is used to generate vertices based upon the build rule macros.
Finally the vertices are used for cylinders.

---%<------%<------%<---
Pov-Ray    : 3.8
Scene File : lsys.pov
Author     : Ingo Janssen
Date       : 2023-06-04

#version 3.8;

global_settings{ assumed_gamma 1.0 }
#default{ finish{ ambient 0.1 diffuse 0.9 }}

//build rules
#declare BuildRules = dictionary;

#macro F(Pos)
  <Pos.x + cos(Pos.z), Pos.y + sin(Pos.z), Pos.z> // <x, y, angle>
#end
#declare BuildRules["F"] = 70; //chr(70) = F

#macro Plus(Pos)
  <Pos.x, Pos.y, Pos.z + (pi/2)>
#end
#declare BuildRules["+"] = 43;

#macro Min(Pos)
  <Pos.x, Pos.y, Pos.z - (pi/2)>
#end
#declare BuildRules["-"] = 45;
//


#macro Ltransform(Axiom, Rules, Iterations)
  #local Result = Axiom;
  #for (i, 1, Iterations)
      #local NewResult = "";
      #local N = strlen(Result);
      #local j = 1;
      #while (j <= N)
        #local CurrentSymbol = substr(Result, j, 1);
        #ifdef(Rules[CurrentSymbol])
          #local NewResult = concat(NewResult, Rules[CurrentSymbol]);
        #else
          #local NewResult = concat(NewResult, CurrentSymbol);
        #end
        #local j = j + 1;
      #end
      #local Result = NewResult;
      //#debug concat(Result, "\n")
  #end
  Result
#end


#macro Lvertices(Lstr)
  #local Pos = <0, 0, 0>; // <x, y, angle>
  #local Return = array{<Pos.x, Pos.y>};

  #for (i, 0, strlen(Lstr)-1)
    #local CurrentSymbol = substr(Lstr, i, 1);
    #ifdef (BuildRules[CurrentSymbol])
      #switch (BuildRules[CurrentSymbol])
        #case(70)
          #local Pos = F(Pos);
        #break
        #case(43)
          #local Pos = Plus(Pos);
        #break
        #case(45)
          #local Pos = Min(Pos);
        #break
      #end
      #local InArr = Return[dimension_size(Return,1)-1];
      #if (Pos.x != InArr.x | Pos.y != InArr.y)
        #local Return[dimension_size(Return,1)] = <Pos.x, Pos.y>;
      #end
    #end
  #end
  Return
#end

#declare Axiom = "FX";
#declare Rules = dictionary{
  ["X"] : "X+YF",
  ["Y"] : "FX-Y"
}
#declare Iterations = 12;

#declare Lstr = Ltransform(Axiom, Rules, Iterations);

#declare Vertices = Lvertices(Lstr);

#for(i, 0, dimension_size(Vertices,1)-2)
  cylinder{
    Vertices[i],Vertices[i+1],0.1
    texture{pigment{rgb 1}}
  }
#end

camera{
  location <-20,0,-40>
  look_at <-20,0,0>
  angle 120
  right x*image_width/image_height
}

light_source{
  <3000,3000,-3000>
  color rgb 1
}

---%<------%<------%<---


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.