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 )