Math-PlanePath

 view release on metacpan or  search on metacpan

lib/Math/PlanePath/AlternateTerdragon.pm  view on Meta::CPAN

    -1, 1        dY minimum = -1, maximum = +1
     1,-1

For 2 or more arms the second arm is rotated by 60 degrees so giving the
following additional combinations, for a total six.  This changes the dX
minimum.

    dX,dY   for arms=2 or more
    -----
    -2, 0        dX minimum = -2, maximum = +2
     1, 1        dY minimum = -1, maximum = +1
    -1,-1

=item C<$sum = $path-E<gt>sumxy_minimum()>

=item C<$sum = $path-E<gt>sumxy_maximum()>

Return the minimum or maximum values taken by coordinate sum X+Y reached by
integer N values in the path.  If there's no minimum or maximum then return
C<undef>.

S=X+Y is an anti-diagonal.  The first arm is entirely above a line 135deg --
-45deg, per the +60deg to -30deg extents shown above.  Likewise the second
arm which is to 60+60=120deg.  They have C<sumxy_minimum = 0>.  More arms
and all C<sumxy_maximum> are unbounded so C<undef>.

=item C<$diffxy = $path-E<gt>diffxy_minimum()>

=item C<$diffxy = $path-E<gt>diffxy_maximum()>

Return the minimum or maximum values taken by coordinate difference X-Y
reached by integer N values in the path.  If there's no minimum or maximum
then return C<undef>.

D=X-Y is a leading diagonal.  The first arm is entirely right of a line
45deg -- -135deg, per the +60deg to -30deg extents shown above, so it has
C<diffxy_minimum = 0>.  More arms and all C<diffxy_maximum> are unbounded so
C<undef>.

=back

=head2 Level Methods

=over

=item C<($n_lo, $n_hi) = $path-E<gt>level_to_n_range($level)>

Return C<(0, 3**$level)>, or for multiple arms return C<(0, $arms *
3**$level + ($arms-1))>.

There are 3^level segments in a curve level, so 3^level+1 points numbered
from 0.  For multiple arms there are arms*(3^level+1) points, numbered from
0 so n_hi = arms*(3^level+1)-1.

=back

=head1 FORMULAS

=cut

# Various formulas for coordinates, boundary, area and more can be found in
# the author's mathematical write-up
#
# =over
#
# L<http://user42.tuxfamily.org/terdragon/index.html>
#
# =back
#
# =head2 N to X,Y
#
# There's no reversals or reflections in the curve so C<n_to_xy()> can take
# the digits of N either low to high or high to low and apply what is
# effectively powers of the N=3 position.  The current code goes low to high
# using i,j,k coordinates as described in L<Math::PlanePath/Triangular
# Calculations>.
#
#     si = 1    # position of endpoint N=3^level
#     sj = 0    #    where level=number of digits processed
#     sk = 0
#
#     i = 0     # position of N for digits so far processed
#     j = 0
#     k = 0
#
#     loop base 3 digits of N low to high
#        if digit == 0
#           i,j,k no change
#        if digit == 1
#           (i,j,k) = (si-j, sj-k, sk+i)  # rotate +120, add si,sj,sk
#        if digit == 2
#           i -= sk      # add (si,sj,sk) rotated +60
#           j += si
#           k += sj
#
#        (si,sj,sk) = (si - sk,      # add rotated +60
#                      sj + si,
#                      sk + sj)
#
# The digit handling is a combination of rotate and offset,
#
#     digit==1                   digit 2
#     rotate and offset          offset at si,sj,sk rotated
#
#          ^                          2------>
#           \
#            \                          \
#     *---  --1                  *--   --*
#
# The calculation can also be thought of in term of w=1/2+I*sqrt(3)/2, a
# complex number sixth root of unity.  i is the real part, j in the w
# direction (60 degrees), and k in the w^2 direction (120 degrees).  si,sj,sk
# increase as if multiplied by w+1.

=pod

=head2 Turn

At each point N the curve always turns 120 degrees either to the left or
right, it never goes straight ahead.  If N is written in ternary then the
lowest non-zero digit at its position gives the turn.  Positions are counted



( run in 1.312 second using v1.01-cache-2.11-cpan-df04353d9ac )