.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Math::NumSeq::PlanePathTurn 3pm" .TH Math::NumSeq::PlanePathTurn 3pm "2021-01-23" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Math::NumSeq::PlanePathTurn \-\- turn sequence from PlanePath module .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& use Math::NumSeq::PlanePathTurn; \& my $seq = Math::NumSeq::PlanePathTurn\->new (planepath => \*(AqDragonCurve\*(Aq, \& turn_type => \*(AqLeft\*(Aq); \& my ($i, $value) = $seq\->next; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This is a tie-in to present turns from a \f(CW\*(C`Math::PlanePath\*(C'\fR module in the form of a NumSeq sequence. .PP The \f(CW\*(C`turn_type\*(C'\fR choices are .PP .Vb 7 \& "Left" 1=left, 0=right or straight \& "Right" 1=right, 0=left or straight \& "Straight" 1=straight, 0=left or right \& "NotStraight" 0=straight, 1=left or right \& "LSR" 1=left, 0=straight, \-1=right \& "SLR" 0=straight, 1=left, 2=right \& "SRL" 0=straight, 1=right, 2=left .Ve .PP In each case the value at sequence index i is the turn at N=i, .PP .Vb 6 \& i+1 \& ^ \& | \& | \& i\-1 \-\-\-> i turn at i \& first turn at i = n_start + 1 .Ve .PP For multiple \*(L"arms\*(R" in the path, the turn follows that particular arm so locations of N = i\-arms to i to i+arms. i values start \&\f(CW\*(C`n_start()+arms_count()\*(C'\fR so that i\-arms is \f(CW\*(C`n_start()\*(C'\fR which is the first N on the path. A single arm path beginning N=0 has its first turn at i=1. .PP For \*(L"Straight\*(R", \*(L"\s-1LSR\*(R", \*(L"SLR\*(R",\s0 and \*(L"\s-1SRL\*(R",\s0 straight means either straight ahead or 180\-degree reversal, ie. the direction N to N+1 is along the same line as N\-1 to N was. .PP \&\*(L"Left\*(R" means to the left side of the N\-1 to N line, so not straight or right. Similarly \*(L"Right\*(R" means to the right side of the N\-1 to N line, so not straight or left. .SH "FUNCTIONS" .IX Header "FUNCTIONS" See \*(L"\s-1FUNCTIONS\*(R"\s0 in Math::NumSeq for behaviour common to all sequence classes. .ie n .IP """$seq = Math::NumSeq::PlanePathTurn\->new (key=>value,...)""" 4 .el .IP "\f(CW$seq = Math::NumSeq::PlanePathTurn\->new (key=>value,...)\fR" 4 .IX Item "$seq = Math::NumSeq::PlanePathTurn->new (key=>value,...)" Create and return a new sequence object. The options are .Sp .Vb 3 \& planepath string, name of a PlanePath module \& planepath_object PlanePath object \& turn_type string, as described above .Ve .Sp \&\f(CW\*(C`planepath\*(C'\fR can be either the module part such as \*(L"SquareSpiral\*(R" or a full class name \*(L"Math::PlanePath::SquareSpiral\*(R". .ie n .IP """$value = $seq\->ith($i)""" 4 .el .IP "\f(CW$value = $seq\->ith($i)\fR" 4 .IX Item "$value = $seq->ith($i)" Return the turn at N=$i in the PlanePath. .ie n .IP """$bool = $seq\->pred($value)""" 4 .el .IP "\f(CW$bool = $seq\->pred($value)\fR" 4 .IX Item "$bool = $seq->pred($value)" Return true if \f(CW$value\fR occurs as a turn. Often this is merely the possible turn values 1,0,\-1, etc, but some spiral paths for example only go left or straight in which case only 1 and 0 occur and \f(CW\*(C`pred()\*(C'\fR reflects that. .ie n .IP """$i = $seq\->i_start()""" 4 .el .IP "\f(CW$i = $seq\->i_start()\fR" 4 .IX Item "$i = $seq->i_start()" Return the first index \f(CW$i\fR in the sequence. This is the position \&\f(CW\*(C`rewind()\*(C'\fR returns to. .Sp This is \f(CW\*(C`$path\->n_start() \- $path\->arms_count()\*(C'\fR from the PlanePath object. .SH "FORMULAS" .IX Header "FORMULAS" .SS "Turn Left or Right" .IX Subsection "Turn Left or Right" A turn left or right is identified by considering the dX,dY at N\-1 and at N. .PP .Vb 10 \& N+1 * \& | \& | \& | dx2,dy2 \& | \& N * \& / \& / \& / dx1,dy1 \& N\-1 * .Ve .PP With the two vectors dx1,dy1 and dx2,dy2 at a common origin, if the dx2,dy2 is \*(L"above\*(R" the dx1,dy1 line then it's a turn to the left, or below is a turn to the right .PP .Vb 7 \& dx2,dy2 \& * \& ^ * dx1,dy1 \& | ^ \& | / \& |/ \& o .Ve .PP At dx2, the Y value of the dx1,dy1 vector is .PP .Vb 1 \& cmpY = dx2 * dy1/dx1 if dx1 != 0 \& \& left if dy2 > cmpY \& dy2 > dx2 * dy1/dx1 \& so dy2 * dx1 > dx2 * dy1 .Ve .PP This cross-product comparison dy2*dx1 > dx2*dy1 works when dx1=0 too, ie. when dx1,dy1 is vertical .PP .Vb 3 \& left if dy2 * 0 > dx2 * dy1 \& 0 > dx2*dy1 \& good, left if dx2 and dy1 opposite signs .Ve .PP So .PP .Vb 3 \& dy2*dx1 > dx2*dy1 left \& dy2*dx1 < dx2*dy1 right \& dy2*dx1 = dx2*dy1 straight, including 180 degree reverse .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Math::NumSeq, Math::NumSeq::PlanePathCoord, Math::NumSeq::PlanePathDelta, Math::NumSeq::PlanePathN .PP Math::NumberCruncher has a \f(CW\*(C`Clockwise()\*(C'\fR turn calculator .SH "HOME PAGE" .IX Header "HOME PAGE" .SH "LICENSE" .IX Header "LICENSE" Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Kevin Ryde .PP This file is part of Math-PlanePath. .PP Math-PlanePath is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP Math-PlanePath is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with Math-PlanePath. If not, see .