Subversion Repositories wimsdev

Rev

Rev 18351 | Rev 18353 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 18351 Rev 18352
Line 15... Line 15...
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
16
 */
17
 
17
 
18
#include <errno.h>
18
#include <errno.h>
19
#include "flydraw.h"
19
#include "flydraw.h"
20
void myGdImageArc(gdImagePtr, double, double, double, double, double, double, int);
-
 
21
const double DEG=M_PI/180;
20
const double DEG=M_PI/180;
22
 
21
 
23
/* Tikz things */
22
/* Tikz things */
24
 
23
 
25
static char *tikz_color (int the_color)
24
static char *tikz_color (int the_color)
Line 649... Line 648...
649
      fprintf(tikz_file, "(%i,%i)--(%i,%i)",
648
      fprintf(tikz_file, "(%i,%i)--(%i,%i)",
650
       pm->p[i],flip(pm->p[i+1]),pm->p[i+2],flip(pm->p[i+3]));
649
       pm->p[i],flip(pm->p[i+1]),pm->p[i+2],flip(pm->p[i+3]));
651
  }
650
  }
652
  if(tikz_file) fprintf(tikz_file, ";\n");
651
  if(tikz_file) fprintf(tikz_file, ";\n");
653
}
652
}
654
/* for geodesics, return data for obj_hypgeods + a point on the arc
-
 
655
  to be used for filling hyperbolic triangle*/
-
 
656
int hypgeodaux(double *q, double* res)
-
 
657
{
-
 
658
  double r,cx,cy,a1,a2,a3,tmp,
-
 
659
    nx = -q[0]*q[2]*q[2]+(q[0]*q[0]+q[1]*q[1]+1)*q[2]-q[0]*q[3]*q[3]-q[0],
-
 
660
    ny = -q[1]*q[2]*q[2]-q[1]*q[3]*q[3]+(q[0]*q[0]+q[1]*q[1]+1)*q[3]-q[1],
-
 
661
    dy = -2*q[1]*q[2]+2*q[0]*q[3];
-
 
662
  if (dy*dy*1e4 < nx*nx+ny*ny){
-
 
663
    res[5]=(q[0]+q[2])/2;
-
 
664
    res[6]=(q[1]+q[3])/2;
-
 
665
    return 0;}
-
 
666
  cx = ny/dy; cy=-nx/dy;
-
 
667
  a1 = atan2(q[1]-cy, q[0]-cx);
-
 
668
  a2 = atan2(q[3]-cy, q[2]-cx);
-
 
669
  if (fabs(a2-a1)>M_PI){if(a1<a2) a1+=2*M_PI; else a2+=2*M_PI;};
-
 
670
  a3 = (a1+a2)/2;
-
 
671
  if(a1>a2) {tmp=a1; a1=a2; a2=tmp;}
-
 
672
  r = sqrt(cx*cx+cy*cy-1);
-
 
673
  res[0]=cx;
-
 
674
  res[1]=cy;
-
 
675
  res[2]=r;
-
 
676
  res[3]=a1;
-
 
677
  res[4]=a2;
-
 
678
  res[5]=cx+r*cos(a3);
-
 
679
  res[6]=cy+r*sin(a3);
-
 
680
  return 1;
-
 
681
}
-
 
682
/* hyperbolic geodesics from x1,y1 to x2,y2, x3,y3 to x4,y4 in Poincaré disk */
-
 
683
 
653
 
684
void obj_hypgeods(objparm *pm)
-
 
685
{
-
 
686
  int i, *qq=pm->p;
-
 
687
  double rx,ry,res[7];
-
 
688
  for (i = 0; i < pm->pcnt; i+=4)
-
 
689
    if (hypgeodaux(pm->pd+i,res)){
-
 
690
      scale2(res[2],res[2],&rx,&ry);
-
 
691
      scale(res,qq,1);
-
 
692
      myGdImageArc(image,qq[0],qq[1],rx,ry,res[3]/DEG,res[4]/DEG,pm->color[0]);
-
 
693
    }
-
 
694
    else {
-
 
695
      scale(pm->pd+i,qq,2);
-
 
696
      gdImageLine(image,qq[0],qq[1],qq[2],qq[3],pm->color[0]);
-
 
697
    }
-
 
698
}
-
 
699
/* hyperbolique triangle, can be filled */
-
 
700
void obj_hyptriangle(objparm *pm)
-
 
701
{
-
 
702
  double rx,ry,data[8],res[7];
-
 
703
  int i, *qq=pm->p;
-
 
704
  for(i=0; i<8; i++) data[i]=pm->pd[i%6];
-
 
705
  for(i=0; i<3; i++)
-
 
706
    if(hypgeodaux(data+2*i,res)) {
-
 
707
      scale2(res[2],res[2],&rx,&ry);
-
 
708
      scale(res,qq,1);
-
 
709
      myGdImageArc(image,qq[0],qq[1],rx,ry,res[3]/DEG,res[4]/DEG,pm->color[0]);
-
 
710
    }
-
 
711
    else {
-
 
712
      scale(data+2*i,qq,2);
-
 
713
      gdImageLine(image,qq[0],qq[1],qq[2],qq[3],pm->color[0]);
-
 
714
    }
-
 
715
  if(pm->fill){
-
 
716
    data[0]=res[5];
-
 
717
    data[1]=res[6];
-
 
718
    hypgeodaux(data,res);
-
 
719
    scale(res+5,qq,1);
-
 
720
    patchgdImageFill(image,qq[0],qq[1],pm->color[0]);
-
 
721
  }
-
 
722
}
-
 
723
/* complete hyperbolic geodesic through two points */
-
 
724
void obj_hyplines(objparm *pm)
-
 
725
{
-
 
726
  double rx,ry,res[7],*pd = pm->pd;
-
 
727
  int i;
-
 
728
  for (i=0; i < pm->pcnt; i+=4,pd+=4)
-
 
729
    if (hypgeodaux(pd,res)) {
-
 
730
      double alpha=atan(1/res[2]), beta = atan2(res[1],res[0]);
-
 
731
      scale(res,pm->p,1);
-
 
732
      scale2(res[2],res[2],&rx,&ry);
-
 
733
      myGdImageArc(image,pm->p[0],pm->p[1],rx,ry,180+(beta-alpha)/DEG,180+(beta+alpha)/DEG,pm->color[0]);
-
 
734
    }
-
 
735
    else {
-
 
736
      double gamma;
-
 
737
      if (pd[1]*pd[1]+pd[0]*pd[0] > pd[2]*pd[2]+pd[3]*pd[3])
-
 
738
        gamma = atan2(pd[1],pd[0]);
-
 
739
      else
-
 
740
        gamma = atan2(pd[3],pd[2]);
-
 
741
      res[0]=cos(gamma);
-
 
742
      res[1]=sin(gamma);
-
 
743
      res[2]=-cos(gamma);
-
 
744
      res[3]=-sin(gamma);
-
 
745
      scale(res,pm->p,2);
-
 
746
      gdImageLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],pm->color[0]);
-
 
747
    }
-
 
748
}
-
 
749
/* segments */
654
/* segments */
750
void obj_dlines(objparm *pm)
655
void obj_dlines(objparm *pm)
751
{
656
{
752
 int i, n;
657
 int i, n;
753
 n=(pm->pcnt)/2;
658
 n=(pm->pcnt)/2;
Line 829... Line 734...
829
  if(tikz_file){
734
  if(tikz_file){
830
    pm->pd[5]-=pm->pd[4];
735
    pm->pd[5]-=pm->pd[4];
831
    pm->pd[5]-=360*floor(pm->pd[5]/360);
736
    pm->pd[5]-=360*floor(pm->pd[5]/360);
832
    pm->pd[5]+=pm->pd[4];
737
    pm->pd[5]+=pm->pd[4];
833
    fprintf(tikz_file,
738
    fprintf(tikz_file,
834
/*    "\\draw\[%s, domain=%f:%f] plot ({%i+%f*cos(\\x)}, {%i+%f*sin(\\x)});\n",*/
-
 
835
      "\\draw \[%s] (%i,%i) arc (%f:%f:%i and %i);\n",
739
      "\\draw \[%s] (%i,%i) arc (%f:%f:%i and %i);\n",
836
        tikz_options(pm->color[0],pm->fill),
740
        tikz_options(pm->color[0],pm->fill),
837
        (int)rint(pm->p[0]+rx*cos(DEG*pm->pd[4])),
741
        (int)rint(pm->p[0]+rx*cos(DEG*pm->pd[4])),
838
        flip((int)rint(pm->p[1]+ry*sin(DEG*pm->pd[4]))),
742
        flip((int)rint(pm->p[1]+ry*sin(DEG*pm->pd[4]))),
839
        pm->pd[4],pm->pd[5],rx,-ry);
743
        pm->pd[4],pm->pd[5],rx,-ry);
Line 1153... Line 1057...
1153
  {"giant", &gdFontGiant,"1"},
1057
  {"giant", &gdFontGiant,"1"},
1154
  {"huge",  &gdFontGiant,"1"}
1058
  {"huge",  &gdFontGiant,"1"}
1155
};
1059
};
1156
 
1060
 
1157
#define fonttab_no (sizeof(fonttab)/sizeof(fonttab[0]))
1061
#define fonttab_no (sizeof(fonttab)/sizeof(fonttab[0]))
1158
 
1062
 
1159
/* string */
1063
/* string */
1160
void obj_string(objparm *pm)
1064
void obj_string(objparm *pm)
1161
{
1065
{
1162
  char *pp, *pe, *p2;
1066
  char *pp, *pe, *p2;
1163
  int i;
1067
  int i;
Line 1275... Line 1179...
1275
  if(pm->fill) {
1179
  if(pm->fill) {
1276
    gdImageSetTile(image,insimg); tiled=1; tileimg=insimg;
1180
    gdImageSetTile(image,insimg); tiled=1; tileimg=insimg;
1277
  }
1181
  }
1278
  else {
1182
  else {
1279
    gdImageSetBrush(image,insimg);brushed=1; brushimg=insimg;
1183
    gdImageSetBrush(image,insimg);brushed=1; brushimg=insimg;
1280
  }
1184
  }
1281
}
1185
}
1282
 
1186
 
1283
/* kill brush */
1187
/* kill brush */
1284
void obj_killbrush(objparm *pm)
1188
void obj_killbrush(objparm *pm)
1285
{
1189
{
1286
  if(brushimg) gdImageDestroy(brushimg);
1190
  if(brushimg) gdImageDestroy(brushimg);
Line 1316... Line 1220...
1316
  styled=0;
1220
  styled=0;
1317
}
1221
}
1318
 
1222
 
1319
/* set transparent */
1223
/* set transparent */
1320
void obj_transp(objparm *pm)
1224
void obj_transp(objparm *pm)
1321
{
1225
{
1322
  gdImageColorTransparent(image,pm->color[0]);
1226
  gdImageColorTransparent(image,pm->color[0]);
1323
}
1227
}
1324
 
1228
 
1325
/* set interlace */
1229
/* set interlace */
1326
void obj_interlace(objparm *pm)
1230
void obj_interlace(objparm *pm)
Line 1474... Line 1378...
1474
  if (tikz_file) fprintf(tikz_file,";\n\%\%end plot\n");
1378
  if (tikz_file) fprintf(tikz_file,";\n\%\%end plot\n");
1475
  if(vimg_enable) vimg_plotend();
1379
  if(vimg_enable) vimg_plotend();
1476
}
1380
}
1477
 
1381
 
1478
void obj_plot(objparm *pm) { _obj_plot( pm,0) ;}
1382
void obj_plot(objparm *pm) { _obj_plot( pm,0) ;}
1479
void obj_dplot(objparm *pm) { _obj_plot( pm,1) ; }
1383
void obj_dplot(objparm *pm) { _obj_plot( pm,1) ;}
1480
 
1384
 
1481
/* set levelcurve granularity */
1385
/* set levelcurve granularity */
1482
void obj_levelstep(objparm *pm)
1386
void obj_levelstep(objparm *pm)
1483
{
1387
{
1484
  int dd;
1388
  int dd;
Line 1632... Line 1536...
1632
 
1536
 
1633
/***** Les modifs de Jean-Christophe Leger Fev 2006 *****/
1537
/***** Les modifs de Jean-Christophe Leger Fev 2006 *****/
1634
 
1538
 
1635
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES, une liste de 4 nombres reels pour la matrice */
1539
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES, une liste de 4 nombres reels pour la matrice */
1636
void obj_setmatrix(objparm *pm)
1540
void obj_setmatrix(objparm *pm)
1637
{
1541
{
1638
  int nummatrix = (int) (pm->pd[0]);
1542
  int nummatrix = (int) (pm->pd[0]);
1639
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1543
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1640
    fly_error("bad_matrix_number");
1544
    fly_error("bad_matrix_number");
1641
    return;
1545
    return;
1642
  }
1546
  }
1643
  matrices_pavage[nummatrix][0] = pm->pd[1];
1547
  matrices_pavage[nummatrix][0] = pm->pd[1];
1644
  matrices_pavage[nummatrix][1] = pm->pd[2];
1548
  matrices_pavage[nummatrix][1] = pm->pd[2];
1645
  matrices_pavage[nummatrix][2] = pm->pd[3];
1549
  matrices_pavage[nummatrix][2] = pm->pd[3];
1646
  matrices_pavage[nummatrix][3] = pm->pd[4];
1550
  matrices_pavage[nummatrix][3] = pm->pd[4];
1647
}
1551
}
1648
 
1552
 
1649
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */
1553
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */
1650
void obj_resetmatrix(objparm *pm)
1554
void obj_resetmatrix(objparm *pm)
1651
{
1555
{
1652
  int nummatrix = (int) (pm->pd[0]);
1556
  int nummatrix = (int) (pm->pd[0]);
1653
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1557
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
Line 1969... Line 1873...
1969
    substit(tbuf2);
1873
    substit(tbuf2);
1970
  }
1874
  }
1971
  if(parse_parms(tbuf2,&pm,objtab+i)!=0) fly_error("bad_parms");
1875
  if(parse_parms(tbuf2,&pm,objtab+i)!=0) fly_error("bad_parms");
1972
  else objtab[i].routine(&pm);
1876
  else objtab[i].routine(&pm);
1973
  return 0;
1877
  return 0;
-
 
1878
}
-
 
1879
 
-
 
1880
/* for hyperbolic geodesics, return data for obj_hypgeods + a point on the arc
-
 
1881
  to be used for filling hyperbolic triangle*/
-
 
1882
int hypgeodaux(double *q, double* res)
-
 
1883
{
-
 
1884
  double r,cx,cy,a1,a2,a3,tmp,
-
 
1885
    nx = -q[0]*q[2]*q[2]+(q[0]*q[0]+q[1]*q[1]+1)*q[2]-q[0]*q[3]*q[3]-q[0],
-
 
1886
    ny = -q[1]*q[2]*q[2]-q[1]*q[3]*q[3]+(q[0]*q[0]+q[1]*q[1]+1)*q[3]-q[1],
-
 
1887
    dy = -2*q[1]*q[2]+2*q[0]*q[3];
-
 
1888
  if (dy*dy*1e4 < nx*nx+ny*ny){
-
 
1889
    res[5]=(q[0]+q[2])/2;
-
 
1890
    res[6]=(q[1]+q[3])/2;
-
 
1891
    return 0;}
-
 
1892
  cx = ny/dy; cy=-nx/dy;
-
 
1893
  a1 = atan2(q[1]-cy, q[0]-cx);
-
 
1894
  a2 = atan2(q[3]-cy, q[2]-cx);
-
 
1895
  if (fabs(a2-a1)>M_PI){if(a1<a2) a1+=2*M_PI; else a2+=2*M_PI;};
-
 
1896
  a3 = (a1+a2)/2;
-
 
1897
  if(a1>a2) {tmp=a1; a1=a2; a2=tmp;}
-
 
1898
  r = sqrt(cx*cx+cy*cy-1);
-
 
1899
  res[0]=cx;
-
 
1900
  res[1]=cy;
-
 
1901
  res[2]=r;
-
 
1902
  res[3]=a1;
-
 
1903
  res[4]=a2;
-
 
1904
  res[5]=cx+r*cos(a3);
-
 
1905
  res[6]=cy+r*sin(a3);
-
 
1906
  return 1;
-
 
1907
}
-
 
1908
/* hyperbolic geodesics from x1,y1 to x2,y2, x3,y3 to x4,y4 in Poincaré disk */
-
 
1909
void obj_hypgeods(objparm *pm)
-
 
1910
{
-
 
1911
  int i, *qq=pm->p;
-
 
1912
  double rx,ry,res[7];
-
 
1913
  if (tikz_file) fprintf(tikz_file, "\\draw[%s]",tikz_options(pm->color[0],pm->fill));
-
 
1914
  for (i = 0; i < pm->pcnt; i+=4)
-
 
1915
    if (hypgeodaux(pm->pd+i,res)){
-
 
1916
      scale2(res[2],res[2],&rx,&ry);
-
 
1917
      scale(res,qq,1);
-
 
1918
      myGdImageArc(image,qq[0],qq[1],rx,ry,res[3]/DEG,res[4]/DEG,pm->color[0]);
-
 
1919
      if(tikz_file) fprintf(tikz_file,"(%i,%i)arc(%f:%f:%i and %i)",
-
 
1920
        qq[0],flip(qq[1]),res[3]/DEG,res[4]/DEG,(int)rint(rx),-(int)rint(ry));
-
 
1921
    }
-
 
1922
    else {
-
 
1923
      scale(pm->pd+i,qq,2);
-
 
1924
      gdImageLine(image,qq[0],qq[1],qq[2],qq[3],pm->color[0]);
-
 
1925
      if(tikz_file) fprintf(tikz_file,"(%i,%i)--(%i,%i)",
-
 
1926
          qq[0],flip(qq[1]),qq[2],flip(qq[3]));
-
 
1927
    }
-
 
1928
  if(tikz_file) fprintf(tikz_file,";\n");
-
 
1929
}
-
 
1930
 
-
 
1931
/* hyperbolic triangle, can be filled */
-
 
1932
void obj_hyptriangle(objparm *pm)
-
 
1933
{
-
 
1934
  double rx,ry,data[8],res[7];
-
 
1935
  int i, *qq=pm->p;
-
 
1936
  for(i=0; i<8; i++) data[i]=pm->pd[i%6];
-
 
1937
  if (tikz_file) fprintf(tikz_file, "\\draw[%s]",tikz_options(pm->color[0],pm->fill));
-
 
1938
  for(i=0; i<3; i++)
-
 
1939
    if(hypgeodaux(data+2*i,res)){
-
 
1940
      scale2(res[2],res[2],&rx,&ry);
-
 
1941
      scale(res,qq,1);
-
 
1942
      myGdImageArc(image,qq[0],qq[1],rx,ry,res[3]/DEG,res[4]/DEG,pm->color[0]);
-
 
1943
      if(tikz_file)
-
 
1944
        fprintf(tikz_file, "(%i,%i) arc (%f:%f:%i and %i)",
-
 
1945
          (int)rint(qq[0]+rx*cos(res[3])),
-
 
1946
          flip((int)rint(qq[1]+ry*sin(res[3]))),
-
 
1947
          res[3]/DEG,res[4]/DEG,(int)rint(rx),-(int)rint(ry));
-
 
1948
    }
-
 
1949
    else {
-
 
1950
      scale(data+2*i,qq,2);
-
 
1951
      gdImageLine(image,qq[0],qq[1],qq[2],qq[3],pm->color[0]);
-
 
1952
      if(tikz_file) fprintf(tikz_file,"(%i,%i)--(%i,%i)",
-
 
1953
            qq[0],flip(qq[1]),qq[2],flip(qq[3]));
-
 
1954
    }
-
 
1955
    if(tikz_file) fprintf(tikz_file,";\n");
-
 
1956
    if(pm->fill){
-
 
1957
      data[0]=res[5];
-
 
1958
      data[1]=res[6];
-
 
1959
      hypgeodaux(data,res);
-
 
1960
      scale(res+5,qq,1);
-
 
1961
      //patchgdImageFill(image,qq[0],qq[1],pm->color[0]);
-
 
1962
      patchgdImageFillToBorder(image,qq[0],qq[1],pm->color[0],pm->color[0]);
-
 
1963
      if(tikz_file) tikz_fill(qq[0],qq[1],1,1,0,pm->color[0],grid);
-
 
1964
    }
-
 
1965
}
-
 
1966
 
-
 
1967
/* complete hyperbolic geodesic through the two first points, then the following two points, etc */
-
 
1968
 
-
 
1969
void obj_hyplines(objparm *pm)
-
 
1970
{
-
 
1971
  double rx,ry,res[7],*pd = pm->pd;
-
 
1972
  int i;
-
 
1973
  if (tikz_file) fprintf(tikz_file, "\\draw[%s]",tikz_options(pm->color[0],0));
-
 
1974
  for (i=0; i < pm->pcnt; i+=4,pd+=4)
-
 
1975
    if (hypgeodaux(pd,res)) {
-
 
1976
      double alpha=atan(1/res[2]), beta = atan2(res[1],res[0]);
-
 
1977
      scale(res,pm->p,1);
-
 
1978
      scale2(res[2],res[2],&rx,&ry);
-
 
1979
      myGdImageArc(image,pm->p[0],pm->p[1],rx,ry,180+(beta-alpha)/DEG,180+(beta+alpha)/DEG,pm->color[0]);
-
 
1980
      if (tikz_file) fprintf(tikz_file, "(%i,%i) arc (%f:%f:%i and %i);\n",
-
 
1981
        (int)rint(pm->p[0]-rx*cos(beta-alpha)), flip((int)rint(pm->p[1]-ry*sin(beta-alpha))),
-
 
1982
          (beta-alpha)/DEG,(beta+alpha)/DEG, (int)rint(rx),-(int)rint(ry));
-
 
1983
    }
-
 
1984
    else {
-
 
1985
      double gamma;
-
 
1986
      if (pd[1]*pd[1]+pd[0]*pd[0] > pd[2]*pd[2]+pd[3]*pd[3])
-
 
1987
        gamma = atan2(pd[1],pd[0]);
-
 
1988
      else
-
 
1989
        gamma = atan2(pd[3],pd[2]);
-
 
1990
        res[0]=cos(gamma);
-
 
1991
        res[1]=sin(gamma);
-
 
1992
        res[2]=-cos(gamma);
-
 
1993
        res[3]=-sin(gamma);
-
 
1994
        scale(res,pm->p,2);
-
 
1995
        gdImageLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],pm->color[0]);
-
 
1996
        if(tikz_file) fprintf(tikz_file, "(%i,%i)--(%i,%i)",
-
 
1997
          pm->p[0],flip(pm->p[1]),pm->p[2],flip(pm->p[3]));
-
 
1998
    }
-
 
1999
    if (tikz_file) fprintf(tikz_file, ";\n");
1974
}
2000
}