Guest User

Untitled

a guest
Aug 16th, 2018
1,629
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6 7.58 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. use Math::Trig;
  4. use POSIX qw/ceil/;
  5. ##
  6. # PEEVE 2(To) Turtle
  7. # Converts a PEEVE script to a Turtle Script.
  8. ##
  9.  
  10. #FILENAME Variables
  11. $FILE=$ARGV[0];
  12. $FILEEXT=$FILEEXT= ($ARGV[0] =~ /([^.]+)$/)[0];
  13. $FILEOUT=0; #If 0, print to stdOut, if 1, print to file specified by ARGV[1]
  14.  
  15. #Initalisation checks
  16. #Check to see if there is at least 1 argument
  17. if($FILEEXT ne "peeve")
  18. {
  19.     #Print error message and close if there is no arguments
  20.     print("Invalid filetype in file argument.");
  21.     exit;
  22. }
  23.  
  24. if($#ARGV == 1)
  25. {
  26.     $FILEOUT=1;
  27. }
  28.  
  29. #Turtle Variables
  30. $xPos=200; #The current x position of the turtle
  31. $yPos=200; #The current y position of the turtle
  32. $dir=0; #The direction in degrees, that the turtle is facing.
  33.  
  34.  
  35. #File Variables
  36. $lineCount=0; #Keeps track of what line in the file we're at. Used for error checking.
  37.  
  38. #---Main---#
  39. #Open the file, or close if not found.
  40. if($#ARGV < 0)
  41. {
  42.     $FILE=*STDIN;  
  43. }
  44. else
  45. {
  46.     open(FILE) or die("File not found.");
  47. }
  48. #@output is the array which holds the text to be written to the svg file.
  49. #Add the header information onto the output
  50.  
  51. #Iterate through the file line by line
  52. foreach $line (<FILE>)
  53. {
  54.     $lineCount=$lineCount + 1;
  55.     preProc($line);
  56.     @line = split(' ', $line);
  57.     if($line ne "\n")
  58.     {
  59.         #Check syntax
  60.         checkSyntax(@line);
  61.  
  62.     }
  63.     if(@line[0] eq "LINE")
  64.     {
  65.         drawLine(@line[1], @line[2], @line[3], @line[4]);          
  66.     }
  67.     elsif(@line[0] eq "POLYGON")
  68.     {
  69.         drawPolygon(@line[1], @line[2], @line[3], @line[4],@line[5]);
  70.     }
  71.     elsif(@line[0] eq "CIRCLE")
  72.     {
  73.         drawCircle(@line[1], @line[2], @line[3]);
  74.     }
  75.     #Else we have style commands.
  76.     else
  77.     {
  78.         push(@output, $line);
  79.     }      
  80. }
  81.  
  82. #Output to file
  83. if($FILEOUT == 1)
  84. {
  85.     open(MYFILE, ">${ARGV[1]}.turtle");
  86.     print MYFILE @output;
  87.     close(MYFILE);
  88. }
  89. else
  90. {
  91.     print @output;
  92. }
  93. #Draws line
  94. #Accepts 4 arguments:
  95. #Starting Coordinates x1,y1
  96. #Ending Coordinates x2, y2
  97. sub drawLine
  98. {
  99.     #Move to start coordinates
  100.     moveTurtle($xPos, $yPos, @_[0], @_[1]);
  101.     #PENDOWN       
  102.     push(@output, "PENDOWN\n");
  103.     moveTurtle(@_[0], @_[1], @_[2], @_[3]);
  104.     #PENUP
  105.     push(@output, "PENUP\n");
  106. }
  107.  
  108. #Draws polygon
  109. sub drawPolygon
  110. {
  111.     $init_angle=@_[2];
  112.     $n_sides=@_[3];
  113.     $side_length=@_[4];
  114.  
  115.     #Calculate turning angle
  116.     $turningAngle=180-((180*($n_sides-2))/($n_sides));
  117.     #Move to start coordinates
  118.     moveTurtle($xPos, $yPos, $_[0], $_[1]);
  119.     #Rotate to init_angle
  120.     rotate($init_angle);
  121.     #PENDOWN
  122.     push(@output, "PENDOWN\n");
  123.     #Give our turtle a little workout      
  124.     for($count = 0; $count < $n_sides; $count++)
  125.     {
  126.         push(@output, "FORWARD ${side_length}\n");
  127.         rotate($dir+$turningAngle);
  128.     }
  129.     #PENUP
  130.     push(@output, "PENUP\n");
  131. }
  132.  
  133. #Draws circle
  134. sub drawCircle
  135. {
  136.     $radius=@_[2];
  137.     $circumference=2*$radius*pi;   
  138.     #Polygon variables
  139.     $init_angle=0;
  140.  
  141.     #Calculate number of sides. If the radius is less than 4, the side length must also be calculated.
  142.     if($radius < 4)
  143.     {
  144.         $side_length=2*$radius*sin(deg2rad(22.5));
  145.         $n_sides = 8; #Minimum of 8 sides.
  146.     }
  147.     else
  148.     {
  149.         $side_length=3; #This is the maximum side length allowed.
  150.         $n_sides = ((360) / (2 * rad2deg(asin(1.5/$radius))));
  151.         #$n_sides = ceil($circumference / 3)
  152.     }
  153.    
  154.     #Move turtle to the start + the radius to the left and half side length down
  155.     moveTurtle($xPos, $yPos, ($_[0]-$radius), ($_[1]+($side_length/2)));
  156.     #Start position is our current position, since we moved here above.
  157.     #Call drawPolygon to draw the circle.
  158.     drawPolygon($xPos, $yPos, 0, $n_sides, $side_length);
  159. }
  160.  
  161. #Moves the turtle from point A to point B
  162. sub moveTurtle
  163. {
  164.     $x1=@_[0];
  165.     $y1=@_[1];
  166.     $x2=@_[2];
  167.     $y2=@_[3];
  168.  
  169.  
  170.     $angle=0;
  171.     $forwardLength=0;
  172.     #If we're moving to the right
  173.     if($x2 > $x1)
  174.     {
  175.         print "In first/second quad";
  176.         #If we're moving up (First Quadrant)
  177.         if($y2 > $y1)
  178.         {  
  179.             print "First Quad\n";
  180.             $angle=rad2deg(atan(($y2-$y1)/($x2-$y1)));
  181.             #Rotate the turtle
  182.             rotate(($angle + 90));
  183.             #Pythagoras to get length of forward
  184.             $forwardLength=sqrt((($x2-$x1)** 2) + (($y2-$y1)**2));
  185.             push(@output, "FORWARD ${forwardLength}\n");
  186.         }
  187.         #If we're moving up (Second Quadrant)
  188.         elsif($y1 > $y2)
  189.         {
  190.             print "Second Quad\n";
  191.             $angle=rad2deg(atan(($x2-$x1)/($y1-$y2)));
  192.             rotate($angle);
  193.             #Pythagoras to get length of forward
  194.             $forwardLength=sqrt((($x2-$x1)** 2) + (($y1-$y2)**2));
  195.             push(@output, "FORWARD ${forwardLength}\n");
  196.         }
  197.         #We're moving to the right directly on the x axis.
  198.         elsif($y1 == $y2)
  199.         {
  200.             print "Direct Right\n";
  201.             #Rotate to 90 degrees (EAST)
  202.             rotate(90);
  203.             push(@output, "FORWARD @{[$x2-$x1]}\n");
  204.         }
  205.     }
  206.     #If we're moving to the left
  207.     elsif($x1 > $x2)
  208.     {
  209.         #If we're moving up (Third)
  210.         if($y2 > $y1)
  211.         {
  212.             print "Fourth Quad\n";
  213.             $angle=rad2deg(atan(($x1-$x2)/($y2-$y1)));
  214.             rotate(($angle + 180)); #Add 180 as offset to Fourth Quadrant
  215.             #Pythagoras to get length of forward
  216.             $forwardLength=sqrt((($x1-$x2)** 2) + (($y2-$y1)** 2));
  217.             push(@output, "FORWARD ${forwardLength}\n");
  218.         }
  219.         #If we're moving up (Third Quadrant)
  220.         elsif($y1 > $y2)
  221.         {
  222.             print "Third Quad\n";
  223.             $angle=rad2deg(atan(($y1-$y2)/($x1-$x2)));
  224.             rotate(($angle + 270)); #Add 270 as offset to Third Quadrant
  225.             #Pythagoras to get length of forward
  226.             $forwardLength=sqrt((($x1-$x2)** 2) + (($y1-$y2)** 2));
  227.             push(@output, "FORWARD ${forwardLength}\n");
  228.         }
  229.         #We're moving to the left directly on the x axis.
  230.         else
  231.         {
  232.             print "Direct Left\n";
  233.             #Rotate to 270 degrees (WEST)
  234.             rotate(270);
  235.             push(@output, "FORWARD @{[$x1-$x2]}\n");
  236.         }
  237.     }
  238.     #We're moving directly up or down the y axis.
  239.     else
  240.     {
  241.         #Move down
  242.         if($y2 > $y1)
  243.         {
  244.             print "Direct Up\n";
  245.             rotate(180); #Rotate to 0 degrees
  246.             push(@output, "FORWARD @{[$y2-$y1]}\n");
  247.         }
  248.         #Move up
  249.         elsif($y1 > $y2)
  250.         {  
  251.             rotate(0); #Rotate to 180 degrees
  252.             push(@output, "FORWARD @{[$y1-$y2]}\n");
  253.         }
  254.         #May as well account for all possibilities.
  255.         else
  256.         {
  257.             #No change in position, really?
  258.         }
  259.     }
  260.     $xPos = $x2;
  261.     $yPos = $y2;
  262. }
  263.  
  264. #Preprocesses the lines read from the peeve script.
  265. #Chops new lines and comments.
  266. sub preProc
  267. {
  268.     #Remove comments
  269.     $_[0] =~ s/#.*$//;     
  270. }
  271.  
  272. #Used for smart rotations of the turtle.
  273. #Accepts the new direction the turtle will face as parameter.
  274. sub rotate
  275. {
  276.     $newDir=@_[0];
  277.     if($dir != $newDir)
  278.     {
  279.         #Make smart turns :D           
  280.         if($dir > $newDir)
  281.         {
  282.             if(($dir - $newDir) > 180)
  283.             {
  284.                 push(@output, "RIGHT @{[360 - $dir + $newDir]}\n");
  285.             }
  286.             else
  287.             {
  288.                 push(@output, "LEFT @{[$dir - $newDir]}\n");
  289.             }
  290.         }
  291.         else
  292.         {
  293.             if(($newDir - $dir) > 180)
  294.             {
  295.                 push(@output, "LEFT @{[$dir + 360-$newDir]}\n");
  296.             }
  297.             else
  298.             {
  299.                 push(@output, "RIGHT @{[$newDir - $dir]}\n");
  300.             }
  301.         }      
  302.         $dir = $newDir;
  303.     }
  304. }
  305.  
  306. sub checkSyntax
  307. {
  308.     #TODO: Check each invidual argument...
  309.     @lineRead=@_;  
  310.     $lineLength = @lineRead;
  311.     #Check command
  312.     if(@lineRead[0] ne "LINE" and @lineRead[0] ne "POLYGON" and @lineRead[0] ne "CIRCLE" and @lineRead[0] ne "SETSTYLE" and @lineRead[0] ne "DEFINESTYLE")
  313.     {
  314.         print "Syntax error (Invalid Command: ${lineRead[0]}) at line ${lineCount} of ${FILE}. Terminating execution.\n";
  315.         exit;  
  316.     }
  317.        
  318.     if(@lineRead[0] eq "LINE" and $lineLength != 5)
  319.     {
  320.         print "Syntax error at line (Invalid Arguments) ${lineCount} of ${FILE}.\n Terminating execution.\n";
  321.         exit;  
  322.     }
  323.     elsif(@lineRead[0] eq "POLYGON" and $lineLength != 6)
  324.     {
  325.         print "Syntax error at line (Invalid Arguments) ${lineCount} of ${FILE}.\n Terminating execution.\n";
  326.         exit;  
  327.     }
  328.     elsif(@lineRead[0] eq "CIRCLE" and $lineLength != 4)
  329.     {
  330.         print "Syntax error at line (Invalid Arguments) ${lineCount} of ${FILE}.\n Terminating execution.\n";
  331.         exit;  
  332.     }
  333. }
Add Comment
Please, Sign In to add comment