11-17-2018 01:22 PM
I am a beginner level user of LabVIEW NXG and i want to draw a Dragon curve (fractal) using the L-system method.
The dragon curve drawn using an L-system.
Here, F means "draw forward", − means "turn left 90°", and + means "turn right 90°". X and Y do not correspond to any drawing action and are only used to control the evolution of the curve.
The user must be able to specify the number of iterations of this curve.
If anyone would be able to give an idea on how to begin this i would appreciate it.
Solved! Go to Solution.
11-17-2018 10:27 PM
I haven't worked with Lindenmayer Systems, so I don't really understand what to do with the rewriting rules you describe, nor how to use these to go from one picture/graph to the next one. I'm not sure why you would want to do this in LabVIEW -- some form of symbolic mathematics software (Mathematica? Maple?) might be more appropriate. Of interest (to me) is that most pictures I've seen of evolution of Dragon curves show Curve 2 as a combination of two Curve 1 images rotated by -45° and -135°, and "shrunk" by 1/sqrt(2) (basically putting a right triangle on a line segment that becomes the non-plotted hypotenuse of an equilateral right triangle) (I know this sounds like gobbledegook, but if you look at a picture, it might make sense). I don't see the notion of converting a line segment by building an equilateral right triangle on it (which implies that every other generation has all the line segments either pure horizontal/pure vertical or "pure diagonal", depending on the generation being odd or even).
Bob Schor
11-19-2018 08:01 AM
This problem is basically in 2 parts, you need to make something to generate the instructions, then make something to mimic a turtle graphics program.
Part1
Reading about it online, I see mathematicians have found a very concise way to describe this in a notation that is impossible for non-mathematicians to understand. Seems like standard practice.
Basically it is just a problem of recursive string replacements.
You have the following
Gen1: FX
Gen2: FX+YF+ (since X is substituted for X+YF+) (Y could not be substituted as it wasnt in Gen1)
Gen3: FX+YF++-FX-YF+ (since X is replaced by X+YF+ and Y is replaced by -FX-Y)
Gen4 :FX+YF++-FX-YF++-FX+YF+--FX-YF+
Gen10: FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF++-FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+--FX+YF++-FX-YF++-FX+YF+--FX-YF+--FX+YF++-FX-YF+--FX+YF+--FX-YF+
...and so on until you crash your computer 🙂
Step 2:
Assuming you stop before you run out of RAM, you can then strip out the X and Y from the string, since they don't influence the pattern, they just dictate how to mutate the next generation
You need to make something to sketch this out. I would use an XY graph for this, but a 2D picture control is also fine.
11-19-2018 08:21 AM - edited 11-19-2018 08:23 AM
Hi,
once I wrote a small VI to draw a Koch curve…
1. Basically it stores all points in an array.
2. With each iteration/generation the array is indexed, two points taken from array and replaced by new points according to the drawing rules. After the iteration you end with a new bigger array containing more points.
3. This point array is plotted in a XY graph…
Hints:
1. You can store points as complex numbers.
2. To turn/apply an angular movement you can use simple complex math…
And yes, you run into memory problems very fast. The XYGraph may have problems with more than 2^24 points…
11-19-2018 08:33 AM
@GerdW wrote:
Hi,
once I wrote a small VI to draw a Koch kurve…
1. Basically it stores all points in an array.
2. With each iteration/generation the array is indexed, two points taken from array and replaced by new points according to the drawing rules. After the iteration you end with a new bigger array containing more points.
3. THis point array is plotted in a XY graph…
Hints:
1. You can store points as complex numbers.
2. To turn/apply an angular movement you can use simple complex math…
Yeah, +1 for the complex, that's how I would plot on the XY graph for sure.
For + in the string add pi/2 to "angle" and for - subtract pi/2 from "angle", for each F take the current complex position and add it to "R=1 theta=ANGLE" to get the next point.
For any inter-generational rotations you can take the initial "Angle" value and set it to pi/4, or just multiply the whole array by R=1, theta = pi/4.
11-19-2018 09:42 AM
So I decided to have a go of this. It makes pretty patterns. This is Gen21.
11-19-2018 10:28 AM
Very nice! Consider posting the code somewhere as an interesting "Teaching Tool".
Bob Schor
11-19-2018 12:02 PM - edited 11-19-2018 12:22 PM
Code attached, its a bit rough and ready. Feel free to optimise/improve/comment/whatever.
This one doesn't do any of the inter-generation rotation, but you can easily manipulate the start angle based on an output of a Quotient and Remainder of the generation number with 2. start at 0 in one case and pi/4 on the other.
11-19-2018 12:07 PM
I get an out of memory error as soon as I run your VI. It seems the 200 million element complex array is causing it.
11-19-2018 12:13 PM - edited 11-19-2018 12:24 PM
Probably. I was running in 64 bit.. 🙂
I did just realise I uploaded the wrong version. The correct version has the 2 inner loops of the first for loop merged into one.
EDIT : I have uploaded the modified one now.
Probably a lot can be done to optimise the code, its just a bit of fun 😉