2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2002-2004 - INRIA - Djalel Abdemouche
4 * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
5 * Copyright (C) 2005 - INRIA - Jean-Baptiste Silvy
6 * Copyright (C) 2010-2011 - DIGITEO - Manuel Juliachs
8 * This file must be used under the terms of the CeCILL.
9 * This source file is licensed as described in the file COPYING, which
10 * you should have received as part of this distribution. The terms
11 * are also available at
12 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
16 /*------------------------------------------------------------------------
18 * Graphic subroutines interface
19 --------------------------------------------------------------------------*/
24 #include "SetProperty.h"
25 #include "GetProperty.h"
26 #include "DrawObjects.h"
27 #include "BuildObjects.h"
28 #include "BasicAlgos.h"
29 #include "math_graphics.h"
34 #include "localization.h"
35 #include "MALLOC.h" /* MALLOC */
39 #include "HandleManagement.h"
40 #include "stack-def.h" /* bsiz */
42 #include "setGraphicObjectProperty.h"
43 #include "getGraphicObjectProperty.h"
44 #include "createGraphicObject.h"
45 #include "graphicObjectProperties.h"
46 #include "CurrentFigure.h"
47 #include "CurrentSubwin.h"
48 #include "CurrentObject.h"
50 #include "deleteGraphicObject.h"
52 /** Update data bounds according to the given data bound passed in rect */
53 static void updateXYDataBounds(int iSubwinUID, double rect[6]);
54 static void updateXYZDataBounds(int iSubwinUID, double rect[6]);
56 /*------------------------------------------------
58 * On recupere la figure courante, puis on recupere la sous fenetre qui y est selectionnee
59 * puis on contruit le rectangle, qu on le place comme objet courant
60 * ensuite il reste qu'appeler la fonction du dessin de l'objet
61 *-----------------------------------------------*/
63 void Objrect (double* x ,
77 iSubwinUID = getCurrentSubWin();
79 /* check if the auto_clear property is on and then erase everything */
83 rect[1] = *x + *width;
84 rect[2] = *y - *height;
87 updateXYDataBounds(iSubwinUID, rect);
89 /*newObjUID = ConstructRectangle(iSubwinUID , *x, *y, *height, *width,
90 foreground, background, isfilled, isline);*/
92 iNewObjUID = createRect(iSubwinUID, *x, *y, *height, *width,
93 foreground == NULL ? -1 : *foreground,
94 background == NULL ? -1 : *background,
95 (int)isfilled, (int)isline);
99 /* an error occurred */
104 setCurrentObject(iNewObjUID);
105 *hdl = getHandle(iNewObjUID);
109 /*----------------------------------------------
111 *-----------------------------------------------*/
113 void Objarc(double* angle1 ,
128 const double two_pi = 2 * M_PI;
130 iSubwinUID = getCurrentSubWin();
133 if (abs(*angle2) >= two_pi)
136 rect[1] = *x + *width;
137 rect[2] = *y - *height;
147 a -= (floor(a / two_pi)) * two_pi;
163 // is there a 2k\pi in [a,b] ?
164 if (ceil(a1 / 2) <= floor(b1 / 2))
166 rect[1] = *x + *width;
170 rect[1] = *x + 0.5 * *width * (1 + Max(cos(a), cos(b)));
173 // is there a (2k+1)\pi in [a,b] ?
174 if (ceil((a1 - 1) / 2) <= floor((b1 - 1) / 2))
180 rect[0] = *x + 0.5 * *width * (1 + Min(cos(a), cos(b)));
183 // is there a (2k+1/2)\pi in [a,b] ?
184 if (ceil((a1 - 0.5) / 2) <= floor((b1 - 0.5) / 2))
190 rect[3] = *y + 0.5 * *height * (-1 + Max(sin(a), sin(b)));
193 // is there a (2k+3/2)\pi in [a,b] ?
194 if (ceil((a1 - 1.5) / 2) <= floor((b1 - 1.5) / 2))
196 rect[2] = *y - *height;
200 rect[2] = *y + 0.5 * *height * (-1 + Min(sin(a), sin(b)));
204 updateXYDataBounds(iSubwinUID, rect);
206 iObjUID = createArc(iSubwinUID, *x, *y,
207 *height, *width, *angle1, *angle2, foreground, background, isfilled, isline);
209 setCurrentObject(iObjUID);
210 *hdl = getHandle(iObjUID);
213 /*------------------------------------------------
215 *-----------------------------------------------*/
217 void Objpoly (double * x ,
228 iSubwinUID = getCurrentSubWin();
234 MiniMaxi(x, n, rect, rect + 1);
235 MiniMaxi(y, n, rect + 2, rect + 3);
237 updateXYDataBounds(iSubwinUID, rect);
242 int absmark = abs(mark);
243 iObjUID = ConstructPolyline(iSubwinUID, x, y, PD0, closed, n, 1,
244 NULL, NULL, &absmark, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
248 iObjUID = ConstructPolyline(iSubwinUID, x, y, PD0, closed, n, 1,
249 &mark, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE);
254 Scierror(999, _("%s: No more memory.\n"), "Objpoly");
258 setCurrentObject(iObjUID);
259 *hdl = getHandle(iObjUID);
263 /*------------------------------------------------
265 *-----------------------------------------------*/
267 void Objfpoly (double * x ,
278 int contourcolor = 0;
279 int *piContourColor = &contourcolor;
281 int closed = 1; /* we close the polyline by default */
284 iSubwinUID = getOrCreateDefaultSubwin();
290 MiniMaxi(x, n, rect, rect + 1);
291 MiniMaxi(y, n, rect + 2, rect + 3);
293 updateXYDataBounds(iSubwinUID, rect);
298 /* interpolated shading is "on" */
299 iObjUID = ConstructPolyline(iSubwinUID, x, y, PD0, closed, n,
300 1, NULL, style, NULL, NULL, NULL, FALSE, TRUE, FALSE, TRUE);
305 /* flat mode is "on" */
308 fillcolor = abs(*style);
309 iObjUID = ConstructPolyline(iSubwinUID, x, y, PD0, closed, n,
310 1, NULL, &fillcolor, NULL, NULL, NULL, FALSE, TRUE, FALSE, FALSE);
312 else if (*style == 0)
314 getGraphicObjectProperty(iSubwinUID, __GO_LINE_COLOR__, jni_int, (void**)&piContourColor);
315 iObjUID = ConstructPolyline(iSubwinUID, x, y, PD0, closed, n,
316 1, &contourcolor, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE);
322 getGraphicObjectProperty(iSubwinUID, __GO_LINE_COLOR__, jni_int, (void**)&piContourColor);
323 iObjUID = ConstructPolyline(iSubwinUID, x, y, PD0, closed, n,
324 1, &contourcolor, &fillcolor, NULL, NULL, NULL, TRUE, TRUE, FALSE, FALSE);
331 Scierror(999, _("%s: No more memory.\n"), "Objfpoly");
335 setCurrentObject(iObjUID);
336 *hdl = getHandle(iObjUID);
340 /*-----------------------------------------------------------
342 *-----------------------------------------------------------*/
343 void Objsegs (int * style,
353 int type = 0, colored = 0;
354 double *fx = NULL, *fy = NULL; // No fx or fy
355 int typeofchamp = -1; /* no champ here, only segs ; this info is useless */
359 iSubwinUID = getCurrentSubWin();
363 MiniMaxi(x, n1, rect, rect + 1);
364 MiniMaxi(y, n1, rect + 2, rect + 3);
368 MiniMaxi(z, n1, rect + 4, rect + 5);
369 updateXYZDataBounds(iSubwinUID, rect);
373 updateXYDataBounds(iSubwinUID, rect);
377 iObjUID = createSegs(iSubwinUID, x, n1, y, n1, z, (z == NULL ? 0 : n1), style, flag == 0 ? 1 : n1, arsize);
381 Scierror(999, _("%s: No more memory.\n"), "Objsegs");
385 setCurrentObject(iObjUID);
387 /*-----------------------------------------------------------
389 *-----------------------------------------------------------*/
391 /* box is an OUTPUT re-used inside matdes.c in scixstring */
392 void Objstring(char ** fname ,
408 sciTextAlignment alignment)
413 iSubwinUID = getCurrentSubWin();
417 iObjUID = ConstructText(iSubwinUID ,
435 Scierror(999, _("%s: No more memory.\n"), "Objstring");
439 *hdl = getHandle(iObjUID);
441 setGraphicObjectProperty(iObjUID, __GO_FONT_ANGLE__, angle, jni_double, 1);
445 /*------------------------------------------------
447 *-----------------------------------------------*/
449 void Objplot2d (int ptype ,
462 plot2dn(ptype, logflags, x, y, n1, n2, style, strflag, legend, brect, aaint, flagNax, 4L, bsiz);
465 /*------------------------------------------------
467 *-----------------------------------------------*/
468 void Objgrayplot (double x[] ,
479 C2F(xgray)(x, y, z, n1, n2, strflag, brect, aaint, flagNax, logflag, bsiz);
482 /*------------------------------------------------
484 *-----------------------------------------------*/
485 void Objmatplot (double z[] ,
493 C2F(xgray1)(z, n1, n2, strflag, brect, aaint, flagNax, bsiz);
496 void ObjmatplotImage (void * z ,
507 C2F(xgray1)((double *)z, n1, n2, strflag, brect, aaint, flagNax, bsiz);
511 C2F(implot)((unsigned char *)z, n1, n2, strflag, brect, aaint, flagNax, bsiz, plottype);
515 /*------------------------------------------------
517 *-----------------------------------------------*/
518 void Objmatplot1 (double z[],
521 double xrect[], int plottype)
525 C2F(xgray2)(z, n1, n2, xrect);
529 C2F(implot1)((unsigned char *)z, n1, n2, xrect, plottype);
533 /*------------------------------------------------
535 *-----------------------------------------------*/
536 void Objplot3d (char * fname ,
550 int * m1 , /*Adding F.Leray 12.03.04 and 19.03.04*/
558 /* F.Leray 25.04.05 : warning here legends means "X@Y@Z": it is labels writings!! */
559 /* legends has not the same meaning than inside plot2dn (there, it is really the legends of the plotted curves)*/
561 sciTypeOf3D typeof3d;
572 int iNewSurfaceUID = 0;
575 /* =================================================
576 * Force SubWindow properties according to arguments
577 * ================================================= */
579 iSubwinUID = getCurrentSubWin();
581 initSubWinTo3d(iSubwinUID, legend, iflag, *alpha, *theta, ebox, x, *m1 **n1, y, *m2 **n2, z, *m3 **n3);
583 /* =================================================
584 * Analyze arguments to find entity type
585 * ================================================= */
591 if (strcmp(fname, "plot3d1") == 0)
593 typeof3d = SCI_FAC3D;
598 typeof3d = SCI_FAC3D;
602 else if (*izcol == 2)
604 typeof3d = SCI_FAC3D;
609 typeof3d = SCI_FAC3D;
613 else if (*isfac == 0)
615 if (strcmp(fname, "plot3d1") == 0)
617 typeof3d = SCI_PLOT3D;
622 typeof3d = SCI_PLOT3D;
628 typeof3d = SCI_PARAM3D1;
632 /* =================================================
633 * Construct the Entities
634 * ================================================= */
636 /*Distinction here between SCI_PARAM3D1 and others*/
637 if (typeof3d != SCI_PARAM3D1)
643 /* x is considered as a matrix */
646 else if (*m1 == 1) /* x is a row vector */
650 else if (*n1 == 1) /* x is a column vector */
654 else /* x is a matrix */
661 int monotony = checkMonotony(x, dimvectx);
664 Scierror(999, _("%s: x vector is not monotonous.\n"), "Objplot3d");
672 /* y is considered as a matrix */
675 else if (*m2 == 1) /* y is a row vector */
679 else if (*n2 == 1) /* y is a column vector */
683 else /* y is a matrix */
690 /* test the monotony on y*/
691 int monotony = checkMonotony(y, dimvecty);
694 Scierror(999, _("%s: y vector is not monotonous.\n"), "Objplot3d");
699 iNewSurfaceUID = ConstructSurface(iSubwinUID, typeof3d,
700 x, y, z, zcol, *izcol, *m, *n, iflag, ebox, flagcolor,
701 isfac, m1, n1, m2, n2, m3, n3, m3n, n3n);
703 if (iNewSurfaceUID == 0)
705 Scierror(999, _("%s: No more memory.\n"), "Objplot3d");
709 setCurrentObject(iNewSurfaceUID);
711 /* Force clipping, 1: CLIPGRF */
713 setGraphicObjectProperty(iNewSurfaceUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
717 int iNewPolylineUID = 0;
718 int iCurrentSubwinUID = 0;
720 if ((pObj = (int*)MALLOC (*n * sizeof (int))) == NULL)
722 Scierror(999, "%s: No more memory.\n", fname);
726 iCurrentSubwinUID = getCurrentSubWin();
728 for (i = 0; i < *n; ++i)
730 if ((*n > 0) && (zcol != (double *)NULL))
732 if ((int) zcol[i] > 0)
734 int intzcol = (int) zcol[i];
735 iNewPolylineUID = ConstructPolyline
737 &(x[*m * i]), &(y[*m * i]), &(z[*m * i]), 0, *m, 1,
738 &intzcol, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE);
742 int intzcol = (int) - zcol[i];
743 iNewPolylineUID = ConstructPolyline
745 &(x[*m * i]), &(y[*m * i]), &(z[*m * i]), 0, *m, 1,
746 NULL, NULL, &intzcol, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
751 /* default case, nothing is given */
753 int *piCurColor = &curcolor;
755 getGraphicObjectProperty(iCurrentSubwinUID, __GO_LINE_COLOR__, jni_int, (void**)&piCurColor);
757 iNewPolylineUID = ConstructPolyline(iCurrentSubwinUID,
758 &(x[*m * i]), &(y[*m * i]), &(z[*m * i]), 0, *m, 1,
759 &curcolor, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE);
762 if (iNewPolylineUID == 0)
764 Scierror(999, _("%s: No more memory.\n"), fname);
769 setCurrentObject(iNewPolylineUID);
770 setGraphicObjectRelationship(iCurrentSubwinUID, iNewPolylineUID);
772 /* Force clipping, 1: CLIPGRF */
774 setGraphicObjectProperty(iNewPolylineUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
776 pObj[i] = iNewPolylineUID;
779 /** construct Compound and make it current object**/
782 int o = createCompound (iCurrentSubwinUID, pObj, *n);
788 /* =================================================
790 * ================================================= */
792 // subwin has been modified
795 setGraphicObjectProperty(iSubwinUID, __GO_FIRST_PLOT__, &firstPlot, jni_bool, 1);
797 /*-----------------------------------------------------------
799 *-----------------------------------------------------------*/
801 void Objdrawaxis (char dir ,
819 int ticksDirection = 0;
822 iSubwinUID = getCurrentSubWin();
857 iObjUID = createAxis(iSubwinUID, ticksDirection, ticksStyle, x, *nx, y, *ny, subint, format, font, textcol, ticscol, seg);
861 Scierror(999, _("%s: No more memory.\n"), "Objdrawaxis");
868 StringMatrix *tics_labels;
870 tics_labels = computeDefaultTicsLabels(iObjUID);
872 if (tics_labels == NULL)
874 deleteGraphicObject(iObjUID);
878 matData = getStrMatData(tics_labels);
881 * The labels vector size must be computed using the matrix's dimensions.
882 * To be modified when the labels computation is moved to the Model.
884 setGraphicObjectProperty(iObjUID, __GO_TICKS_LABELS__, matData, jni_string_vector, tics_labels->nbCol * tics_labels->nbRow);
886 deleteMatrix(tics_labels);
892 * Labels are set using the str argument; the previous code tested whether each element of the
893 * str array was null and set the corresponding Axis' element to NULL, though there was no
894 * apparent reason to do so. This is still checked, but now aborts building the Axis.
897 if (nb_tics_labels == -1)
899 Scierror(999, _("Impossible case when building axis\n"));
900 deleteGraphicObject(iObjUID);
904 for (i = 0; i < nb_tics_labels; i++)
908 deleteGraphicObject(iObjUID);
913 setGraphicObjectProperty(iObjUID, __GO_TICKS_LABELS__, val, jni_string_vector, nb_tics_labels);
916 setCurrentObject(iObjUID);
919 /*-----------------------------------------------------------
921 *-----------------------------------------------------------*/
923 void Objnumb(char * fname ,
924 unsigned long fname_len,
932 /*** faire une macro scilab sur xstring ****/
937 /*------------------------------------------------
939 *-----------------------------------------------*/
940 void Objfec (double x[] ,
956 C2F(fec)(x, y, noeud, fun, n, m, strflag, legend, brect, aaint,
957 Zminmax, Colminmax, ColOut, WithMesh, flagNax, 4L, bsiz);
959 /*------------------------------------------------------------------------*/
960 static void updateXYDataBounds(int iSubwinUID, double rect[6])
963 int * piFirstPlot = &firstPlot;
965 getGraphicObjectProperty(iSubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piFirstPlot);
973 double * dataBounds = NULL;
974 getGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
976 rect[0] = Min(rect[0], dataBounds[0]);
977 rect[1] = Max(rect[1], dataBounds[1]);
978 rect[2] = Min(rect[2], dataBounds[2]);
979 rect[3] = Max(rect[3], dataBounds[3]);
980 rect[4] = dataBounds[4];
981 rect[5] = dataBounds[5];
984 setGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, rect, jni_double_vector, 6);
986 /*------------------------------------------------------------------------*/
987 static void updateXYZDataBounds(int iSubwinUID, double rect[6])
990 int * piFirstPlot = &firstPlot;
992 getGraphicObjectProperty(iSubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piFirstPlot);
995 double * dataBounds = NULL;
996 getGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
998 rect[0] = Min(rect[0], dataBounds[0]);
999 rect[1] = Max(rect[1], dataBounds[1]);
1000 rect[2] = Min(rect[2], dataBounds[2]);
1001 rect[3] = Max(rect[3], dataBounds[3]);
1002 rect[4] = Min(rect[4], dataBounds[4]);
1003 rect[5] = Max(rect[5], dataBounds[5]);
1006 setGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, rect, jni_double_vector, 6);
1008 /*------------------------------------------------------------------------*/