Actual source code: axis.c
petsc-3.6.1 2015-08-06
2: #include <../src/sys/classes/draw/utils/axisimpl.h> /*I "petscdraw.h" I*/
6: /*@
7: PetscDrawAxisSetLimits - Sets the limits (in user coords) of the axis
9: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
11: Input Parameters:
12: + axis - the axis
13: . xmin,xmax - limits in x
14: - ymin,ymax - limits in y
16: Options Database:
17: . -drawaxis_hold - hold the initial set of axis limits for future plotting
19: Level: advanced
21: .seealso: PetscDrawAxisSetHoldLimits()
23: @*/
24: PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)
25: {
29: if (!axis) return(0);
30: if (axis->hold) return(0);
31: axis->xlow = xmin;
32: axis->xhigh= xmax;
33: axis->ylow = ymin;
34: axis->yhigh= ymax;
36: PetscOptionsHasName(((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);
37: return(0);
38: }
42: /*@
43: PetscDrawAxisGetLimits - Gets the limits (in user coords) of the axis
45: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
47: Input Parameters:
48: + axis - the axis
49: . xmin,xmax - limits in x
50: - ymin,ymax - limits in y
52: Level: advanced
54: .seealso: PetscDrawAxisSetLimits()
56: @*/
57: PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax)
58: {
60: if (!axis) return(0);
61: if (axis->hold) return(0);
62: *xmin = axis->xlow;
63: *xmax = axis->xhigh;
64: *ymin = axis->ylow;
65: *ymax = axis->yhigh;
66: return(0);
67: }
71: /*
72: val is the label value. sep is the separation to the next (or previous)
73: label; this is useful in determining how many significant figures to
74: keep.
75: */
76: PetscErrorCode PetscADefLabel(PetscReal val,PetscReal sep,char **p)
77: {
78: static char buf[40];
82: /* Find the string */
83: if (PetscAbsReal(val)/sep < 1.e-4) {
84: buf[0] = '0'; buf[1] = 0;
85: } else {
86: sprintf(buf,"%0.1e",(double)val);
87: PetscStripZerosPlus(buf);
88: PetscStripe0(buf);
89: PetscStripInitialZero(buf);
90: PetscStripAllZeros(buf);
91: PetscStripTrailingZeros(buf);
92: }
93: *p =buf;
94: return(0);
95: }
99: /* Finds "nice" locations for the ticks */
100: PetscErrorCode PetscADefTicks(PetscReal low,PetscReal high,int num,int *ntick,PetscReal * tickloc,int maxtick)
101: {
103: int i,power;
104: PetscReal x = 0.0,base=0.0;
107: PetscAGetBase(low,high,num,&base,&power);
108: PetscAGetNice(low,base,-1,&x);
110: /* Values are of the form j * base */
111: /* Find the starting value */
112: if (x < low) x += base;
114: i = 0;
115: while (i < maxtick && x <= high) {
116: tickloc[i++] = x;
117: x += base;
118: }
119: *ntick = i;
121: if (i < 2 && num < 10) {
122: PetscADefTicks(low,high,num+1,ntick,tickloc,maxtick);
123: }
124: return(0);
125: }
127: #define EPS 1.e-6
131: PetscErrorCode PetscExp10(PetscReal d,PetscReal *result)
132: {
134: *result = PetscPowReal((PetscReal)10.0,d);
135: return(0);
136: }
140: PetscErrorCode PetscMod(PetscReal x,PetscReal y,PetscReal *result)
141: {
142: int i;
145: if (y == 1) {
146: *result = 0.0;
147: return(0);
148: }
149: i = ((int)x) / ((int)y);
150: x = x - i * y;
151: while (x > y) x -= y;
152: *result = x;
153: return(0);
154: }
158: PetscErrorCode PetscCopysign(PetscReal a,PetscReal b,PetscReal *result)
159: {
161: if (b >= 0) *result = a;
162: else *result = -a;
163: return(0);
164: }
168: /*
169: Given a value "in" and a "base", return a nice value.
170: based on "sign", extend up (+1) or down (-1)
171: */
172: PetscErrorCode PetscAGetNice(PetscReal in,PetscReal base,int sign,PetscReal *result)
173: {
174: PetscReal etmp,s,s2,m;
178: PetscCopysign (0.5,(double)sign,&s);
179: etmp = in / base + 0.5 + s;
180: PetscCopysign (0.5,etmp,&s);
181: PetscCopysign (EPS * etmp,(double)sign,&s2);
182: etmp = etmp - 0.5 + s - s2;
183: PetscMod(etmp,1.0,&m);
184: etmp = base * (etmp - m);
185: *result = etmp;
186: return(0);
187: }
191: PetscErrorCode PetscAGetBase(PetscReal vmin,PetscReal vmax,int num,PetscReal *Base,int *power)
192: {
193: PetscReal base,ftemp,e10;
194: static PetscReal base_try[5] = {10.0,5.0,2.0,1.0,0.5};
195: PetscErrorCode ierr;
196: int i;
199: /* labels of the form n * BASE */
200: /* get an approximate value for BASE */
201: base = (vmax - vmin) / (double)(num + 1);
203: /* make it of form m x 10^power, m in [1.0, 10) */
204: if (base <= 0.0) {
205: base = PetscAbsReal(vmin);
206: if (base < 1.0) base = 1.0;
207: }
208: ftemp = PetscLog10Real((1.0 + EPS) * base);
209: if (ftemp < 0.0) ftemp -= 1.0;
210: *power = (int)ftemp;
211: PetscExp10((double)-*power,&e10);
212: base = base * e10;
213: if (base < 1.0) base = 1.0;
214: /* now reduce it to one of 1, 2, or 5 */
215: for (i=1; i<5; i++) {
216: if (base >= base_try[i]) {
217: PetscExp10((double)*power,&e10);
218: base = base_try[i-1] * e10;
219: if (i == 1) *power = *power + 1;
220: break;
221: }
222: }
223: *Base = base;
224: return(0);
225: }