// -*- mode:C++ ; compile-command: "g++-3.4 -I.. -g -c tex.cc" -*- #include "giacPCH.h" /* * Copyright (C) 2002,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres * Figure printing adapted from eukleides (c) 2002, Christian Obrecht * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ //#include #include #include #ifdef __ANDROID__ using std::vector; #endif using namespace std; #include "gen.h" #include "gausspol.h" #include "identificateur.h" #include "symbolic.h" #include "poly.h" #include "usual.h" #include "tex.h" #include "prog.h" #include "rpn.h" #include "plot.h" #include "giacintl.h" #ifndef NO_NAMESPACE_GIAC namespace giac { #endif // ndef NO_NAMESPACE_GIAC // find if a*x+b*y=c intersects the rectangle xmin..xmax,ymin..ymax // if true set x0,y0 and x1,y1 to the intersections bool is_clipped(double a,double xmin,double xmax,double b,double ymin,double ymax,double c,double & x0,double &y0,double & x1,double &y1){ int found=0; // find the intersects with x=xmin/x=xmax double x,y; // test whether a or b is too small double theta=std::atan2(b,a); if (std::abs(M_PI/2-std::abs(theta))<1e-3){ // line y=cst x0=xmin; x1=xmax; y0=y1=c/b; return y0>=ymin && y0<=ymax; } if (std::abs(theta)<1e-3 || (M_PI-std::abs(theta))<1e-3){ // line x=cst y0=ymin; y1=ymax; x0=x1=c/a; return x0>=xmin && x0<=xmax; } y=(c-a*xmin)/b; if (y>=ymin && y<=ymax){ ++found; x0=xmin; y0=y; } y=(c-a*xmax)/b; if (y>=ymin && y<=ymax){ if (found){ x1=xmax; y1=y; return true; } ++found; x0=xmax; y0=y; } x=(c-b*ymin)/a; if (x>=xmin && x<=xmax){ if (found){ x1=x; y1=ymin; return true; } ++found; x0=x; y0=ymin; } x=(c-b*ymax)/a; if (x>=xmin && x<=xmax){ if (found){ x1=x; y1=ymax; return true; } ++found; x0=x; y0=ymax; } return false; } bool in_rectangle(double ax,double ay,double xmin,double ymin,double xmax,double ymax){ return (ax>=xmin && ax<=xmax && ay>=ymin && ay<=ymax); } // clip line or segment or halfline, result in xa,ya xb,yb // mode can be _LINE__VECT (line), _HALFLINE__VECT (halfline) // anything else is considered to be a segment // return true if there is something to draw bool clip_line(double x1,double y1,double x2,double y2,double xmin,double ymin,double xmax,double ymax,int mode,double & xa,double & ya,double & xb,double & yb){ bool in1=in_rectangle(x1,y1,xmin,ymin,xmax,ymax); bool in2=in_rectangle(x2,y2,xmin,ymin,xmax,ymax); if (mode!=_LINE__VECT && mode !=_HALFLINE__VECT && in1 && in2){ xa=x1; ya=y1; xb=x2; yb=y2; return true; } // Line equation is (y2-y1)*x-(x2-x1)*y=(y2*x1-x2*y1) double dy=y2-y1; double dx=x2-x1; double c=(y2*x1-x2*y1); bool a=false,b=false; // Find 2 intersections y of x=xmin and x=xmax with line // Check if they are inside clip region >=ymin and <=ymax if (dx){ double y=(dy*xmin-c)/dx; if (y>=ymin && y<=ymax){ xa=xmin; ya=y; a=true; } y=(dy*xmax-c)/dx; if (y>=ymin && y<=ymax){ if (a){ xb=xmax; yb=y; b=true; } else { xa=xmax; ya=y; a=true; } } } // Find 2 intersections of y=ymin and y=ymax with line if (!b && dy){ double x=(dx*ymin+c)/dy; if (x>=xmin && x<=xmax){ if (a){ xb=x; yb=ymin; b=true; } else { xa=x; ya=ymin; a=true;} } x=(dx*ymax+c)/dy; if (x>=xmin && x<=xmax){ if (a){ xb=x; yb=ymax; b=true; } else { xa=x; ya=ymax; a=true;} } } if (a && b){ // if not true there is nothing to draw // First case is line, we are done if (mode==_LINE__VECT) return true; if (mode!=_HALFLINE__VECT){ // segment // we know that both points are not inside if (!in1 && !in2) // both are outside, it's like a line return (xa-xmin)*(xb-xmin)<0; if (in1){ // 1 is in, 2 not, find if a is between 1 and 2 if ((xa-x1)*(x2-x1)>0 || (ya-y1)*(y2-y1)>0){ xb=x1; yb=y1; } else { xa=x1; ya=y1; } return true; } if (in2){ // 2 is in, 1 not, find if a is between 2 and 1 if ((xa-x2)*(x1-x2)>0 || (ya-y2)*(y1-y2)>0){ xb=x2; yb=y2; } else { xa=x2; ya=y2; } return true; } } } return false; } // dimension of the LaTeX output figures default 12 cm x 12 cm double horiz_latex=12.; double vert_latex=12.; const char tex_preamble[]="\\documentclass{article} \n\\usepackage{pst-plot,color} \n\\usepackage{graphicx} \n\\begin{document}\n"; #ifdef RTOS_THREADX const char tex_color[]=""; #else const char tex_color[]="\\newrgbcolor{fltkcolor0}{0 0 0}\n\\newrgbcolor{fltkcolor1}{0.9961 0 0}\n\\newrgbcolor{fltkcolor2}{0 0.9961 0}\n\\newrgbcolor{fltkcolor3}{0.9961 0.9961 0}\n\\newrgbcolor{fltkcolor4}{0 0 0.9961}\n\\newrgbcolor{fltkcolor5}{0.9961 0 0.9961}\n\\newrgbcolor{fltkcolor6}{0 0.9961 0.9961}\n\\newrgbcolor{fltkcolor7}{0.9961 0.9961 0.9961}\n\\newrgbcolor{fltkcolor8}{0.332 0.332 0.332}\n\\newrgbcolor{fltkcolor9}{0.7734 0.4414 0.4414}\n\\newrgbcolor{fltkcolor10}{0.4414 0.7734 0.4414}\n\\newrgbcolor{fltkcolor11}{0.5547 0.5547 0.2188}\n\\newrgbcolor{fltkcolor12}{0.4414 0.4414 0.7734}\n\\newrgbcolor{fltkcolor13}{0.5547 0.2188 0.5547}\n\\newrgbcolor{fltkcolor14}{0.2188 0.5547 0.5547}\n\\newrgbcolor{fltkcolor15}{0 0 0.5}\n\\newrgbcolor{fltkcolor16}{0.6562 0.6562 0.5938}\n\\newrgbcolor{fltkcolor17}{0.9062 0.9062 0.8438}\n\\newrgbcolor{fltkcolor18}{0.4062 0.4062 0.3438}\n\\newrgbcolor{fltkcolor19}{0.5938 0.6562 0.6562}\n\\newrgbcolor{fltkcolor20}{0.8438 0.9062 0.9062}\n\\newrgbcolor{fltkcolor21}{0.3438 0.4062 0.4062}\n\\newrgbcolor{fltkcolor22}{0.6094 0.6094 0.6562}\n\\newrgbcolor{fltkcolor23}{0.8594 0.8594 0.9062}\n\\newrgbcolor{fltkcolor24}{0.3594 0.3594 0.4062}\n\\newrgbcolor{fltkcolor25}{0.6094 0.6562 0.6094}\n\\newrgbcolor{fltkcolor26}{0.8594 0.9062 0.8594}\n\\newrgbcolor{fltkcolor27}{0.3594 0.4062 0.3594}\n\\newrgbcolor{fltkcolor28}{0.5625 0.5625 0.5625}\n\\newrgbcolor{fltkcolor29}{0.75 0.75 0.75}\n\\newrgbcolor{fltkcolor30}{0.3125 0.3125 0.3125}\n\\newrgbcolor{fltkcolor31}{0.625 0.625 0.625}\n\\newrgbcolor{fltkcolor32}{0 0 0}\n\\newrgbcolor{fltkcolor33}{0.05078 0.05078 0.05078}\n\\newrgbcolor{fltkcolor34}{0.1016 0.1016 0.1016}\n\\newrgbcolor{fltkcolor35}{0.1484 0.1484 0.1484}\n\\newrgbcolor{fltkcolor36}{0.1914 0.1914 0.1914}\n\\newrgbcolor{fltkcolor37}{0.2383 0.2383 0.2383}\n\\newrgbcolor{fltkcolor38}{0.2812 0.2812 0.2812}\n\\newrgbcolor{fltkcolor39}{0.332 0.332 0.332}\n\\newrgbcolor{fltkcolor40}{0.3711 0.3711 0.3711}\n\\newrgbcolor{fltkcolor41}{0.4141 0.4141 0.4141}\n\\newrgbcolor{fltkcolor42}{0.457 0.457 0.457}\n\\newrgbcolor{fltkcolor43}{0.5 0.5 0.5}\n\\newrgbcolor{fltkcolor44}{0.5391 0.5391 0.5391}\n\\newrgbcolor{fltkcolor45}{0.582 0.582 0.582}\n\\newrgbcolor{fltkcolor46}{0.625 0.625 0.625}\n\\newrgbcolor{fltkcolor47}{0.6641 0.6641 0.6641}\n\\newrgbcolor{fltkcolor48}{0.707 0.707 0.707}\n\\newrgbcolor{fltkcolor49}{0.75 0.75 0.75}\n\\newrgbcolor{fltkcolor50}{0.793 0.793 0.793}\n\\newrgbcolor{fltkcolor51}{0.832 0.832 0.832}\n\\newrgbcolor{fltkcolor52}{0.875 0.875 0.875}\n\\newrgbcolor{fltkcolor53}{0.9141 0.9141 0.9141}\n\\newrgbcolor{fltkcolor54}{0.957 0.957 0.957}\n\\newrgbcolor{fltkcolor55}{0.9961 0.9961 0.9961}\n\\newrgbcolor{fltkcolor56}{0 0 0}\n\\newrgbcolor{fltkcolor57}{0 0.1406 0}\n\\newrgbcolor{fltkcolor58}{0 0.2812 0}\n\\newrgbcolor{fltkcolor59}{0 0.4258 0}\n\\newrgbcolor{fltkcolor60}{0 0.5664 0}\n\\newrgbcolor{fltkcolor61}{0 0.7109 0}\n\\newrgbcolor{fltkcolor62}{0 0.8516 0}\n\\newrgbcolor{fltkcolor63}{0 0.9961 0}\n\\newrgbcolor{fltkcolor64}{0.2461 0 0}\n\\newrgbcolor{fltkcolor65}{0.2461 0.1406 0}\n\\newrgbcolor{fltkcolor66}{0.2461 0.2812 0}\n\\newrgbcolor{fltkcolor67}{0.2461 0.4258 0}\n\\newrgbcolor{fltkcolor68}{0.2461 0.5664 0}\n\\newrgbcolor{fltkcolor69}{0.2461 0.7109 0}\n\\newrgbcolor{fltkcolor70}{0.2461 0.8516 0}\n\\newrgbcolor{fltkcolor71}{0.2461 0.9961 0}\n\\newrgbcolor{fltkcolor72}{0.4961 0 0}\n\\newrgbcolor{fltkcolor73}{0.4961 0.1406 0}\n\\newrgbcolor{fltkcolor74}{0.4961 0.2812 0}\n\\newrgbcolor{fltkcolor75}{0.4961 0.4258 0}\n\\newrgbcolor{fltkcolor76}{0.4961 0.5664 0}\n\\newrgbcolor{fltkcolor77}{0.4961 0.7109 0}\n\\newrgbcolor{fltkcolor78}{0.4961 0.8516 0}\n\\newrgbcolor{fltkcolor79}{0.4961 0.9961 0}\n\\newrgbcolor{fltkcolor80}{0.7461 0 0}\n\\newrgbcolor{fltkcolor81}{0.7461 0.1406 0}\n\\newrgbcolor{fltkcolor82}{0.7461 0.2812 0}\n\\newrgbcolor{fltkcolor83}{0.7461 0.4258 0}\n\\newrgbcolor{fltkcolor84}{0.7461 0.5664 0}\n\\newrgbcolor{fltkcolor85}{0.7461 0.7109 0}\n\\newrgbcolor{fltkcolor86}{0.7461 0.8516 0}\n\\newrgbcolor{fltkcolor87}{0.7461 0.9961 0}\n\\newrgbcolor{fltkcolor88}{0.9961 0 0}\n\\newrgbcolor{fltkcolor89}{0.9961 0.1406 0}\n\\newrgbcolor{fltkcolor90}{0.9961 0.2812 0}\n\\newrgbcolor{fltkcolor91}{0.9961 0.4258 0}\n\\newrgbcolor{fltkcolor92}{0.9961 0.5664 0}\n\\newrgbcolor{fltkcolor93}{0.9961 0.7109 0}\n\\newrgbcolor{fltkcolor94}{0.9961 0.8516 0}\n\\newrgbcolor{fltkcolor95}{0.9961 0.9961 0}\n\\newrgbcolor{fltkcolor96}{0 0 0.2461}\n\\newrgbcolor{fltkcolor97}{0 0.1406 0.2461}\n\\newrgbcolor{fltkcolor98}{0 0.2812 0.2461}\n\\newrgbcolor{fltkcolor99}{0 0.4258 0.2461}\n\\newrgbcolor{fltkcolor100}{0 0.5664 0.2461}\n\\newrgbcolor{fltkcolor101}{0 0.7109 0.2461}\n\\newrgbcolor{fltkcolor102}{0 0.8516 0.2461}\n\\newrgbcolor{fltkcolor103}{0 0.9961 0.2461}\n\\newrgbcolor{fltkcolor104}{0.2461 0 0.2461}\n\\newrgbcolor{fltkcolor105}{0.2461 0.1406 0.2461}\n\\newrgbcolor{fltkcolor106}{0.2461 0.2812 0.2461}\n\\newrgbcolor{fltkcolor107}{0.2461 0.4258 0.2461}\n\\newrgbcolor{fltkcolor108}{0.2461 0.5664 0.2461}\n\\newrgbcolor{fltkcolor109}{0.2461 0.7109 0.2461}\n\\newrgbcolor{fltkcolor110}{0.2461 0.8516 0.2461}\n\\newrgbcolor{fltkcolor111}{0.2461 0.9961 0.2461}\n\\newrgbcolor{fltkcolor112}{0.4961 0 0.2461}\n\\newrgbcolor{fltkcolor113}{0.4961 0.1406 0.2461}\n\\newrgbcolor{fltkcolor114}{0.4961 0.2812 0.2461}\n\\newrgbcolor{fltkcolor115}{0.4961 0.4258 0.2461}\n\\newrgbcolor{fltkcolor116}{0.4961 0.5664 0.2461}\n\\newrgbcolor{fltkcolor117}{0.4961 0.7109 0.2461}\n\\newrgbcolor{fltkcolor118}{0.4961 0.8516 0.2461}\n\\newrgbcolor{fltkcolor119}{0.4961 0.9961 0.2461}\n\\newrgbcolor{fltkcolor120}{0.7461 0 0.2461}\n\\newrgbcolor{fltkcolor121}{0.7461 0.1406 0.2461}\n\\newrgbcolor{fltkcolor122}{0.7461 0.2812 0.2461}\n\\newrgbcolor{fltkcolor123}{0.7461 0.4258 0.2461}\n\\newrgbcolor{fltkcolor124}{0.7461 0.5664 0.2461}\n\\newrgbcolor{fltkcolor125}{0.7461 0.7109 0.2461}\n\\newrgbcolor{fltkcolor126}{0.7461 0.8516 0.2461}\n\\newrgbcolor{fltkcolor127}{0.7461 0.9961 0.2461}\n\\newrgbcolor{fltkcolor128}{0.9961 0 0.2461}\n\\newrgbcolor{fltkcolor129}{0.9961 0.1406 0.2461}\n\\newrgbcolor{fltkcolor130}{0.9961 0.2812 0.2461}\n\\newrgbcolor{fltkcolor131}{0.9961 0.4258 0.2461}\n\\newrgbcolor{fltkcolor132}{0.9961 0.5664 0.2461}\n\\newrgbcolor{fltkcolor133}{0.9961 0.7109 0.2461}\n\\newrgbcolor{fltkcolor134}{0.9961 0.8516 0.2461}\n\\newrgbcolor{fltkcolor135}{0.9961 0.9961 0.2461}\n\\newrgbcolor{fltkcolor136}{0 0 0.4961}\n\\newrgbcolor{fltkcolor137}{0 0.1406 0.4961}\n\\newrgbcolor{fltkcolor138}{0 0.2812 0.4961}\n\\newrgbcolor{fltkcolor139}{0 0.4258 0.4961}\n\\newrgbcolor{fltkcolor140}{0 0.5664 0.4961}\n\\newrgbcolor{fltkcolor141}{0 0.7109 0.4961}\n\\newrgbcolor{fltkcolor142}{0 0.8516 0.4961}\n\\newrgbcolor{fltkcolor143}{0 0.9961 0.4961}\n\\newrgbcolor{fltkcolor144}{0.2461 0 0.4961}\n\\newrgbcolor{fltkcolor145}{0.2461 0.1406 0.4961}\n\\newrgbcolor{fltkcolor146}{0.2461 0.2812 0.4961}\n\\newrgbcolor{fltkcolor147}{0.2461 0.4258 0.4961}\n\\newrgbcolor{fltkcolor148}{0.2461 0.5664 0.4961}\n\\newrgbcolor{fltkcolor149}{0.2461 0.7109 0.4961}\n\\newrgbcolor{fltkcolor150}{0.2461 0.8516 0.4961}\n\\newrgbcolor{fltkcolor151}{0.2461 0.9961 0.4961}\n\\newrgbcolor{fltkcolor152}{0.4961 0 0.4961}\n\\newrgbcolor{fltkcolor153}{0.4961 0.1406 0.4961}\n\\newrgbcolor{fltkcolor154}{0.4961 0.2812 0.4961}\n\\newrgbcolor{fltkcolor155}{0.4961 0.4258 0.4961}\n\\newrgbcolor{fltkcolor156}{0.4961 0.5664 0.4961}\n\\newrgbcolor{fltkcolor157}{0.4961 0.7109 0.4961}\n\\newrgbcolor{fltkcolor158}{0.4961 0.8516 0.4961}\n\\newrgbcolor{fltkcolor159}{0.4961 0.9961 0.4961}\n\\newrgbcolor{fltkcolor160}{0.7461 0 0.4961}\n\\newrgbcolor{fltkcolor161}{0.7461 0.1406 0.4961}\n\\newrgbcolor{fltkcolor162}{0.7461 0.2812 0.4961}\n\\newrgbcolor{fltkcolor163}{0.7461 0.4258 0.4961}\n\\newrgbcolor{fltkcolor164}{0.7461 0.5664 0.4961}\n\\newrgbcolor{fltkcolor165}{0.7461 0.7109 0.4961}\n\\newrgbcolor{fltkcolor166}{0.7461 0.8516 0.4961}\n\\newrgbcolor{fltkcolor167}{0.7461 0.9961 0.4961}\n\\newrgbcolor{fltkcolor168}{0.9961 0 0.4961}\n\\newrgbcolor{fltkcolor169}{0.9961 0.1406 0.4961}\n\\newrgbcolor{fltkcolor170}{0.9961 0.2812 0.4961}\n\\newrgbcolor{fltkcolor171}{0.9961 0.4258 0.4961}\n\\newrgbcolor{fltkcolor172}{0.9961 0.5664 0.4961}\n\\newrgbcolor{fltkcolor173}{0.9961 0.7109 0.4961}\n\\newrgbcolor{fltkcolor174}{0.9961 0.8516 0.4961}\n\\newrgbcolor{fltkcolor175}{0.9961 0.9961 0.4961}\n\\newrgbcolor{fltkcolor176}{0 0 0.7461}\n\\newrgbcolor{fltkcolor177}{0 0.1406 0.7461}\n\\newrgbcolor{fltkcolor178}{0 0.2812 0.7461}\n\\newrgbcolor{fltkcolor179}{0 0.4258 0.7461}\n\\newrgbcolor{fltkcolor180}{0 0.5664 0.7461}\n\\newrgbcolor{fltkcolor181}{0 0.7109 0.7461}\n\\newrgbcolor{fltkcolor182}{0 0.8516 0.7461}\n\\newrgbcolor{fltkcolor183}{0 0.9961 0.7461}\n\\newrgbcolor{fltkcolor184}{0.2461 0 0.7461}\n\\newrgbcolor{fltkcolor185}{0.2461 0.1406 0.7461}\n\\newrgbcolor{fltkcolor186}{0.2461 0.2812 0.7461}\n\\newrgbcolor{fltkcolor187}{0.2461 0.4258 0.7461}\n\\newrgbcolor{fltkcolor188}{0.2461 0.5664 0.7461}\n\\newrgbcolor{fltkcolor189}{0.2461 0.7109 0.7461}\n\\newrgbcolor{fltkcolor190}{0.2461 0.8516 0.7461}\n\\newrgbcolor{fltkcolor191}{0.2461 0.9961 0.7461}\n\\newrgbcolor{fltkcolor192}{0.4961 0 0.7461}\n\\newrgbcolor{fltkcolor193}{0.4961 0.1406 0.7461}\n\\newrgbcolor{fltkcolor194}{0.4961 0.2812 0.7461}\n\\newrgbcolor{fltkcolor195}{0.4961 0.4258 0.7461}\n\\newrgbcolor{fltkcolor196}{0.4961 0.5664 0.7461}\n\\newrgbcolor{fltkcolor197}{0.4961 0.7109 0.7461}\n\\newrgbcolor{fltkcolor198}{0.4961 0.8516 0.7461}\n\\newrgbcolor{fltkcolor199}{0.4961 0.9961 0.7461}\n\\newrgbcolor{fltkcolor200}{0.7461 0 0.7461}\n\\newrgbcolor{fltkcolor201}{0.7461 0.1406 0.7461}\n\\newrgbcolor{fltkcolor202}{0.7461 0.2812 0.7461}\n\\newrgbcolor{fltkcolor203}{0.7461 0.4258 0.7461}\n\\newrgbcolor{fltkcolor204}{0.7461 0.5664 0.7461}\n\\newrgbcolor{fltkcolor205}{0.7461 0.7109 0.7461}\n\\newrgbcolor{fltkcolor206}{0.7461 0.8516 0.7461}\n\\newrgbcolor{fltkcolor207}{0.7461 0.9961 0.7461}\n\\newrgbcolor{fltkcolor208}{0.9961 0 0.7461}\n\\newrgbcolor{fltkcolor209}{0.9961 0.1406 0.7461}\n\\newrgbcolor{fltkcolor210}{0.9961 0.2812 0.7461}\n\\newrgbcolor{fltkcolor211}{0.9961 0.4258 0.7461}\n\\newrgbcolor{fltkcolor212}{0.9961 0.5664 0.7461}\n\\newrgbcolor{fltkcolor213}{0.9961 0.7109 0.7461}\n\\newrgbcolor{fltkcolor214}{0.9961 0.8516 0.7461}\n\\newrgbcolor{fltkcolor215}{0.9961 0.9961 0.7461}\n\\newrgbcolor{fltkcolor216}{0 0 0.9961}\n\\newrgbcolor{fltkcolor217}{0 0.1406 0.9961}\n\\newrgbcolor{fltkcolor218}{0 0.2812 0.9961}\n\\newrgbcolor{fltkcolor219}{0 0.4258 0.9961}\n\\newrgbcolor{fltkcolor220}{0 0.5664 0.9961}\n\\newrgbcolor{fltkcolor221}{0 0.7109 0.9961}\n\\newrgbcolor{fltkcolor222}{0 0.8516 0.9961}\n\\newrgbcolor{fltkcolor223}{0 0.9961 0.9961}\n\\newrgbcolor{fltkcolor224}{0.2461 0 0.9961}\n\\newrgbcolor{fltkcolor225}{0.2461 0.1406 0.9961}\n\\newrgbcolor{fltkcolor226}{0.2461 0.2812 0.9961}\n\\newrgbcolor{fltkcolor227}{0.2461 0.4258 0.9961}\n\\newrgbcolor{fltkcolor228}{0.2461 0.5664 0.9961}\n\\newrgbcolor{fltkcolor229}{0.2461 0.7109 0.9961}\n\\newrgbcolor{fltkcolor230}{0.2461 0.8516 0.9961}\n\\newrgbcolor{fltkcolor231}{0.2461 0.9961 0.9961}\n\\newrgbcolor{fltkcolor232}{0.4961 0 0.9961}\n\\newrgbcolor{fltkcolor233}{0.4961 0.1406 0.9961}\n\\newrgbcolor{fltkcolor234}{0.4961 0.2812 0.9961}\n\\newrgbcolor{fltkcolor235}{0.4961 0.4258 0.9961}\n\\newrgbcolor{fltkcolor236}{0.4961 0.5664 0.9961}\n\\newrgbcolor{fltkcolor237}{0.4961 0.7109 0.9961}\n\\newrgbcolor{fltkcolor238}{0.4961 0.8516 0.9961}\n\\newrgbcolor{fltkcolor239}{0.4961 0.9961 0.9961}\n\\newrgbcolor{fltkcolor240}{0.7461 0 0.9961}\n\\newrgbcolor{fltkcolor241}{0.7461 0.1406 0.9961}\n\\newrgbcolor{fltkcolor242}{0.7461 0.2812 0.9961}\n\\newrgbcolor{fltkcolor243}{0.7461 0.4258 0.9961}\n\\newrgbcolor{fltkcolor244}{0.7461 0.5664 0.9961}\n\\newrgbcolor{fltkcolor245}{0.7461 0.7109 0.9961}\n\\newrgbcolor{fltkcolor246}{0.7461 0.8516 0.9961}\n\\newrgbcolor{fltkcolor247}{0.7461 0.9961 0.9961}\n\\newrgbcolor{fltkcolor248}{0.9961 0 0.9961}\n\\newrgbcolor{fltkcolor249}{0.9961 0.1406 0.9961}\n\\newrgbcolor{fltkcolor250}{0.9961 0.2812 0.9961}\n\\newrgbcolor{fltkcolor251}{0.9961 0.4258 0.9961}\n\\newrgbcolor{fltkcolor252}{0.9961 0.5664 0.9961}\n\\newrgbcolor{fltkcolor253}{0.9961 0.7109 0.9961}\n\\newrgbcolor{fltkcolor254}{0.9961 0.8516 0.9961}\n\\newrgbcolor{fltkcolor255}{0.9961 0.9961 0.9961}\n"; #endif const char tex_end[]="\n\\end{document}"; const char mbox_begin[]="\\mathrm{"; // ("\\mbox{"); const char mbox_end[]="}"; string spread2tex(const matrice & m,int formule,GIAC_CONTEXT){ int l=int(m.size()); if (!l) return "\\mbox{empty_spread}"; int c=int(m.front()._VECTptr->size()); string s("\\ \\mbox{\\begin{tabular}{|"); for (int j=0;j<=c;++j) s += "r|"; s += "}\\hline\n & "; for (int k=0;;){ // write first line string tmp; int i=k; for(int j=0;;++j){ tmp=char('A'+i%26-(j!=0))+tmp; i=i/26; if (!i) break; } s += tmp; ++k; if (k==c){ s += " \\\\\\hline\n"; break; } else s += " & "; } for (int i=0;isize()); string s("\\left(\\begin{array}{"); for (int j=0;jtype==_CPLX && !is_zero(*it->_CPLXptr) && !is_zero(*(it->_CPLXptr+1))) || (it->type==_SYMB && ( it->_SYMBptr->sommet==at_plus || (it->_SYMBptr->sommet==at_neg && need_parenthesis(it->_SYMBptr->feuille)) ) ) ) s += string("(")+gen2tex(*it,contextptr)+string(")"); else s += gen2tex(*it,contextptr); ++it; if (it==itend) return s; if (it->type<=_IDNT || (it->type==_SYMB && (it->_SYMBptr->sommet==at_neg || (it->_SYMBptr->sommet.ptr()->printsommet && it->_SYMBptr->feuille.type==_VECT && !it->_SYMBptr->feuille._VECTptr->empty() && it->_SYMBptr->feuille._VECTptr->front().type<=_IDNT)) )) // second part of the test added for e.g. latex('2*3*5^2') s += "\\cdot "; else s += " "; } } string translate_underscore(const string & s){ string res; string::const_iterator it=s.begin(),itend=s.end(); for (;it!=itend;++it){ switch (*it){ case '_': res += "\\_"; break; case '^': res += "{\\tt\\symbol{94}}"; break; case '~': res += "{\\tt\\symbol{126}}"; break; case '<': res += "{\\tt\\symbol{60}}"; break; case '>': res += "{\\tt\\symbol{62}}"; break; case '\n': res += "\\\\\n"; break; case '&': res += "\\&"; break; case '{': res += "\\{"; break; case '}': res += "\\}"; break; case '\\': res += "$\\backslash $"; break; case '%': res += "\\%"; break; case '#': res += "\\#"; break; case '$': res += "\\$"; break; default: res += *it; } } string s0; greek2tex(res,s0,false); return s0; } static string fill_flag(bool flag){ if (flag) return "linestyle=none,fillstyle=solid,"; else return ""; } /* static string line_flag(int flag){ switch(flag) { case _STYLE_FULL : return ""; case _STYLE_DOTTED : return "[linestyle=dotted]"; case _STYLE_DASHED : return "[linestyle=dashed]"; } return "error"; } */ static string vector_flag(int flag){ switch(flag) { case _VECTOR__VECT : return "{->}"; // case BACKARROW : return "{<-}"; // case DOUBLEARROW : return "{<->}"; default : return ""; } } static string point_flag(int flag){ switch(flag) { case _STYLE_BOX : return "[dotstyle=square*]"; case _STYLE_CROSS : return "[dotstyle=x]"; case _STYLE_PLUS : return "[dotstyle=+]"; default : return "[dotstyle=*]"; } } #ifdef GIAC_HAS_STO_38 static string flcolor2pstrickscolor(int color){ switch(color) { case FL_BLACK: return "black"; case FL_WHITE: return "white"; case FL_DARK1: return "darkgray"; case FL_GRAY: return "gray"; } return "unknown"; } #else static string flcolor2pstrickscolor(int color){ switch(color) { case FL_BLACK: return "black"; case FL_DARK1: return "darkgray"; case FL_GRAY: return "gray"; case FL_LIGHT1 : return "lightgray"; #ifdef HAVE_LIBFLTK case _WHITE: return "white"; #endif case FL_WHITE : return "white"; #ifdef HAVE_LIBFLTK case _RED: return "red"; #endif case FL_RED : return "red"; #ifdef HAVE_LIBFLTK case _GREEN: return "green"; #endif case FL_GREEN : return "green"; #ifdef HAVE_LIBFLTK case _BLUE: return "blue"; #endif case FL_BLUE : return "blue"; #ifdef HAVE_LIBFLTK case _CYAN: return "cyan"; #endif case FL_CYAN : return "cyan"; #ifdef HAVE_LIBFLTK case _MAGENTA: return "magenta"; #endif case FL_MAGENTA : return "magenta"; #ifdef HAVE_LIBFLTK case _YELLOW: return "yellow"; #endif case FL_YELLOW : return "yellow"; default: return "black"; } return "fltkcolor"+print_INT_(color); } #endif // GIAC_HAS_STO_38 static string double2tex(double d){ char s[32]; #if 0 // def BESTA_OS assert(0); // returning an auto-var, when the string is constructed before the copy? // not the niceest of things to do.... // BP: I don't understand where you see a problem, a string is constructed from s // then the std::string is returned #else if (d<=-1e30 || d>=1e30) sprintfdouble(s,"%13g",d); else sprintfdouble(s,"%13.6f",d); #endif return s; } // convert UTF-8 string to wchar_t *, return adjusted length // FIXME: use utf82unicode instead? static unsigned int utf8(wchar_t * wline,const char * line,unsigned int n){ unsigned int i=0,j=0,c; for (;i=2;--j){ if (s0[j]>32 && isalpha(s0[j])) break; } string s=s0.substr(0,j+1),sadd; if (j=2){ if (v[1].type==_INT_) ensemble_attributs=v[1].val; if (v[1].type==_VECT){ vecteur & w=*v[1]._VECTptr; if (!w.empty() && (w.front().type==_INT_) ) ensemble_attributs=w.front().val; } } int width =(ensemble_attributs & 0x00070000) >> 16; // 3 bits // FIXME should be used! // int epaisseur_point =(ensemble_attributs & 0x00380000) >> 19; // 3 bits // int type_line =(ensemble_attributs & 0x01c00000) >> 22; // 3 bits int type_point =(ensemble_attributs & 0x0e000000) >> 25; // 3 bits labelpos =(ensemble_attributs & 0x30000000) >> 28; // 2 bits bool fill_polygon =((ensemble_attributs & 0x40000000) >> 30)!=0; couleur =(ensemble_attributs & 0x0000ffff); string col(flcolor2pstrickscolor(couleur)); ++width; if (file) fprintf(file,"\\psset{linecolor=%s}\n\\psset{linewidth=%.4fpt}\n", col.c_str(),width*0.5); if (sres) *sres += "\\psset{linecolor="+col+"}\n\\psset{linewidth="+double2tex(width*0.5)+"pt}\n"; // draw point/line/parametric gen point=v[0],x,y; // point is either a symb that evals to a complex or a param curve // or a vector of complex points // next line should be replaced by postscript (rpn) translation of curve // equation if possible if ( (point.type==_SYMB) && (point._SYMBptr->sommet==at_curve) && (point._SYMBptr->feuille.type==_VECT) && (point._SYMBptr->feuille._VECTptr->size()) ) point=point._SYMBptr->feuille._VECTptr->back(); if ( (point.type==_SYMB) && (point._SYMBptr->sommet==at_cercle)){ vecteur v=*point._SYMBptr->feuille._VECTptr; gen diametre=remove_at_pnt(v[0]); gen e1=diametre._VECTptr->front().evalf(1,contextptr),e2=diametre._VECTptr->back().evalf(1,contextptr); gen centre=rdiv(e1+e2,gen(2.0),contextptr),rayon=abs(rdiv(e2-e1,gen(2.0),contextptr),contextptr); x=evalf_double(re(centre,contextptr),1,contextptr); y=evalf_double(im(centre,contextptr),1,contextptr); if ( (x.type==_DOUBLE_) && (y.type==_DOUBLE_) && (rayon.type==_DOUBLE_) ){ xd=x._DOUBLE_val; yd=y._DOUBLE_val; if (v.size()>2){ gen theta1=evalf_double(v[1],1,contextptr),theta2=evalf_double(v[2],1,contextptr); //grad int mode=get_mode_set_radian(contextptr); gen angle=arg(e2-e1,contextptr).evalf_double(1,contextptr); angle_mode(mode, contextptr); if (theta1.type==_DOUBLE_ && theta2.type==_DOUBLE_ && angle.type==_DOUBLE_){ double t1=theta1._DOUBLE_val,t2=theta2._DOUBLE_val; if (t1>t2){ double tmp=t1; t1=t2; t2=tmp; } t1=(t1+angle._DOUBLE_val)*rad2deg_d; t2=(t2+angle._DOUBLE_val)*rad2deg_d; if (file) fprintf (file,"\\pswedge[%sfillcolor=%s](%.4f,%.4f){%.4f}{%.4f}{%.4f}\n",fill_flag(fill_polygon).c_str(),col.c_str(),xd,yd,rayon._DOUBLE_val,t1,t2); // was psarc if (sres) *sres += "\\pswedge[" + fill_flag(fill_polygon) + "fillcolor=" + col + "](" + double2tex(xd)+","+double2tex(yd)+"){" + double2tex(rayon._DOUBLE_val) + "}{" + double2tex(t1)+ "}{" + double2tex(t2) + "}\n"; xd=x._DOUBLE_val+rayon._DOUBLE_val*std::cos(t1); yd=y._DOUBLE_val+rayon._DOUBLE_val*std::sin(t1); return true; } } if (file) fprintf(file,"\\pscircle[%sfillcolor=%s](%.4f,%.4f){%.4f}\n",fill_flag(fill_polygon).c_str(),col.c_str(),xd,yd,rayon._DOUBLE_val); if (sres) *sres += "\\pscircle["+fill_flag(fill_polygon)+"fillcolor="+col+ "]("+ double2tex(xd)+","+double2tex(yd)+"){"+ double2tex(rayon._DOUBLE_val)+"}\n"; xd=x._DOUBLE_val+rayon._DOUBLE_val; return true; } return false; } // end cercle if (point.type!=_VECT){ // single point point=evalf_double(point,1,contextptr); x=re(point,contextptr); y=im(point,contextptr).evalf(1,contextptr); if ( (x.type==_DOUBLE_) && (y.type==_DOUBLE_) ){ xd=x._DOUBLE_val; yd=y._DOUBLE_val; if (file) fprintf(file,"\\psdots%s(%.4f,%.4f)\n", point_flag(type_point).c_str(), xd, yd); if (sres) *sres += "\\psdots"+point_flag(type_point)+"("+double2tex(xd)+","+double2tex(yd)+")\n"; return true; } return false; } vecteur & w=*point._VECTptr; int ws=int(w.size()); if (ws==2){ gen A=w[0].evalf(1,contextptr),B=w[1].evalf(1,contextptr); gen Ax=re(A,contextptr),Ay=im(A,contextptr).evalf(1,contextptr), Bx=re(B,contextptr),By=im(B,contextptr).evalf(1,contextptr); if ( (Ax.type==_DOUBLE_) && (Ay.type==_DOUBLE_) && (Bx.type==_DOUBLE_) && (By.type==_DOUBLE_) ){ double ax=Ax._DOUBLE_val,ay=Ay._DOUBLE_val,bx=Bx._DOUBLE_val,by=By._DOUBLE_val; xd=(ax+bx)/2.; yd=(ay+by)/2.; if (point.subtype==_GROUP__VECT) drawlegende=false; double x1,y1,x2,y2; if (point.subtype!=_HALFLINE__VECT){ clip_line(ax,ay,bx,by,xmin,ymin,xmax,ymax,point.subtype,x1,y1,x2,y2); if (file) fprintf(file,"\\psline%s(%.4f,%.4f)(%.4f,%.4f)\n",vector_flag(point.subtype).c_str(), x1,y1,x2,y2); if (sres) *sres += "\\psline"+vector_flag(point.subtype)+ "("+double2tex(x1)+","+double2tex(y1)+")("+ double2tex(x2)+","+double2tex(y2)+")\n"; return true; } double vx=bx-ax,vy=by-ay; // check for line/halfline bx=bx+5*vx; by=by+5*vy; // FIXME: improve clipping!! Removed here if (file) fprintf(file,"\\psline%s(%.4f,%.4f)(%.4f,%.4f)\n",vector_flag(point.subtype).c_str(),ax,ay,bx,by); if (sres) *sres += "\\psline"+vector_flag(point.subtype)+"("+double2tex(ax)+","+double2tex(ay)+")("+double2tex(bx)+","+double2tex(by)+")\n"; return true; } // end DOUBLE types return false; } // end w.size()==2 // multi-line string prefixstr,printstring; if (fill_polygon) printstring="\\pspolygon["+fill_flag(fill_polygon)+"fillcolor="+col+"]"; else prefixstr = "\\psline[fillcolor="+col+"]"; double xprec=0,yprec=0,xa,ya,xb,yb; for (int i=0;ibegin(),itend=g._VECTptr->end(); for (;it!=itend;++it) invectpnt2tex(file,*it,X1,X2,Y1,Y2,xunit,yunit,resptr,contextptr); } else { if (g.is_symb_of_sommet(at_pnt) && !is3d(g)){ gen & feu = g._SYMBptr->feuille; if (feu.type==_VECT){ vecteur & arg=*feu._VECTptr; double xd,yd; bool drawlegende; int labelpos,couleur; if (pnt2tex(file,arg,X1,Y1,X2,Y2,xd,yd,drawlegende,labelpos,couleur,resptr,contextptr)){ if (drawlegende && (arg.size()>2)){ xunit=(gnuplot_xmax-gnuplot_xmin); pnt2texlegende(file,arg,xd,yd,xunit,couleur,labelpos,resptr); } } } } } } // evalf_double of a and splt re/im void evalfdouble2reim(const gen & a,gen & e,gen & f0,gen & f1,GIAC_CONTEXT){ if (a.type==_CPLX){ f0=a._CPLXptr->evalf2double(1,contextptr); f1=(a._CPLXptr+1)->evalf2double(1,contextptr); if (a._CPLXptr->type==_DOUBLE_ && (a._CPLXptr+1)->type==_DOUBLE_) e=a; else e=gen(f0._DOUBLE_val,f1._DOUBLE_val); return ; } #ifndef NO_STDEXCEPT try { #endif e=a.evalf_double(1,contextptr); // FIXME? level 1 does not work for non 0 context #ifndef NO_STDEXCEPT } catch (std::runtime_error & error ){ CERR << error.what() << endl; } #endif if (e.type==_CPLX){ f0=*e._CPLXptr; f1=*(e._CPLXptr+1); } else { f0=e; f1=0.0; } } static bool in_autoscale(const gen & g,vector & vx,vector & vy,vector & vz,GIAC_CONTEXT){ if (g.type==_VECT && g.subtype==_POINT__VECT && g._VECTptr->size()==3){ vecteur v=*evalf_double(g,1,contextptr)._VECTptr; if (v[2].type==_CPLX) v[2]=abs(v[2],contextptr); if (v[0].type==_DOUBLE_ && v[1].type==_DOUBLE_ && v[2].type==_DOUBLE_ ){ vx.push_back(v[0]._DOUBLE_val); vy.push_back(v[1]._DOUBLE_val); vz.push_back(v[2]._DOUBLE_val); return false; } } if (g.type==_VECT ){ bool ortho=false; const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); for (;it!=itend;++it){ ortho = ortho | in_autoscale(*it,vx,vy,vz,contextptr); } return ortho; } if (g.is_symb_of_sommet(at_curve)){ gen & gf=g._SYMBptr->feuille; if (gf.type==_VECT && gf._VECTptr->size()>1){ in_autoscale((*gf._VECTptr)[1],vx,vy,vz,contextptr); } return false; } if (g.is_symb_of_sommet(at_hypersurface)){ gen & g0=g._SYMBptr->feuille; if (g0.type==_VECT && g0._VECTptr->size()>2){ gen & gf=g0._VECTptr->front(); if (gf.type==_VECT && gf._VECTptr->size()>4){ in_autoscale((*gf._VECTptr)[4],vx,vy,vz,contextptr); } } return false; } if (g.is_symb_of_sommet(at_cercle)){ gen c,r; centre_rayon(g,c,r,false,contextptr); if (is_zero(r)) r=1; vecteur v; if (g._SYMBptr->feuille.type==_VECT && g._SYMBptr->feuille._VECTptr->size()>=3){ v=*g._SYMBptr->feuille._VECTptr; gen delta=v[2]-v[1]; v=makevecteur(c-r*exp(cst_i*(v[1]-0.1*delta),contextptr), c-r*exp(cst_i*v[1],contextptr), c-r*exp(cst_i*(3*v[1]+v[2])/gen(4),contextptr), c-r*exp(cst_i*(v[1]+v[2])/gen(2),contextptr), c-r*exp(cst_i*(v[1]+3*v[2])/gen(4),contextptr), c-r*exp(cst_i*v[2],contextptr), c-r*exp(cst_i*(v[2]+0.1*delta),contextptr)); // FIXME? centre_rayon returns (a-b)/2 for rayon instead of (b-a)/2... } else v=makevecteur(c-r,c+r,c-cst_i*r,c+cst_i*r); in_autoscale(v,vx,vy,vz,contextptr); return true; } // FIXME sphere etc. if (g.type!=_VECT){ gen e,f0,f1; evalfdouble2reim(g,e,f0,f1,contextptr); if (f0.type==_DOUBLE_ && f1.type==_DOUBLE_){ vx.push_back(f0._DOUBLE_val); vy.push_back(f1._DOUBLE_val); } } return false; } bool autoscaleg(const gen & g,vector & vx,vector & vy,vector & vz,GIAC_CONTEXT){ if (g.type==_VECT){ bool ortho=false; const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end(); for (;it!=itend;++it) ortho = ortho | autoscaleg(*it,vx,vy,vz,contextptr); return ortho; } if (g.is_symb_of_sommet(at_pnt)){ gen & gf=g._SYMBptr->feuille; if (gf.type==_VECT && !gf._VECTptr->empty()){ gen & f=gf._VECTptr->front(); return in_autoscale(f,vx,vy,vz,contextptr); } } if (g.is_symb_of_sommet(at_equal) && g._SYMBptr->feuille.type==_VECT && g._SYMBptr->feuille._VECTptr->size()==2 && g._SYMBptr->feuille._VECTptr->front()==_GL_ORTHO && !is_zero(g._SYMBptr->feuille._VECTptr->back())) return true; return false; } void overwrite_viewbox(const gen & g,double & window_xmin,double & window_xmax,double & window_ymin,double & window_ymax,double &window_zmin,double & window_zmax){ if (g.type==_VECT){ vecteur v =*g._VECTptr; for (int i=0;ifeuille; if (f.type==_VECT && f._VECTptr->size()==2){ gen optname= f._VECTptr->front(),optvalue=f._VECTptr->back(); if (optvalue.is_symb_of_sommet(at_interval) && optname.type==_INT_ && optname.subtype==_INT_PLOT && optname.val>=_GL_X && optname.val<=_GL_Z){ gen optvf=evalf_double(optvalue._SYMBptr->feuille,1,context0); if (optvf.type==_VECT && optvf._VECTptr->size()==2){ gen a=optvf._VECTptr->front(); gen b=optvf._VECTptr->back(); if (a.type==_DOUBLE_ && b.type==_DOUBLE_){ switch (optname.val){ case _GL_X: window_xmin=a._DOUBLE_val; window_xmax=b._DOUBLE_val; break; case _GL_Y: window_ymin=a._DOUBLE_val; window_ymax=b._DOUBLE_val; break; case _GL_Z: window_zmin=a._DOUBLE_val; window_zmax=b._DOUBLE_val; break; } } } } } } } static void zoom(double &m,double & M,double d){ double x_center=(M+m)/2; double dx=(M-m); double s=std::abs(m)+std::abs(M); if (dx<=1e-5*s){ dx=s; if (dx<=1e-5) dx=1; } dx *= d/2; m = x_center - dx; M = x_center + dx; } void autoscaleminmax(vector & v,double & m,double & M,bool fullview){ int s=int(v.size()); if (s==0){ v.push_back(0); ++s; } if (s==1){ v.push_back(v.front()); ++s; } if (s>1){ sort(v.begin(),v.end()); m=v[s/10]; M=v[9*s/10]; if (fullview || 2*(M-m)>(v[s-1]-v[0]) || (M-m)<0.01*(v[s-1]-v[0])){ M=v[s-1]; m=v[0]; zoom(m,M,1.1); } else zoom(m,M,1/0.8); } } static string vectpnt2tex(const gen & g,GIAC_CONTEXT){ string res; double X1=gnuplot_xmin,X2=gnuplot_xmax,Y1=gnuplot_ymin,Y2=gnuplot_ymax; vector vx,vy,vz; autoscaleg(g,vx,vy,vz,contextptr); autoscaleminmax(vx,X1,X2,false); autoscaleminmax(vy,Y1,Y2,false); double xunit=giac::horiz_latex/(X2-X1); double yunit=(X2-X1)/(Y2-Y1)*xunit; res="\\begin{pspicture}("+double2tex(X1*xunit)+","+double2tex(Y1*xunit)+ ")("+double2tex(X2*xunit)+","+double2tex(Y2*xunit)+ ")\n\\psset{unit="+double2tex(xunit)+ "cm}\n\\psset{linewidth=.5pt}\n\\psset{arrowsize=2pt 4}\n"; res+="\\psset{linecolor=black}\n"; if (show_axes(contextptr) && (Y2>=0) && (Y1<=0) ) res+="\\psline[linestyle=dashed]{->}("+double2tex(X1)+","+double2tex(0.0)+")("+double2tex(X2)+","+double2tex(0.0)+")\n"; if (show_axes(contextptr) && (X2>=0) && (X1<=0) ) res+="\\psline[linestyle=dashed]{->}("+double2tex(0.0)+","+double2tex(Y1)+")("+double2tex(0.0)+","+double2tex(Y2)+")\n"; invectpnt2tex(0,g,X1,X2,Y1,Y2,xunit,yunit,&res,contextptr); res += "\\end{pspicture}\n"; return res; } static string symbolic2tex(const symbolic & mys,GIAC_CONTEXT){ const gen &feu=mys.feuille; if (mys.sommet==at_pnt && feu.type==_VECT && !is3d(mys)) return vectpnt2tex(mys,contextptr); if (mys.sommet.ptr()->texprint) return mys.sommet.ptr()->texprint(feu,mys.sommet.ptr()->s,contextptr); if (mys.sommet==at_abs) return '|'+gen2tex(feu,contextptr)+'|'; string opstring=idnt2tex(mys.sommet.ptr()->print(contextptr)); if ( (feu.type==_VECT) && (feu._VECTptr->empty()) ) return opstring+string("()"); if ( (feu.type!=_VECT) || (feu._VECTptr->front().type==_VECT && mys.sommet!=at_pow) ){ if ((mys.sommet==at_neg) || (mys.sommet==at_plus)){ if (feu.type!=_SYMB) return opstring+gen2tex(feu,contextptr) ; if (feu._SYMBptr->sommet==at_inv || !need_parenthesis(feu._SYMBptr->feuille)) return opstring+gen2tex(feu,contextptr) ; return opstring+string("\\left(") + gen2tex(feu,contextptr) +string("\\right)"); } if (mys.sommet==at_inv && (feu.is_symb_of_sommet(at_prod) || feu.is_symb_of_sommet(at_plus) || feu.is_symb_of_sommet(at_pow) || feu.type<=_IDNT) ){ if (feu.type==_IDNT) return gen2tex(feu,contextptr)+"^{-1}"; return string("\\frac{1}{") + gen2tex(feu,contextptr) +string("}"); } return opstring + "\\left(" + gen2tex(feu,contextptr) +"\\right)" ; } string s; int l=int(feu._VECTptr->size()); if ( mys.sommet==at_plus ){ for (int i=0;isommet==at_neg)){ s += "-"; if (e._SYMBptr->feuille.type!=_CPLX && (e._SYMBptr->feuille.type!=_SYMB || e._SYMBptr->feuille._SYMBptr->sommet==at_inv || e._SYMBptr->feuille._SYMBptr->sommet==at_prod|| !need_parenthesis(e._SYMBptr->feuille)) ) s += gen2tex(e._SYMBptr->feuille,contextptr) ; else s += "\\left(" + gen2tex(e._SYMBptr->feuille,contextptr) + "\\right)"; } else { if ( e.type<=_REAL && !is_positive(e,0) ) s += e.print(contextptr); else { string sadd=gen2tex(e,contextptr); if (i){ if (opstring=="+" && !sadd.empty() && sadd[0]=='-') ; else s += opstring; } s += sadd; } } } // end_for return s; } if (mys.sommet==at_prod) { vecteur num; vecteur den; for (int i=0;isommet==at_inv) ) den.push_back(e._SYMBptr->feuille); else { if (!den.empty()){ s += "\\frac{"+prod_vect2tex(num,contextptr)+"}{"+prod_vect2tex(den,contextptr)+"} \\cdot "; num.clear(); den.clear(); } num.push_back(e); } } if (den.empty()) return s+prod_vect2tex(num,contextptr); return s+"\\frac{"+prod_vect2tex(num,contextptr)+"}{"+prod_vect2tex(den,contextptr)+'}'; } // end if sommet_is_prod if (mys.sommet==at_pow){ vecteur & v=*feu._VECTptr; if ( (v.back()==plus_one_half) ) return "\\sqrt{"+gen2tex(v.front(),contextptr)+"}"; if ( v.back()==minus_one_half || v.back()==fraction(minus_one,plus_two) ) return "\\frac{1}{\\sqrt{"+gen2tex(v.front(),contextptr)+"}}"; string res=gen2tex(v.front(),contextptr); bool par = (v.front().type>=_CPLX || is_strictly_positive(-v.front(),contextptr) ) && v.front().type!=_IDNT && !ckmatrix(v.front()); if (par && !v.front().is_symb_of_sommet(at_plus)){ int ress=int(res.size()),i; for (i=1;iempty() && e._VECTptr->back().is_symb_of_sommet(at_pnt) && !is3d(e._VECTptr->back()) ) return vectpnt2tex(e,contextptr); if (ckmatrix(*e._VECTptr)) return matrix2tex(*e._VECTptr,contextptr); else return _VECT2tex(*e._VECTptr,e.subtype,contextptr); case _POLY: return mbox_begin+string("polynome")+mbox_end+" "; case _SPOL1: return gen2tex(spol12gen(*e._SPOL1ptr,contextptr),contextptr); case _FRAC: return string("\\frac{")+gen2tex(e._FRACptr->num,contextptr)+"}{"+gen2tex(e._FRACptr->den,contextptr)+'}'; case _EXT: return ""; case _STRNG: return idnt2tex(*e._STRNGptr); case _FUNC: return idnt2tex(e.print(contextptr)); case _USER: return e._USERptr->texprint(contextptr); case _MOD: return gen2tex(*e._MODptr,contextptr)+"\\%"+gen2tex(*(e._MODptr+1),contextptr); case _POINTER_: if (e.subtype==_FL_WIDGET_POINTER &&fl_widget_texprint_function ) return fl_widget_texprint_function(e._POINTER_val); return "Done"; default: return "Error in Tex conversion for "+e.print(contextptr); } return 0; } gen _latex(const gen & g,GIAC_CONTEXT){ if ( g.type==_STRNG && g.subtype==-1) return g; #ifndef NSPIRE if (!secure_run && g.type==_VECT && g.subtype==_SEQ__VECT && g._VECTptr->size()==2 && (*g._VECTptr)[1].type==_STRNG){ ofstream of((*g._VECTptr)[1]._STRNGptr->c_str()); of << gen2tex(g._VECTptr->front(),contextptr) << endl; return plus_one; } #endif return string2gen(gen2tex(g,contextptr),false); } static const char _latex_s []="latex"; static define_unary_function_eval (__latex,&_latex,_latex_s); define_unary_function_ptr5( at_latex ,alias_at_latex,&__latex,0,true); static const char _TeX_s []="TeX"; static define_unary_function_eval (__TeX,&_latex,_TeX_s); define_unary_function_ptr5( at_TeX ,alias_at_TeX,&__TeX,0,true); int graph2tex(FILE * file,const vecteur & v,double X1,double X2,double Y1,double Y2,double Unit,const char * filename,bool logo,GIAC_CONTEXT){ return graph2tex(file,v,X1,X2,Y1,Y2,Unit,Unit,filename,logo,contextptr); } static int ingraph2tex(FILE * file,const vecteur & v,double xunit,double yunit,double xmin, double ymin,double xmax,double ymax,GIAC_CONTEXT){ vecteur w; const_iterateur it=v.begin(),itend=v.end(); for (;it!=itend;++it){ gen sortie=*it; // CERR << "graph2tex " << *it << endl; if (sortie.type==_POINTER_ && sortie.subtype==_FL_WIDGET_POINTER && fl_widget_updatepict_function) sortie = fl_widget_updatepict_function(sortie); if (sortie.type!=_VECT) w=vecteur(1,sortie); else w=*sortie._VECTptr; const_iterateur jt=w.begin(),jtend=w.end(); for (;jt!=jtend;++jt){ if (jt->type==_VECT) ingraph2tex(file,*jt->_VECTptr,xunit,yunit,xmin,ymin,xmax,ymax,contextptr); if ( (jt->type!=_SYMB) || (jt->_SYMBptr->sommet!=at_pnt) ) continue; gen & g=jt->_SYMBptr->feuille; if (g.type!=_VECT) continue; vecteur & arg=*g._VECTptr; double xd,yd; bool drawlegende; int labelpos,couleur; if (pnt2tex(file,arg,xmin,ymin,xmax,ymax,xd,yd,drawlegende,labelpos,couleur,0,contextptr) && drawlegende && (arg.size()>2)) pnt2texlegende(file,arg,xd,yd,xunit,couleur,labelpos,0); } } return 1; } int graph2tex(FILE * file,const vecteur & v,double X1,double X2,double Y1,double Y2,double xunit,double yunit,const char * filename,bool logo,GIAC_CONTEXT){ double z(0); if (filename) fprintf(file,"\n%%file %s",filename); fprintf(file,"\n%% Generated by xcas\n\\noindent\n"); // BUG xunit/yunit do not work for circles, FIXME if (xunit!=yunit) fprintf(file,"\\begin{pspicture}(%.4f,%.4f)(%.4f,%.4f)\n\\psset{unit=%.4fcm}\n\\psset{xunit=%.4fcm}\n\\psset{yunit=%.4fcm}\n\\psset{linewidth=.5pt}\n\\psset{arrowsize=2pt 4}\n", X1*xunit,Y1*yunit,X2*xunit,Y2*yunit,xunit,xunit,yunit); else fprintf(file,"\\begin{pspicture}(%.4f,%.4f)(%.4f,%.4f)\n\\psset{unit=%.4fcm}\n\\psset{linewidth=.5pt}\n\\psset{arrowsize=2pt 4}\n", X1*xunit, Y1*xunit, X2*xunit, Y2*xunit,xunit); fprintf(file,"\\psset{linecolor=black}\n"); if (logo){ // fprintf(file,"\\psframe[fillstyle=solid,fillcolor=gray](%.4f,%.4f)(%.4f,%.4f)\n",X1,Y1,X2,Y2); vector w=vecteur2turtlevect(v); vector * turtleptr=&w; int l=int(turtleptr->size()); if (l>0){ double labelsep(0.1/xunit),angle(45); fprintf(file,"%s{%.4f}[%.4f](%.4f,%.4f){%s%i}\n","%\\uput",labelsep,angle,X2-100,Y2-25, "x ",int(turtleptr->back().x+.5)); fprintf(file,"%s{%.4f}[%.4f](%.4f,%.4f){%s%i}\n","%\\uput",labelsep,angle,X2-100,Y2-48, "y ",int(turtleptr->back().y+.5)); fprintf(file,"%s{%.4f}[%.4f](%.4f,%.4f){%s%i}\n","%\\uput",labelsep,angle,X2-100,Y2-65, "t ",int(turtleptr->back().theta+.5)); logo_turtle prec =(*turtleptr)[0]; for (int k=1;k0){ int r=current.radius & 0x1ff; // bit 0-8 double theta1,theta2; if (current.direct){ theta1=prec.theta+double((current.radius >> 9) & 0x1ff); // bit 9-17 theta2=prec.theta+double((current.radius >> 18) & 0x1ff); // bit 18-26 } else { theta1=prec.theta-double((current.radius >> 9) & 0x1ff); // bit 9-17 theta2=prec.theta-double((current.radius >> 18) & 0x1ff); // bit 18-26 } bool rempli=(current.radius >> 27) & 0x1; double angle; double x,y; angle = M_PI/180*(theta2-90); if (current.direct){ x=current.x - r*std::cos(angle); y=current.y - r*std::sin(angle); } else { x=current.x + r*std::cos(angle); y=current.y + r*std::sin(angle); } if (current.direct){ if (rempli){ fprintf(file,"\\pswedge*[fillcolor="); fprintf(file,"%s",flcolor2pstrickscolor(prec.color).c_str()); fprintf(file,"]"); } else fprintf(file,"\\psarc"); fprintf(file,"(%.4f,%.4f){%.4f}{%.4f}{%.4f}\n",x,y,double(r),theta1-90,theta2-90); } else { if (rempli){ fprintf(file,"\\pswedge*[fillcolor="); fprintf(file,"%s",flcolor2pstrickscolor(prec.color).c_str()); fprintf(file,"]"); } else fprintf(file,"\\psarc"); fprintf(file,"(%.4f,%.4f){%.4f}{%.4f}{%.4f}\n",x,y,double(r),theta2+90,theta1+90); } } // end radius>0 else { if (prec.mark && (prec.x!=current.x || prec.y!=current.y) ){ fprintf(file,"\\psline(%.4f,%.4f)(%.4f,%.4f)\n", prec.x,prec.y,current.x,current.y); } } if (current.radius<-1 && k+current.radius>=0){ // poly-line from (*turtleptr)[k+current.radius] to (*turtleptr)[k] string printstring("\\pspolygon[linestyle=none,fillstyle=solid,fillcolor="+flcolor2pstrickscolor(prec.color)+"]"); for (int i=0;i>=current.radius;--i){ logo_turtle & t=(*turtleptr)[k+i]; printstring += "("+double2tex(t.x)+","+double2tex(t.y)+")"; } printstring += "("+double2tex(current.x)+","+double2tex(current.y)+")\n"; fprintf(file,"%s",printstring.c_str()); } } // end else (non-string turtle record) prec=current; } // end for (all turtle records) logo_turtle & t = (*turtleptr)[l-1]; double x=t.x,y=t.y; double cost=std::cos(t.theta*deg2rad_d); double sint=std::sin(t.theta*deg2rad_d); double Dx=t.turtle_length*cost/2; double Dy=t.turtle_length*sint/2; string col(flcolor2pstrickscolor(prec.color)); fprintf(file,"\\psset{linecolor=%s}\n", col.c_str()); if (t.visible){ fprintf(file,"\\psline(%.4f,%.4f)(%.4f,%.4f)\n", x+Dy, y-Dx, x-Dy, y+Dx); // fl_line(deltax+x+Dy,deltay+h()-(y-Dx),deltax+x-Dy,deltay+h()-(y+Dx)); if (!t.mark){ string col(flcolor2pstrickscolor(t.color+1)); fprintf(file,"\\psset{linecolor=%s}\n", col.c_str()); } fprintf(file,"\\psline(%.4f,%.4f)(%.4f,%.4f)\n", x+Dy, y-Dx, x+3*Dx, y+3*Dy); fprintf(file,"\\psline(%.4f,%.4f)(%.4f,%.4f)\n", x-Dy, y+Dx, x+3*Dx, y+3*Dy); } // end if t.visible } // end if l>0 } // end if logo else { if (show_axes(contextptr) && (Y2>=0) && (Y1<=0) ) fprintf(file,"\\psline[linestyle=dashed]{->}(%.4f,%.4f)(%.4f,%.4f)\n",X1,z,X2,z); if (show_axes(contextptr) && (X2>=0) && (X1<=0) ) fprintf(file,"\\psline[linestyle=dashed]{->}(%.4f,%.4f)(%.4f,%.4f)\n",z,Y1,z,Y2); ingraph2tex(file,v,xunit,yunit,X1,Y1,X2,Y2,contextptr); } fprintf(file,"\\end{pspicture} \n\n"); return 1; } int graph2tex(const string &s,const vecteur & v,double X1,double X2,double Y1,double Y2,double Unit,bool logo,GIAC_CONTEXT){ return graph2tex(s,v,X1,X2,Y1,Y2,Unit,Unit,logo,contextptr); } std::string get_path(const string & st){ int s=int(st.size()),i; for (i=s-1;i>=0;--i){ if (st[i]=='/') break; } return st.substr(0,i+1); } std::string remove_path(const std::string & st){ int s=int(st.size()),i; for (i=s-1;i>=0;--i){ if (st[i]=='/') break; } return st.substr(i+1,s-i-1); } int graph2tex(const string &s,const vecteur & v,double X1,double X2,double Y1,double Y2,double xunit,double yunit,bool logo,GIAC_CONTEXT){ if (is_undef(check_secure())) return 0; // int file; // file = open (s.c_str(), O_WRONLY); // if (file==-1) // return file; // int savestdout; // dup2(STDOUT_FILENO,savestdout); // dup2(file,STDOUT_FILENO); // Begin eukleides code with redirected stdout FILE * filecol=fopen((get_path(s)+"fltkcol.tex").c_str(),"w"); if (!filecol){ CERR << "Unable to open color file fltkcol.tex" << endl; return 0; } fprintf(filecol,"%s",tex_color); fclose(filecol); FILE * file=fopen(s.c_str(), "w"); if (!file){ CERR << "Unable to open file "+s << endl; return 0; } fprintf(file,"%s",tex_preamble); fprintf(file,"\\input fltkcol.tex"); graph2tex(file,v,X1,X2,Y1,Y2,xunit,yunit,s.c_str(),logo,contextptr); fprintf(file,"\\end{document}\n"); fclose(file); return 1; // End eukleides code, restore stdout // dup2(savestdout,STDOUT_FILENO); } gen _graph2tex(const gen & args,GIAC_CONTEXT){ if ( args.type==_STRNG && args.subtype==-1) return args; int i=erase_pos(contextptr); vecteur hist(history_out(contextptr).begin()+i,history_out(contextptr).end()); return graph2tex(args,hist,contextptr); } gen graph2tex(const gen & args,const vecteur & hist,GIAC_CONTEXT){ if (args.type==_STRNG){ double horiz_unit=horiz_latex/(gnuplot_xmax-gnuplot_xmin); double vert_unit=vert_latex/(gnuplot_ymax-gnuplot_ymin); double unit=horiz_unit; if (horiz_unit>vert_unit) unit=vert_unit; return graph2tex(*args._STRNGptr,hist,gnuplot_xmin,gnuplot_xmax,gnuplot_ymin,gnuplot_ymax,unit,false,contextptr); } if ( (args.type!=_VECT) || (args._VECTptr->size()<2) ) return symbolic(at_graph2tex,args); vecteur & v=*args._VECTptr; int vs=int(v.size()); if ( (v[0].type!=_STRNG) || (v[1].type!=_DOUBLE_) ) return gensizeerr(); if ( (vs>2) && (v[2].type==_DOUBLE_) ) gnuplot_xmin=v[2]._DOUBLE_val; if ( (vs>3) && (v[3].type==_DOUBLE_) ) gnuplot_xmax=v[3]._DOUBLE_val; if ( (vs>4) && (v[4].type==_DOUBLE_) ) gnuplot_ymin=v[4]._DOUBLE_val; if ( (vs>5) && (v[5].type==_DOUBLE_) ) gnuplot_ymax=v[5]._DOUBLE_val; return graph2tex(*v[0]._STRNGptr,hist,gnuplot_xmin,gnuplot_xmax,gnuplot_ymin,gnuplot_ymax,v[1]._DOUBLE_val,false,contextptr); } static const char _graph2tex_s []="graph2tex"; static define_unary_function_eval (__graph2tex,&_graph2tex,_graph2tex_s); define_unary_function_ptr5( at_graph2tex ,alias_at_graph2tex,&__graph2tex,0,true); gen _graph3d2tex(const gen & args,GIAC_CONTEXT){ if ( args.type==_STRNG && args.subtype==-1) return args; gen tmp=check_secure(); if (is_undef(tmp)) return tmp; if (args.type==_STRNG){ string & s=*args._STRNGptr; #ifdef WITH_GNUPLOT bool clrplot; int out_handle; FILE * gnuplot_out_readstream,* stream = open_gnuplot(clrplot,gnuplot_out_readstream,out_handle); latex_replot(stream,s); gnuplot_wait(out_handle,gnuplot_out_readstream,5); #endif return string2gen(s,false); } else { // search in history for the last plot command answer == to an int int s=giacmin(int(history_out(contextptr).size()),int(history_in(contextptr).size())); for (int i=s-1;i>=0;--i){ if (history_out(contextptr)[i].is_symb_of_sommet(at_pnt) && history_out(contextptr)[i].subtype>=0) return history_out(contextptr)[i].subtype; if ( history_out(contextptr)[i].type==_INT_ && history_in(contextptr)[i].type==_SYMB && ( equalposcomp(implicittex_plot_sommets,history_in(contextptr)[i]._SYMBptr->sommet) || equalposcomp(notexprint_plot_sommets,history_in(contextptr)[i]._SYMBptr->sommet) ) ) return history_out(contextptr)[i]; } return undef; } } static const char _graph3d2tex_s []="graph3d2tex"; static define_unary_function_eval (__graph3d2tex,&_graph3d2tex,_graph3d2tex_s); define_unary_function_ptr5( at_graph3d2tex ,alias_at_graph3d2tex,&__graph3d2tex,0,true); #ifndef NO_NAMESPACE_GIAC } // namespace giac #endif // ndef NO_NAMESPACE_GIAC