vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
547 stars 90 forks source link

Formatting rational multiples of pi #300

Closed abrombo closed 2 years ago

abrombo commented 2 years ago

I have written some code of pretty labeling of the tics on a radian axis (latex labels in fractions of pi). I am embedding the code since was not allowed to attach an asy file. Just run the code for an example of what it does -

import math; texpreamble("\newcommand{\bfrac}[2]{\displaystyle{\frac{#1}{#2}}}");

// Calculate the greatest common denominator of m and n int gcd(int m, int n) { int small; if (m > n) { small = n; } else { small = m; };

int igcd;

for (int i=1; i <= small; ++i) { if((m % i == 0) & (n % i == 0)) { igcd = i;} } return igcd; }

typedef string intop(real);

//Pretty pi labels for axis in radians //m is the number of intervals you want to divide pi into, //pilabel(m)(x) x is the value of the tic mark you want to label, //and pilable output a LaTeX string to label the tic mark. //It is assumed the x values are close to a multiple of pi/n. //Run this file for examples intop pilabel(int m) { return new string(real x) { string sgn = "";

if (x < 0.0)
{
  sgn = "-";
  x = -x;
}

real dpi = pi/(real) m;
real denom = x/dpi;
int ndenom = (int) denom;
if (denom - (real) ndenom < 0 ) ++ndenom;
int igcd = gcd(m,ndenom);
string s1 = (string) (ndenom/igcd);
string s2 = (string) (m/igcd);
string lab;
if (s1 == "1" & s2 == "1")
{
  lab = "$"+sgn+"\pi$";
  return lab;
}

if (s1 == "1")
{
  lab = "$"+sgn+"\bfrac{\pi}{"+s2+"}$";
  return lab;
}

if (s2 == "1")
{
  lab = "$"+sgn+s1+"\pi$";
  return lab;
}

lab = "$"+sgn+"\bfrac{"+ s1 +"}{"+ s2 +"}\pi$";
return lab;

}; }

void test(int n, real x) { write("x = "+(string)x+" = "+pilabel(n)(x)); }

test(8,pi/4.0); test(8,pi); test(8,2.0pi); test(8,3.0pi/4.0);

johncbowman commented 2 years ago

There is already a gcd function in rational.asy. You should import that module instead. It is better to use code mode <> to post code so that it doesn't get reformatted into something else.

The Asymptote Forum is a better place for such discussions:

https://sourceforge.net/p/asymptote/discussion/409349

We could perhaps provide the functionality you want by adding an explicit cast from real to rational, to allow you to say: (rational) (0.785398163397448/pi);

One could then add some TeX formatting to rational.asy as well.