1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
/*
* Turtle Graphics for LaTeX eepic
* Bart 2001/05/28
*
* Copyright © 2001 Bart Massey.
* All Rights Reserved. See the file COPYING in this directory
* for licensing information.
*/
namespace Turtle {
import File;
/* configuration */
file target;
int scale;
/* current turtle state */
struct {
real x, y;
} pos;
rational theta;
/* keep theta in range */
void function
normalize_theta() {
while (theta < 0)
theta += 1;
while (theta >= 1)
theta -= 1;
}
/* angles used by trig functions */
real function
radians(rational angle) {
return 2 * pi * (1 - angle) + pi / 2;
}
/* for various conversions */
int function
round(real arg) {
return floor(arg + 0.5);
}
/*
* Create a new turtle drawing.
* Sizes are in inches.
* Coordinates normalized s.t. given x_size is 1.0
*/
public void function
start_turtle(string outfile, real x_size, real y_size) {
target = open(outfile, "w");
scale = floor(x_size * 1000);
int yscale = floor(y_size * 1000);
pos.x = 0;
pos.y = 0;
theta = 0;
fprintf(target, "\\setlength{\\unitlength}{0.001in}\n");
fprintf(target, "\\begin{picture}(%d,%d)\n",
scale, yscale);
}
/* finish the drawing */
public void function
stop_turtle() {
fprintf(target, "\\end{picture}\n");
close(target);
}
/* move to normalized absolute position */
public void function
move_turtle(real x, real y) {
pos.x = x * scale;
pos.y = y * scale;
}
/* turn *to* normalized rational angle */
public void function
aim_turtle(rational angle) {
theta = angle;
normalize_theta();
}
/* turn *by* angle */
public void function
turn_turtle(rational angle) {
theta += angle;
normalize_theta();
}
/* travel turtle while making mark */
public void function
stroke_turtle(rational dist) {
real dx = scale * dist * cos(radians(theta));
real dy = scale * dist * sin(radians(theta));
fprintf(target, "\\path(%d,%d)(%d,%d)\n",
round(pos.x), round(pos.y),
round(pos.x + dx), round(pos.y + dy));
pos.x += dx;
pos.y += dy;
}
}
|