Calculus II
Lesson 18: Application of Series: Geometric Curves
The Snowflake Curve
The Snowflake Curve was initially described by Koch as an affirmative solution to the problem of whether there is a continuous curve that has no tangent line at any point on the curve.
It is defined as the limit of the sequence of curves generated by the procedure snowflake given below. Type in the words defined below and then enter snow(4) to get a feel for what the snowflake curve looks like. The first word performs a basic operation on any segment, which we think of as a list of its endpoints. It replaces the segment of length d with a sequence of four segments of length d/3 obtained in the following way: Start at the left endpoint of the segment and go d/3 of the way along the segment, turn left 60 degrees and go the same distance, turn right 60 degrees and go the same distance, then turn left 60 degrees and proceed d/3 units along the original segment to the right endpoint. Note that the resulting path has three points where there is no tangent.
> basic := proc(p1,p2) local dx,dy, p3,p4,p5; dx := (p2[1]-p1[1])/3.; dy := (p2[2]-p1[2])/3.; p3 := [p1[1]+dx,p1[2]+dy]; p4 := [p1[1]+2*dx,p1[2]+2*dy]; p5 := [p1[1]+1.5*dx-sqrt(3.)/2*dy, p1[2]+1.5*dy+sqrt(3.)/2.*dx]; p3,p5,p4,p2; end:
So for example, if we feed the points [0,0], [1,0] into basic, we get out the following sequence of numbers:
> basic([0,0],[1,0]);
Notice the left endpoint of the original segment is missing from this list. That is for programming reasons which become clear in the definition of the word flake below. The word flake takes a list of points, which represents a sequence of line segments laid end to end, and returns a list representing 4 times as many line segments, where each segment in the original list has been replaced by the 4 segments returned by basic.
> flake := proc(fl) local i,curve; curve := fl[1]; for i from 1 to nops(fl)-1 do curve := curve ,basic(fl[i],fl[i+1] ) ; od end:
Now the starting point for the snowflake curve is the equilateral triangle.
> curve := [[0,0],[1/2,1/2*sqrt(3)],[1,0],[0,0]];
To draw the second stage of the snowflake curve,
> plot([flake(curve)],scaling=constrained);
Now we can define the nth stage of the snowflake curve.
> snowflake := proc(n) local i,curve,ti; curve := [[0,0],[1/2,1/2*sqrt(3)],[1,0],[0,0]]; for i from 2 to n do curve := [flake(curve)] od; ti := cat(n,`th stage of the snowflake curve`); plot(curve,color=black,style = LINE, axes = NONE,scaling = CONSTRAINED,title = ti) end:
> snowflake(4);
Here's an animation of the snowflake curve 'growing in place'. About 5 frames is all you can usefully see.
> plots[display]([seq(snowflake(i),i=1..5)],insequence=true,axes=none,scaling=constrained);
Problem: What is the length of the snowflake curve?
Solution: To calculate the length of the snowflake curve we see that the first stage has length units; the 2nd stage has length , or ; in general the nth stage has length , or . So the length of the nth stage goes to infinity as n gets large. This says the snowflake curve is infinitely long.
A Spacefiller
David Hilbert in 1891 described a continuous curve whose range is the unit square! This was contrary to the intuition of the time, which was that the range of a path had to be 1-dimensional. Here is a Maple word that draws an approximation to Hilbert's space filling curve . The approach to defining the drawing procedure peano (below) is similar to that used to define snowflake (above).
> basic := proc(p1,p2,p3) local dx,dy,p4,p5,p6,p7,p8,p9; p4 := .5*(p1+p2); p9 := .5*(p2+p3); p5 := p4+(p2-p9); p6 := p2+(p2-p9); p7 := p2+(p4-p1); p8 := p9+(p4-p1); p4,p5,p6, p2 ,p7,p8,p9, p3 ; end:
> peano := proc(fl) local i,cur; cur := [fl[1] ] ; for i from 1 by 2 to nops(fl)-2 do cur := [op(cur),basic( fl[i],fl[i+1],fl[i+2] )] od;
> end:
> fl := [[0,0],[1,1],[2,0]];
> for i from 1 to 4 do fl := peano(fl) od: ti := cat(4,`th stage of Peano's curve`); plot(fl,style=LINE,axes=NONE,title=ti, scaling=CONSTRAINED);