|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T l
Length: 4499 (0x1193)
Types: TextFile
Names: »latex_line.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z«
└─⟦036c765ac⟧
└─⟦this⟧ »TeX3.0/TeXgraphics/transfig/fig2dev/latex_line.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦63303ae94⟧ »unix3.14/TeX3.14.tar.Z«
└─⟦c58930e5c⟧
└─⟦this⟧ »TeX3.14/TeXgraphics/transfig/fig2dev/latex_line.c«
#include <stdio.h>
#include <math.h>
/*
* latex_line.c:
* Subroutines for drawing and translating lines for the LaTeX
* picture environment.
* Written by Frank Schmuck (schmuck@svax.cs.cornell.edu)
* June 1988
*
* The LaTeX picture environment allows generating pictures in standard
* LaTeX. However, some restrictions apply: lines and vectors (a vector
* is a line with an arrow at the end) can only be drawn with a finite
* number of slopes. The available slopes are given by dy/dx where
* dx and dy must be integers <= 6 for lines and <= 4 for vectors.
*
* The subroutines in this file are used in fig2latex to approximate
* an arbitrary line or vector by a LaTeX line/vector, and in fig to
* restrict line drawing to slopes supported by LaTeX.
*/
/*
* Constant for converting from radian to degrees
*/
double rad2deg = 57.295779513082320877;
int pgcd(a,b)
int a, b;
/*
* compute greatest common divisor, assuming 0 < a <= b
*/
{
b = b % a;
return (b)? gcd(b, a): a;
}
int gcd(a, b)
int a, b;
/*
* compute greatest common divisor
*/
{
if (a < 0) a = -a;
if (b < 0) b = -b;
return (a <= b)? pgcd(a, b): pgcd(b, a);
}
int lcm(a, b)
int a, b;
/*
* Compute least common multiple
*/
{
return abs(a*b)/gcd(a,b);
}
/*
* Tables of line and vector slopes supported by LaTeX
*/
struct angle_table {
int x, y;
double angle;
};
#define N_LINE 25
struct angle_table line_angles[N_LINE] =
{ {0, 1, 90.0},
{1, 0, 0.0},
{1, 1, 45.0},
{1, 2, 63.434948822922010648},
{1, 3, 71.565051177077989351},
{1, 4, 75.963756532073521417},
{1, 5, 78.690067525979786913},
{1, 6, 80.537677791974382609},
{2, 1, 26.565051177077989351},
{2, 3, 56.309932474020213086},
{2, 5, 68.198590513648188229},
{3, 1, 18.434948822922010648},
{3, 2, 33.690067525979786913},
{3, 4, 53.130102354155978703},
{3, 5, 59.036243467926478582},
{4, 1, 14.036243467926478588},
{4, 3, 36.869897645844021297},
{4, 5, 51.340191745909909396},
{5, 1, 11.309932474020213086},
{5, 2, 21.801409486351811770},
{5, 3, 30.963756532073521417},
{5, 4, 38.659808254090090604},
{5, 6, 50.194428907734805993},
{6, 1, 9.4623222080256173906},
{6, 5, 39.805571092265194006}
};
#define N_ARROW 13
struct angle_table arrow_angles[N_ARROW] =
{ {0, 1, 90.0},
{1, 0, 0.0},
{1, 1, 45.0},
{1, 2, 63.434948822922010648},
{1, 3, 71.565051177077989351},
{1, 4, 75.963756532073521417},
{2, 1, 26.565051177077989351},
{2, 3, 56.309932474020213086},
{3, 1, 18.434948822922010648},
{3, 2, 33.690067525979786913},
{3, 4, 53.130102354155978703},
{4, 1, 14.036243467926478588},
{4, 3, 36.869897645844021297},
};
get_slope(dx, dy, sxp, syp, arrow)
int dx, dy, *sxp, *syp, arrow;
/*
* Find the LaTeX line slope that is closest to the one given by dx, dy.
* Result is returned in *sxp, *syp. If (arrow != 0) the closest LaTeX
* vector slope is selected.
*/
{
double angle;
int i, s, max;
double d, d1;
struct angle_table *st;
if (dx == 0) {
*sxp = 0;
*syp = (dy < 0)? -1: 1;
return;
}
angle = atan((double)abs(dy) / (double)abs(dx)) * rad2deg;
if (arrow) {
st = arrow_angles;
max = N_ARROW;
} else {
st = line_angles;
max = N_LINE;
}
s = 0;
d = 9.9e9;
for (i = 0; i < max; i++) {
d1 = fabs(angle - st[i].angle);
if (d1 < d) {
s = i;
d = d1;
}
}
*sxp = st[s].x;
if (dx < 0) *sxp = -*sxp;
*syp = st[s].y;
if (dy < 0) *syp = -*syp;
}
latex_endpoint(x1, y1, x2, y2, xout, yout, arrow, magnet)
int x1, y1, x2, y2;
int *xout, *yout;
int arrow, magnet;
/*
* Computes a point "close" to (x2,y2) that is reachable from (x1,y1)
* by a LaTeX line (LaTeX vector if arrow != 0). The result is returned
* in *xout, *yout. If (magnet > 1) the point returned is selected such that
* (*xout - x1) and (*yout - y1) are both multiples of magnet.
*/
{
int dx, dy, sx, sy, ds, dsx, dsy;
dx = x2-x1;
dy = y2-y1;
get_slope(dx, dy, &sx, &sy, arrow);
if (abs(sx) >= abs(sy)) {
ds = lcm(sx, magnet*gcd(sx,magnet));
dsx = (2*abs(dx)/ds + 1)/2;
dsx = (dx >= 0)? dsx*ds: -dsx*ds;
*xout = x1 + dsx;
*yout = y1 + dsx*sy/sx;
} else {
ds = lcm(sy, magnet*gcd(sy,magnet));
dsy = (2*abs(dy)/ds + 1)/2;
dsy = (dy >= 0)? dsy*ds: -dsy*ds;
*yout = y1 + dsy;
*xout = x1 + dsy*sx/sy;
}
}