The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# Copyright 2013 Kevin Ryde

# This file is part of Math-PlanePath.
#
# Math-PlanePath is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# Math-PlanePath is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with Math-PlanePath.  If not, see <http://www.gnu.org/licenses/>.


`Draw Dragon [ from .x1. .y1. to .x2. .y2. [level .level.] ]'
Draw a dragon curve going from .x1. .y1. to .x2. .y2. with recursion
depth .level.

The total number of line segments for the recursion is 2^level.
level=0 is a straight line from x1,y1 to x2,y2.

The default for x1,y1 and x2,y2 is to draw horizontally from 0,0
to 1,0.
{
    new .x1. .y1. .x2. .y2. .level.
    .x1. = \.word3.
    .y1. = \.word4.
    .x2. = \.word6.
    .y2. = \.word7.
    .level. = \.word9.
    
    if {rpn \.words. 5 >=}
        .x2. = 1
        .y2. = 0
    end if
    if {rpn \.words. 7 >=}
        .level. = 6
    end if
    
    if {rpn 0 .level. <=}
        draw line from .x1. .y1. to .x2. .y2.
    else
        .level. = {rpn .level. 1 -}

        # xmid,ymid is half way between x1,y1 and x2,y2 and up at
        # right angles away.
        #
        #            xmid,ymid             xmid = (x1+x2 + y2-y1)/2
        #            ^       ^             ymid = (x1-x2 + y1+y2)/2
        #           /    .    \
        #          /     .     \
        #     x1,y1 ........... x2,y2
        #
        new .xmid. .ymid.
        .xmid. = {rpn .x1. .x2. + .y2. .y1. - + 2 /}
        .ymid. = {rpn .x1. .x2. - .y1. .y2. + + 2 /}
        
        # The recursion is a level-1 dragon from x1,y1 to the midpoint
        # and the same from x2,y2 to the midpoint (the latter
        # effectively being a revered dragon.)
        #
        Draw Dragon from .x1. .y1. to .xmid. .ymid. level .level.
        Draw Dragon from .x2. .y2. to .xmid. .ymid. level .level.
        
        delete .xmid. .ymid.
    end if
    
    delete .x1. .y1. .x2. .y2. .level.
}

# Dragon curve from 0,0 to 1,0 extends out by 1/3 at the ends, so
# extents -0.5 to +1.5 for a bit of margin.  The Y extent is the same
# size 2 to make the graph square.
set x axis -0.5 1.5   .25
set y axis -1 1 .25

Draw Dragon





#Draw Dragon from 0 0 to 1 0 level 10

# x1,y1 to x2,y2
# dx = x2-x1
# dy = y2-y1
# xmid = x1 + dx/2 - dy/2
#      = x1 + (x2-x1 - (y2-y1))/2
#      = (2*x1 + x2-x1 -y2+y1)/2
#      = (2*x1 + x2-x1 - y2+y1) / 2
#      = (x1+x2 + y1-y2)/2
# ymid = y1 + dy/2 + dx/2
#      = (2*y1 + dy + dx)/2
#      = (2*y1 + y2-y1 + x2-x1) / 2
#      = (y1+y2 + x2-x1) / 2

# xmid = x1 + dx/2 + dy/2
#      = x1 + (x2-x1 + y2-y1)/2
#      = (x1+x2 + y2-y1)/2
# ymid = y1 + dy/2 - dx/2
#      = (2*y1 + y2-y1 + x1-x2) / 2
#      = (y1+y2 + x1-x2) / 2

        # show " line " .x1. " " .y1. " to " .x2. " " .y2.
         # show .x1. " " .y1. " to " .x2. " " .y2. " mid " .xmid. " " .ymid.
         # show "second " .x1. " " .y1. " to " .x2. " " .y2. " mid " .xmid. " " .ymid.
    # show "level " .level.