1 2 #include <../src/sys/classes/draw/utils/axisimpl.h> 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "PetscRint" 6 static PetscErrorCode PetscRint(PetscReal x,PetscReal *result) 7 { 8 PetscFunctionBegin; 9 if (x > 0) *result = floor(x + 0.5); 10 else *result = floor(x - 0.5); 11 PetscFunctionReturn(0); 12 } 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "PetscDrawAxisSetLimits" 16 /*@ 17 PetscDrawAxisSetLimits - Sets the limits (in user coords) of the axis 18 19 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 20 21 Input Parameters: 22 + axis - the axis 23 . xmin,xmax - limits in x 24 - ymin,ymax - limits in y 25 26 Options Database: 27 . -drawaxis_hold - hold the initial set of axis limits for future plotting 28 29 Level: advanced 30 31 .seealso: PetscDrawAxisSetHoldLimits() 32 33 @*/ 34 PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax) 35 { 36 PetscErrorCode ierr; 37 38 PetscFunctionBegin; 39 if (!axis) PetscFunctionReturn(0); 40 if (axis->hold) PetscFunctionReturn(0); 41 axis->xlow = xmin; 42 axis->xhigh= xmax; 43 axis->ylow = ymin; 44 axis->yhigh= ymax; 45 ierr = PetscOptionsHasName(((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);CHKERRQ(ierr); 46 PetscFunctionReturn(0); 47 } 48 49 #undef __FUNCT__ 50 #define __FUNCT__ "PetscDrawAxisGetLimits" 51 /*@ 52 PetscDrawAxisGetLimits - Gets the limits (in user coords) of the axis 53 54 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 55 56 Input Parameters: 57 + axis - the axis 58 . xmin,xmax - limits in x 59 - ymin,ymax - limits in y 60 61 Level: advanced 62 63 .seealso: PetscDrawAxisSetLimits() 64 65 @*/ 66 PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax) 67 { 68 PetscFunctionBegin; 69 if (!axis) PetscFunctionReturn(0); 70 if (axis->hold) PetscFunctionReturn(0); 71 *xmin = axis->xlow; 72 *xmax = axis->xhigh; 73 *ymin = axis->ylow; 74 *ymax = axis->yhigh; 75 PetscFunctionReturn(0); 76 } 77 78 #undef __FUNCT__ 79 #define __FUNCT__ "PetscADefLabel" 80 /* 81 val is the label value. sep is the separation to the next (or previous) 82 label; this is useful in determining how many significant figures to 83 keep. 84 */ 85 PetscErrorCode PetscADefLabel(PetscReal val,PetscReal sep,char **p) 86 { 87 static char buf[40]; 88 PetscErrorCode ierr; 89 PetscReal rval; 90 91 PetscFunctionBegin; 92 /* Find the string */ 93 if (PetscAbsReal(val)/sep < 1.e-4) { 94 buf[0] = '0'; buf[1] = 0; 95 } else { 96 ierr = PetscRint(val,&rval);CHKERRQ(ierr); 97 if (rval == val) { 98 sprintf(buf,"%d",(int)val); 99 ierr = PetscStripInitialZero(buf);CHKERRQ(ierr); 100 ierr = PetscStripAllZeros(buf);CHKERRQ(ierr); 101 ierr = PetscStripTrailingZeros(buf);CHKERRQ(ierr); 102 } else { 103 sprintf(buf,"%0.1le",(double)val); 104 ierr = PetscStripe0(buf);CHKERRQ(ierr); 105 ierr = PetscStripInitialZero(buf);CHKERRQ(ierr); 106 ierr = PetscStripAllZeros(buf);CHKERRQ(ierr); 107 ierr = PetscStripTrailingZeros(buf);CHKERRQ(ierr); 108 } 109 } 110 *p =buf; 111 PetscFunctionReturn(0); 112 } 113 114 #undef __FUNCT__ 115 #define __FUNCT__ "PetscADefTicks" 116 /* Finds "nice" locations for the ticks */ 117 PetscErrorCode PetscADefTicks(PetscReal low,PetscReal high,int num,int *ntick,PetscReal * tickloc,int maxtick) 118 { 119 PetscErrorCode ierr; 120 int i,power; 121 PetscReal x = 0.0,base=0.0; 122 123 PetscFunctionBegin; 124 /* patch if low == high */ 125 if (low == high) { 126 low -= .01; 127 high += .01; 128 } 129 130 /* if (PetscAbsReal(low-high) < 1.e-8) { 131 low -= .01; 132 high += .01; 133 } */ 134 135 ierr = PetscAGetBase(low,high,num,&base,&power);CHKERRQ(ierr); 136 ierr = PetscAGetNice(low,base,-1,&x);CHKERRQ(ierr); 137 138 /* Values are of the form j * base */ 139 /* Find the starting value */ 140 if (x < low) x += base; 141 142 i = 0; 143 while (i < maxtick && x <= high) { 144 tickloc[i++] = x; 145 x += base; 146 } 147 *ntick = i; 148 149 if (i < 2 && num < 10) { 150 ierr = PetscADefTicks(low,high,num+1,ntick,tickloc,maxtick);CHKERRQ(ierr); 151 } 152 if (num == 10) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"trouble"); 153 PetscFunctionReturn(0); 154 } 155 156 #define EPS 1.e-6 157 158 #undef __FUNCT__ 159 #define __FUNCT__ "PetscExp10" 160 PetscErrorCode PetscExp10(PetscReal d,PetscReal *result) 161 { 162 PetscFunctionBegin; 163 *result = pow((PetscReal)10.0,d); 164 PetscFunctionReturn(0); 165 } 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "PetscMod" 169 PetscErrorCode PetscMod(PetscReal x,PetscReal y,PetscReal *result) 170 { 171 int i; 172 173 PetscFunctionBegin; 174 if (y == 1) { 175 *result = 0.0; 176 PetscFunctionReturn(0); 177 } 178 i = ((int)x) / ((int)y); 179 x = x - i * y; 180 while (x > y) x -= y; 181 *result = x; 182 PetscFunctionReturn(0); 183 } 184 185 #undef __FUNCT__ 186 #define __FUNCT__ "PetscCopysign" 187 PetscErrorCode PetscCopysign(PetscReal a,PetscReal b,PetscReal *result) 188 { 189 PetscFunctionBegin; 190 if (b >= 0) *result = a; 191 else *result = -a; 192 PetscFunctionReturn(0); 193 } 194 195 #undef __FUNCT__ 196 #define __FUNCT__ "PetscAGetNice" 197 /* 198 Given a value "in" and a "base", return a nice value. 199 based on "sign", extend up (+1) or down (-1) 200 */ 201 PetscErrorCode PetscAGetNice(PetscReal in,PetscReal base,int sign,PetscReal *result) 202 { 203 PetscReal etmp,s,s2,m; 204 PetscErrorCode ierr; 205 206 PetscFunctionBegin; 207 ierr = PetscCopysign (0.5,(double)sign,&s);CHKERRQ(ierr); 208 etmp = in / base + 0.5 + s; 209 ierr = PetscCopysign (0.5,etmp,&s);CHKERRQ(ierr); 210 ierr = PetscCopysign (EPS * etmp,(double)sign,&s2);CHKERRQ(ierr); 211 etmp = etmp - 0.5 + s - s2; 212 ierr = PetscMod(etmp,1.0,&m);CHKERRQ(ierr); 213 etmp = base * (etmp - m); 214 *result = etmp; 215 PetscFunctionReturn(0); 216 } 217 218 #undef __FUNCT__ 219 #define __FUNCT__ "PetscAGetBase" 220 PetscErrorCode PetscAGetBase(PetscReal vmin,PetscReal vmax,int num,PetscReal*Base,int*power) 221 { 222 PetscReal base,ftemp,e10; 223 static PetscReal base_try[5] = {10.0,5.0,2.0,1.0,0.5}; 224 PetscErrorCode ierr; 225 int i; 226 227 PetscFunctionBegin; 228 /* labels of the form n * BASE */ 229 /* get an approximate value for BASE */ 230 base = (vmax - vmin) / (double)(num + 1); 231 232 /* make it of form m x 10^power, m in [1.0, 10) */ 233 if (base <= 0.0) { 234 base = PetscAbsReal(vmin); 235 if (base < 1.0) base = 1.0; 236 } 237 ftemp = log10((1.0 + EPS) * base); 238 if (ftemp < 0.0) ftemp -= 1.0; 239 *power = (int)ftemp; 240 ierr = PetscExp10((double)- *power,&e10);CHKERRQ(ierr); 241 base = base * e10; 242 if (base < 1.0) base = 1.0; 243 /* now reduce it to one of 1, 2, or 5 */ 244 for (i=1; i<5; i++) { 245 if (base >= base_try[i]) { 246 ierr = PetscExp10((double)*power,&e10);CHKERRQ(ierr); 247 base = base_try[i-1] * e10; 248 if (i == 1) *power = *power + 1; 249 break; 250 } 251 } 252 *Base = base; 253 PetscFunctionReturn(0); 254 } 255 256 257 258 259 260 261