The R Project SVN R

Rev

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

Rev 24735 Rev 27215
Line 867... Line 867...
867
    return mainlist;
867
    return mainlist;
868
}
868
}
869
 
869
 
870
SEXP GEdrawContourLines();
870
SEXP GEdrawContourLines();
871
 
871
 
-
 
872
SEXP do_contourLines(SEXP call, SEXP op, SEXP args, SEXP env)
-
 
873
{
-
 
874
    SEXP oargs, c, x, y, z;
-
 
875
    int nx, ny, nc;
-
 
876
    GEDevDesc *dd = GEcurrentDevice();
-
 
877
 
-
 
878
    oargs = args;
-
 
879
 
-
 
880
    x = CAR(args);
-
 
881
    internalTypeCheck(call, x, REALSXP);
-
 
882
    nx = LENGTH(x);
-
 
883
    args = CDR(args);
-
 
884
 
-
 
885
    y = CAR(args);
-
 
886
    internalTypeCheck(call, y, REALSXP);
-
 
887
    ny = LENGTH(y);
-
 
888
    args = CDR(args);
-
 
889
 
-
 
890
    z = CAR(args);
-
 
891
    internalTypeCheck(call, z, REALSXP);
-
 
892
    args = CDR(args);
-
 
893
 
-
 
894
    /* levels */
-
 
895
    c = CAR(args);
-
 
896
    internalTypeCheck(call, c, REALSXP);
-
 
897
    nc = LENGTH(c);
-
 
898
    args = CDR(args);
-
 
899
    
-
 
900
    return GEcontourLines(REAL(x), nx, REAL(y), ny, REAL(z), REAL(c), nc, dd);
-
 
901
}
-
 
902
 
-
 
903
/*
-
 
904
 * The *base graphics* function contour() and the *general base* 
-
 
905
 * function contourLines() use the same code to generate contour lines 
-
 
906
 * (i.e., the function contourLines())
-
 
907
 *
-
 
908
 * I had a look at extracting the code that draws the labels 
-
 
909
 * into a *general base* function
-
 
910
 * (e.g., into some sort of labelLines() function), 
-
 
911
 * but the code is too base-graphics-specific (e.g., one of the 
-
 
912
 * labelling methods seeks the location closest to the edge of the
-
 
913
 * plotting region) so I've left it alone for now. 
-
 
914
 * 
-
 
915
 * This does mean that the contourLines() function is part of the
-
 
916
 * graphics engine, but the contour() function is part of the 
-
 
917
 * base graphics system.
-
 
918
 */
-
 
919
 
872
static void contour(SEXP x, int nx, SEXP y, int ny, SEXP z, 
920
static void contour(SEXP x, int nx, SEXP y, int ny, SEXP z, 
873
		    double zc,
921
		    double zc,
874
		    SEXP labels, int cnum,
922
		    SEXP labels, int cnum,
875
		    Rboolean drawLabels, int method,
923
		    Rboolean drawLabels, int method,
876
		    Rboolean vectorFonts, int typeface, int fontindex,
924
		    Rboolean vectorFonts, int typeface, int fontindex,
Line 878... Line 926...
878
{
926
{
879
/* draw a contour for one given contour level `zc' */
927
/* draw a contour for one given contour level `zc' */
880
 
928
 
881
    char *vmax;
929
    char *vmax;
882
 
930
 
883
    double f, xl, xh, yl, yh, zll, zhl, zlh, zhh, xx[4], yy[4];
-
 
884
    double xend, yend;
931
    double xend, yend;
885
    int i, ii, j, jj, k, l, m, nacode, ns, ns2, dir;
932
    int i, ii, j, jj, ns, ns2, dir;
886
    SEGP seglist, seg, s, start, end;
933
    SEGP seglist, seg, s, start, end;
887
    double *xxx, *yyy;
934
    double *xxx, *yyy;
888
 
935
 
889
    double variance, dX, dY, deltaX, deltaY;
936
    double variance, dX, dY, deltaX, deltaY;
890
    double dXC, dYC, deltaXC, deltaYC;
937
    double dXC, dYC, deltaXC, deltaYC;
Line 908... Line 955...
908
    Rboolean ddl;/* Don't draw label -- currently unused, i.e. always FALSE*/
955
    Rboolean ddl;/* Don't draw label -- currently unused, i.e. always FALSE*/
909
 
956
 
910
#ifdef DEBUG_contour
957
#ifdef DEBUG_contour
911
    Rprintf("contour(lev = %g):\n", zc);
958
    Rprintf("contour(lev = %g):\n", zc);
912
#endif
959
#endif
913
    for (i = 0; i < nx - 1; i++) {
-
 
914
	xl = REAL(x)[i];
-
 
915
	xh = REAL(x)[i + 1];
-
 
916
	for (j = 0; j < ny - 1; j++) {
-
 
917
	    yl = REAL(y)[j];
-
 
918
	    yh = REAL(y)[j + 1];
-
 
919
	    k = i + j * nx;
-
 
920
	    zll = REAL(z)[k];
-
 
921
	    zhl = REAL(z)[k + 1];
-
 
922
	    zlh = REAL(z)[k + nx];
-
 
923
	    zhh = REAL(z)[k + nx + 1];
-
 
924
 
-
 
925
	    /* If the value at a corner is exactly equal to a contour level, 
-
 
926
	     * change that value by a tiny amount */
-
 
927
 
-
 
928
	    if (zll == zc) zll += atom;
-
 
929
	    if (zhl == zc) zhl += atom;
-
 
930
	    if (zlh == zc) zlh += atom;
-
 
931
	    if (zhh == zc) zhh += atom;
-
 
932
#ifdef DEBUG_contour
-
 
933
	    /* Haven't seen this happening (MM): */
-
 
934
	    if (zll == zc) REprintf(" [%d,%d] ll: %g\n",i,j, zll);
-
 
935
	    if (zhl == zc) REprintf(" [%d,%d] hl: %g\n",i,j, zhl);
-
 
936
	    if (zlh == zc) REprintf(" [%d,%d] lh: %g\n",i,j, zlh);
-
 
937
	    if (zhh == zc) REprintf(" [%d,%d] hh: %g\n",i,j, zhh);
-
 
938
#endif
-
 
939
	    /* Check for intersections with sides */
-
 
940
 
960
 
941
	    nacode = 0;
-
 
942
	    if (R_FINITE(zll)) nacode += 1;
-
 
943
	    if (R_FINITE(zhl)) nacode += 2;
-
 
944
	    if (R_FINITE(zlh)) nacode += 4;
-
 
945
	    if (R_FINITE(zhh)) nacode += 8;
-
 
946
 
-
 
947
	    k = 0;
-
 
948
	    switch (nacode) {
-
 
949
	    case 15:
-
 
950
		if (ctr_intersect(zll, zhl, zc, &f)) {
-
 
951
		    xx[k] = xl + f * (xh - xl);
-
 
952
		    yy[k] = yl; k++;
-
 
953
		}
-
 
954
		if (ctr_intersect(zll, zlh, zc, &f)) {
-
 
955
		    yy[k] = yl + f * (yh - yl);
-
 
956
		    xx[k] = xl; k++;
-
 
957
		}
-
 
958
		if (ctr_intersect(zhl, zhh, zc, &f)) {
-
 
959
		    yy[k] = yl + f * (yh - yl);
-
 
960
		    xx[k] = xh; k++;
-
 
961
		}
-
 
962
		if (ctr_intersect(zlh, zhh, zc, &f)) {
-
 
963
		    xx[k] = xl + f * (xh - xl);
-
 
964
		    yy[k] = yh; k++;
-
 
965
		}
-
 
966
		break;
-
 
967
	    case 14:
-
 
968
		if (ctr_intersect(zhl, zhh, zc, &f)) {
-
 
969
		    yy[k] = yl + f * (yh - yl);
-
 
970
		    xx[k] = xh; k++;
-
 
971
		}
-
 
972
		if (ctr_intersect(zlh, zhh, zc, &f)) {
-
 
973
		    xx[k] = xl + f * (xh - xl);
-
 
974
		    yy[k] = yh; k++;
-
 
975
		}
-
 
976
		if (ctr_intersect(zlh, zhl, zc, &f)) {
-
 
977
		    xx[k] = xl + f * (xh - xl);
-
 
978
		    yy[k] = yh + f * (yl - yh);
-
 
979
		    k++;
-
 
980
		}
-
 
981
		break;
-
 
982
	    case 13:
-
 
983
		if (ctr_intersect(zll, zlh, zc, &f)) {
-
 
984
		    yy[k] = yl + f * (yh - yl);
-
 
985
		    xx[k] = xl; k++;
-
 
986
		}
-
 
987
		if (ctr_intersect(zlh, zhh, zc, &f)) {
-
 
988
		    xx[k] = xl + f * (xh - xl);
-
 
989
		    yy[k] = yh; k++;
-
 
990
		}
-
 
991
		if (ctr_intersect(zll, zhh, zc, &f)) {
-
 
992
		    xx[k] = xl + f * (xh - xl);
-
 
993
		    yy[k] = yl + f * (yh - yl);
-
 
994
		    k++;
-
 
995
		}
-
 
996
		break;
-
 
997
	    case 11:
-
 
998
		if (ctr_intersect(zhl, zhh, zc, &f)) {
-
 
999
		    yy[k] = yl + f * (yh - yl);
-
 
1000
		    xx[k] = xh; k++;
-
 
1001
		}
-
 
1002
		if (ctr_intersect(zll, zhl, zc, &f)) {
-
 
1003
		    xx[k] = xl + f * (xh - xl);
-
 
1004
		    yy[k] = yl; k++;
-
 
1005
		}
-
 
1006
		if (ctr_intersect(zll, zhh, zc, &f)) {
-
 
1007
		    xx[k] = xl + f * (xh - xl);
-
 
1008
		    yy[k] = yl + f * (yh - yl);
-
 
1009
		    k++;
-
 
1010
		}
-
 
1011
		break;
-
 
1012
	    case 7:
-
 
1013
		if (ctr_intersect(zll, zlh, zc, &f)) {
-
 
1014
		    yy[k] = yl + f * (yh - yl);
-
 
1015
		    xx[k] = xl; k++;
-
 
1016
		}
-
 
1017
		if (ctr_intersect(zll, zhl, zc, &f)) {
-
 
1018
		    xx[k] = xl + f * (xh - xl);
-
 
1019
		    yy[k] = yl; k++;
961
    vmax = vmaxget();
1020
		}
-
 
1021
		if (ctr_intersect(zlh, zhl, zc, &f)) {
-
 
1022
		    xx[k] = xl + f * (xh - xl);
-
 
1023
		    yy[k] = yh + f * (yl - yh);
-
 
1024
		    k++;
-
 
1025
		}
-
 
1026
		break;
-
 
1027
	    }
-
 
1028
 
-
 
1029
	    /* We now have k(=2,4) endpoints */
-
 
1030
	    /* Decide which to join */
-
 
1031
 
-
 
1032
	    seglist = NULL;
-
 
1033
 
-
 
1034
	    if (k > 0) {
-
 
1035
		if (k == 2) {
-
 
1036
		    seglist = ctr_newseg(xx[0], yy[0], xx[1], yy[1], seglist);
962
    ctr_SegDB = contourLines(REAL(x), nx, REAL(y), ny, REAL(z), zc, atom);
1037
		}
-
 
1038
		else if (k == 4) {
-
 
1039
		    for (k = 3; k >= 1; k--) {
-
 
1040
			m = k;
-
 
1041
			xl = xx[k];
-
 
1042
			for (l = 0; l < k; l++) {
-
 
1043
			    if (xx[l] > xl) {
-
 
1044
				xl = xx[l];
-
 
1045
				m = l;
-
 
1046
			    }
-
 
1047
			}
-
 
1048
			if (m != k) {
-
 
1049
			    xl = xx[k];
-
 
1050
			    yl = yy[k];
-
 
1051
			    xx[k] = xx[m];
-
 
1052
			    yy[k] = yy[m];
-
 
1053
			    xx[m] = xl;
963
    vmaxset(vmax);
1054
			    yy[m] = yl;
-
 
1055
			}
-
 
1056
		    }
-
 
1057
		    seglist = ctr_newseg(xx[0], yy[0], xx[1], yy[1], seglist);
-
 
1058
		    seglist = ctr_newseg(xx[2], yy[2], xx[3], yy[3], seglist);
-
 
1059
		}
-
 
1060
		else error("k != 2 or 4");
-
 
1061
	    }
-
 
1062
	    ctr_SegDB[i + j * nx] = seglist;
-
 
1063
	}
-
 
1064
    }
-
 
1065
 
964
 
1066
    /* The segment database is now assembled. */
965
    /* The segment database is now assembled. */
1067
    /* Begin following contours. */
966
    /* Begin following contours. */
1068
    /* 1. Grab a segment */
967
    /* 1. Grab a segment */
1069
    /* 2. Follow its tail */
968
    /* 2. Follow its tail */