Example #1
0
bool ScaleDiv::buildLogDiv(int maxMajSteps, int maxMinSteps, double majStep)
{
	double firstTick, lastTick;
	double lFirst, lLast;
	double val, sval, minStep, minFactor;
	int nMaj, nMin, minSize, i, k, k0, kstep, kmax, i0;
	int rv = true;
	double width;

	QVector<double> buffer;


	// Parameter range check
	maxMajSteps = qwtMax(1, qwtAbs(maxMajSteps));
	maxMinSteps = qwtMax(0, qwtAbs(maxMinSteps));
	majStep = qwtAbs(majStep);

	// boundary check
	limRange(d_hBound, LOG_MIN, LOG_MAX);
	limRange(d_lBound, LOG_MIN, LOG_MAX);

	// reset vectors
	d_minMarks.resize(0);
	d_majMarks.resize(0);

	if (d_lBound == d_hBound) return true;

	// scale width in decades
	width = log10(d_hBound) - log10(d_lBound);

	// scale width is less than one decade -> build linear scale
	if (width < 1.0)
	{
		rv = buildLinDiv(maxMajSteps, maxMinSteps, 0.0);
		// convert step width to decades
		if (d_majStep > 0)
			d_majStep = log10(d_majStep);

		return rv;
	}

	//
	//  Set up major scale divisions
	//
	if (majStep == 0.0)
		d_majStep = qwtCeil125(width * 0.999999 / double(maxMajSteps));
	else
		d_majStep = majStep;

	// major step must be >= 1 decade
	d_majStep = qwtMax(d_majStep, 1.0);


	lFirst = ceil((log10(d_lBound) - step_eps * d_majStep) / d_majStep) * d_majStep;
	lLast = floor((log10(d_hBound) + step_eps * d_majStep) / d_majStep) * d_majStep;

	firstTick = pow(10.0, lFirst);
	lastTick = pow(10.0, lLast);

	nMaj = qwtMin(10000, int(rint(qwtAbs(lLast - lFirst) / d_majStep)) + 1);

	d_majMarks.resize(nMaj);
	qwtLogSpace(d_majMarks.data(), d_majMarks.size(), firstTick, lastTick);


	//
	// Set up minor scale divisions
	//

	if ((d_majMarks.size() < 1) || (maxMinSteps < 1)) return true; // no minor marks

	if (d_majStep < 1.1) // major step width is one decade
	{
		if (maxMinSteps >= 8)
		{
			k0 = 2;
			kmax = 9;
			kstep = 1;
			minSize = (d_majMarks.size() + 1) * 8;
		}
		else if (maxMinSteps >= 4)
		{
			k0 = 2;
			kmax = 8;
			kstep = 2;
			minSize = (d_majMarks.size() + 1) * 4;
		}
		else if (maxMinSteps >= 2)
		{
			k0 = 2;
			kmax = 5;
			kstep = 3;
			minSize = (d_majMarks.size() + 1) * 2;
		}
		else
		{
			k0 = 5;
			kmax = 5;
			kstep = 1;
			minSize = (d_majMarks.size() + 1);
		}

		// resize buffer to the max. possible number of minor marks
		buffer.resize(minSize);

		// Are there minor ticks below the first major tick?
		if (d_lBound < firstTick)
			i0 = -1;
		else
			i0 = 0;

		minSize = 0;
		for (i = i0; i < (int) d_majMarks.size(); i++)
		{
			if (i >= 0)
				val = d_majMarks[i];
			else
				val = d_majMarks[0] / pow(10.0, d_majStep);

			for (k = k0; k <= kmax; k += kstep)
			{
				sval = val * double(k);
				if (limRange(sval, d_lBound, d_hBound, border_eps))
				{
					buffer[minSize] = sval;
					minSize++;
				}
			}
		}

		// copy values into the minMarks array
		//d_minMarks.duplicate(buffer.data(), minSize);
		d_minMarks.resize(minSize);
		qCopy(buffer.data(), buffer.data() + minSize, d_minMarks.begin());


	}
	else // major step > one decade
	{

		// substep width in decades, at least one decade
		minStep = qwtCeil125((d_majStep - step_eps * (d_majStep / double(maxMinSteps)))
				/ double(maxMinSteps));
		minStep = qwtMax(1.0, minStep);

		// # subticks per interval
		nMin = int(rint(d_majStep / minStep)) - 1;

		// Do the minor steps fit into the interval?
		if (qwtAbs(double(nMin + 1) * minStep - d_majStep) > step_eps * d_majStep)
			nMin = 0;

		if (nMin < 1) return true; // no subticks

		// resize buffer to max. possible number of subticks
		buffer.resize((d_majMarks.size() + 1) * nMin);

		// substep factor = 10^substeps
		minFactor = qwtMax(pow(10, minStep), 10.0);

		// Are there minor ticks below the first major tick?
		if (d_lBound < firstTick)
			i0 = -1;
		else
			i0 = 0;

		minSize = 0;
		for (i = i0; i < (int) d_majMarks.size(); i++)
		{
			if (i >= 0)
				val = d_majMarks[i];
			else
				val = firstTick / pow(10.0, d_majStep);

			for (k = 0; k < nMin; k++)
			{
				sval = (val *= minFactor);
				if (limRange(sval, d_lBound, d_hBound, border_eps))
				{
					buffer[minSize] = sval;
					minSize++;
				}
			}
		}
		//d_minMarks.duplicate(buffer.data(), minSize);
		d_minMarks.resize(minSize);
		qCopy(buffer.data(), buffer.data() + minSize, d_minMarks.begin());

	}

	return rv;
}
Example #2
0
/*!
  \brief Build a linear scale
*/
void QwtAutoScale::buildLinScale ()
{
    double delta;
    const double ticks = double (d_maxMajor);

    //
    // If in Autoscale Mode, adjust minval and maxval according to
    // the active scale options, and add the margins
    //
    if (!d_autoScale) 
        return;
    
    double minval = d_minValue;    // scale boundaries are based on the
    double maxval = d_maxValue;    // data.

    //
    // add / subtract margins
    //
    if (d_loMargin > 0.0)
       minval -= d_loMargin;
    if (d_hiMargin > 0.0)
       maxval += d_hiMargin;

    //
    //  Correct minval / maxval according to the scale options
    //
    if (d_scaleOpt & Symmetric)
    {
        delta = qwtMax(qwtAbs(d_ref - maxval), qwtAbs(d_ref - minval));
        maxval = d_ref + delta;
        minval = d_ref - delta; 
    }
    else if (d_scaleOpt & IncludeRef)
    {
        if (maxval < d_ref) 
           maxval = d_ref;
        else if (minval > d_ref) 
           minval = d_ref;
    }
    
    //
    // first approximation of d_scaleMin and d_scaleMax
    //
    setRange(minval, maxval);
    delta = d_scaleMax - d_scaleMin;


    // dec := maximal power of ten which fits into the interval
    //   [d_scaleMin,d_scaleMax]
    const double dec = pow (10.0, floor (log10 (delta)));

    //
    //  The following magic line calculates the step size such that
    //      - The number of subintervals will not exceed the maximum
    //        as specified by the user
    //      - The step size fits {1,2,5}*10^n with a natural number n  
    // 
    double step = qwtCeil125(delta * 0.999999 / dec / ticks) * dec;

    //
    //  determine he final values of scaleMin and scaleMax
    //
    if (! (d_scaleOpt & Floating) )
    {
       // adjust of d_scaleMin and d_scaleMax such that both are integer
       // multiples of the step size.
       d_scaleMin = step * floor ((d_scaleMin + MinEps * step) / step);
       d_scaleMax = step * ceil ((d_scaleMax - MinEps * step) / step);
    }

    if (d_scaleOpt & Inverted)
    {
        step = -step;
        d_scldiv.rebuild(d_scaleMax, d_scaleMin, d_maxMajor, d_maxMinor,
             FALSE, step, FALSE);
    }
    else
    {
        d_scldiv.rebuild(d_scaleMin, d_scaleMax, d_maxMajor, d_maxMinor,
             FALSE, step, TRUE);
    }
}
Example #3
0
bool ScaleDiv::buildLinDiv(int maxMajSteps, int maxMinSteps, double step)
{

	int nMaj, nMin, minSize, i0, i, k;
	double val, mval;
	double firstTick, lastTick;
	double minStep;
	QVector<double> buffer;
	bool rv = true;

	// parameter range check
	maxMajSteps = qwtMax(1, maxMajSteps);
	maxMinSteps = qwtMax(0, maxMinSteps);
	step = qwtAbs(step);

	// reset vectors
	d_minMarks.resize(0);
	d_majMarks.resize(0);

	if (d_lBound == d_hBound) return true;

	//
	// Set up major divisions
	//
	if (step == 0.0)
		d_majStep = qwtCeil125(qwtAbs(d_hBound - d_lBound) * 0.999999
			/ double(maxMajSteps));
	else
		d_majStep = step;

	if (d_majStep == 0.0) return true;

	firstTick = ceil((d_lBound - step_eps * d_majStep) / d_majStep) * d_majStep;
	lastTick = floor((d_hBound + step_eps * d_majStep) / d_majStep) * d_majStep;

	nMaj = qwtMin(10000, int(rint((lastTick - firstTick) / d_majStep)) + 1);

	d_majMarks.resize(nMaj);
	qwtLinSpace(d_majMarks.data(), d_majMarks.size(), firstTick, lastTick);

	//
	// Set up minor divisions
	//
	if (maxMinSteps < 1) // no minor divs
		return true;

	minStep = qwtCeil125(d_majStep / double(maxMinSteps));

	if (minStep == 0.0) return true;

	nMin = qwtAbs(int(rint(d_majStep / minStep))) - 1; // # minor steps per interval

	// Do the minor steps fit into the interval?
	if (qwtAbs(double(nMin + 1) * minStep - d_majStep) > step_eps * d_majStep)
	{
		nMin = 1;
		minStep = d_majStep * 0.5;
	}

	// Are there minor ticks below the first major tick?
	if (d_majMarks[0] > d_lBound)
		i0 = -1;
	else
		i0 = 0;

	// resize buffer to the maximum possible number of minor ticks
	buffer.resize(nMin * (nMaj + 1));

	// calculate minor ticks
	if (rv)
	{
		minSize = 0;
		for (i = i0; i < (int) d_majMarks.size(); i++)
		{
			if (i >= 0)
				val = d_majMarks[i];
			else
				val = d_majMarks[0] - d_majStep;

			for (k = 0; k < nMin; k++)
			{
				mval = (val += minStep);
				if (limRange(mval, d_lBound, d_hBound, border_eps))
				{
					buffer[minSize] = mval;
					minSize++;
				}
			}
		}
		//d_minMarks.duplicate(buffer.data(), minSize);
		d_minMarks.resize(minSize);
		qCopy(buffer.data(), buffer.data() + minSize, d_minMarks.begin());
	}

	return rv;
}