diff options
Diffstat (limited to 'attic/muse2-oom/muse2/muse/widgets/dimap.cpp')
-rw-r--r-- | attic/muse2-oom/muse2/muse/widgets/dimap.cpp | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/attic/muse2-oom/muse2/muse/widgets/dimap.cpp b/attic/muse2-oom/muse2/muse/widgets/dimap.cpp new file mode 100644 index 00000000..1f87358c --- /dev/null +++ b/attic/muse2-oom/muse2/muse/widgets/dimap.cpp @@ -0,0 +1,308 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: dimap.cpp,v 1.1.1.1 2003/10/27 18:55:11 wschweer Exp $ + +// Copyright (C) 1997 Josef Wilgen +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License, version 2, +// as published by the Free Software Foundation. +// +// (C) Copyright 2000 Werner Schweer (ws@seh.de) +//========================================================= + +#include <cmath> +#include "dimap.h" +#include "mmath.h" + +const double DiMap::LogMin = 1.0e-150; +const double DiMap::LogMax = 1.0e150; + +// DiMap - Map a double interval into an integer interval +// +// The DiMap class maps an interval of type double into an interval of +// type integer. It consists +// of two intervals D = [d1, d2] (double) and I = [i1, i2] (int), which are +// specified with the @DiMap::setDblRange@ and @DiMap::setIntRange@ +// members. The point d1 is mapped to the point i1, and d2 is mapped to i2. +// Any point inside or outside D can be mapped to a point inside or outside +// I using @DiMap::transform@ or @DiMap::limTransform@ or vice versa +// using @QwtPlot::invTransform@. D can be scaled linearly or +// logarithmically, as specified with @DiMap::setDblRange@. + +//------------------------------------------------------------ +//.F DiMap::DiMap (1) +// Construct a DiMap instance. +// +//.u Syntax +//.f DiMap::DiMap() +// +//.u Description +// The double and integer intervals are both set to [0,1]. +//------------------------------------------------------------ + +DiMap::DiMap() + { + d_x1 = 0.0; + d_x2 = 1.0; + d_y1 = 0; + d_y2 = 1; + d_cnv = 1.0; + } + +//------------------------------------------------------------ +//.F DiMap::DiMap (2) +// Construct a DiMap instance with initial integer +// and double intervals +// +//.u Syntax +//.f DiMap::DiMap(int i1, int i2, double d1, double d2, bool logarithmic) +// +//.u Parameters +//.p int i1 -- first border of integer interval +// int i2 -- second border of integer interval +// double d1 -- first border of double interval +// double d2 -- second border of double interval +// bool logarithmic -- logarithmic mapping, TRUE or FALSE. Defaults +// to FALSE. +//------------------------------------------------------------ + +DiMap::DiMap(int i1, int i2, double d1, double d2, bool logarithmic) + { + d_log = logarithmic; + setIntRange(i1,i2); + setDblRange(d1, d2); + } + +//------------------------------------------------------------ +//.F DiMap::~DiMap +// Destroy a DiMap instance. +// +//.u Syntax +//.f DiMap::~DiMap() +//------------------------------------------------------------ + +DiMap::~DiMap() + { + } + +//------------------------------------------------------------ +//.F DiMap::contains (1) +// Returns TRUE if a value x lies inside or at the border of the +// map's double range. +// +//.u Syntax +//.f bool DiMap::contains(double x) +// +//.u Parameters +//.p double x -- value +//------------------------------------------------------------ + +bool DiMap::contains(double x) const + { + return ( (x >= qwtMin(d_x1, d_x1)) && (x <= qwtMax(d_x1, d_x2))); + } + +//------------------------------------------------------------ +//.F DiMap::contains (2) +// Returns TRUE if a value x lies inside or at the border of the +// map's integer range +// +//.u Syntax +//.f bool DiMap::contains(int x) +// +//.u Parameters +//.p int x -- value +//------------------------------------------------------------ + +bool DiMap::contains(int x) const + { + return ( (x >= qwtMin(d_y1, d_y1)) && (x <= qwtMax(d_y1, d_y2))); + } + +//------------------------------------------------------------ +//.F DiMap::setDblRange +// Specify the borders of the double interval +// +//.u Syntax +//.f void DiMap::setDblRange(double d1, double d2, bool lg = FALSE) +// +//.u Parameters +//.p double d1 -- first border +// double d2 -- second border +// bool lg -- logarithmic (TRUE) or linear (FALSE) +// scaling. Defaults to FALSE. +//------------------------------------------------------------ + +void DiMap::setDblRange(double d1, double d2, bool lg) + { + if (lg) { + d_log = true; + if (d1 < LogMin) + d1 = LogMin; + else if (d1 > LogMax) + d1 = LogMax; + + if (d2 < LogMin) + d2 = LogMin; + else if (d2 > LogMax) + d2 = LogMax; + + d_x1 = log(d1); + d_x2 = log(d2); + } + else { + d_log = FALSE; + d_x1 = d1; + d_x2 = d2; + } + newFactor(); + } + +//------------------------------------------------------------ +//.F DiMap::setIntRange +// Specify the borders of the integer interval +// +//.u Syntax +//.f void DiMap::setIntRange(int i1, int i2) +// +//.u Parameters +//.p int i1 -- first border +// int i2 -- second border +//------------------------------------------------------------ + +void DiMap::setIntRange(int i1, int i2) + { + d_y1 = i1; + d_y2 = i2; + newFactor(); + } + +//------------------------------------------------------------ +//.F DiMap::transform +// Transform a point in double interval into an point in the +// integer interval +// +//.u Syntax +//.f int DiMap::transform(double x) +// +//.u Parameters +//.p double x +// +//.u Return Value +//.t +// linear mapping: -- rint(i1 + (i2 - i1) / (d2 - d1) * (x - d1)) +// logarithmic mapping: -- rint(i1 + (i2 - i1) / log(d2 / d1) * log(x / d1)) +// +//.u Note +// The specified point is allowed to lie outside the intervals. If you +// want to limit the returned value, use @DiMap::limTransform@. +//------------------------------------------------------------ + +int DiMap::transform(double x) const + { + if (d_log) + return (d_y1 + int(rint( (log(x) - d_x1) * d_cnv ))); + else + return (d_y1 + int(rint( (x - d_x1) * d_cnv ))); + } + +//------------------------------------------------------------ +//.F DiMap::invTransform +// Transform an integer value into a double value +// +//.u Syntax +//.f double DiMap::invTransform(int y) +// +//.u Parameters +//.p int y -- integer value to be transformed +// +//.u Return Value +//.t +// linear mapping: -- d1 + (d2 - d1) / (i2 - i1) * (y - i1) +// logarithmic mapping: -- d1 + (d2 - d1) / log(i2 / i1) * log(y / i1) +//------------------------------------------------------------ + +double DiMap::invTransform(int y) const + { + if (d_cnv == 0.0) + return 0.0; + else { + if (d_log) + return exp(d_x1 + double(y - d_y1) / d_cnv ); + else + return ( d_x1 + double(y - d_y1) / d_cnv ); + } + } + +//------------------------------------------------------------ +//.F DiMap::limTransform +// Transform and limit +// +//.u Syntax +//.f int DiMap::limTransform(double x) +// +//.u Parameters +//.p double x +// +//.u Return Value +// transformed value +// +//.u Description +// The function is similar to @DiMap::transform@, but limits the input value +// to the nearest border of the map's double interval if it lies outside +// that interval. +//------------------------------------------------------------ + +int DiMap::limTransform(double x) const + { + if ( x > qwtMax(d_x1, d_x2) ) + x = qwtMax(d_x1, d_x2); + else if ( x < qwtMin(d_x1, d_x2)) + x = qwtMin(d_x1, d_x2); + return transform(x); + } + +//------------------------------------------------------------ +//.F DiMap::xTransform +// Exact transformation +// +//.u Syntax +//.f double DiMap::dTransform(double x) +// +//.u Parameters +//.p double x -- value to be transformed +// +//.u Return Value +//.t +// linear mapping: -- i1 + (i2 - i1) / (d2 - d1) * (x - d1) +// logarithmic mapping: -- i1 + (i2 - i1) / log(d2 / d1) * log(x / d1) +// +//.u Description +// This function is similar to @DiMap::transform@, but +// makes the integer interval appear to be double. +//------------------------------------------------------------ + +double DiMap::xTransform(double x) const + { + double rv; + + if (d_log) + rv = double(d_y1) + (log(x) - d_x1) * d_cnv; + else + rv = double(d_y1) + (x - d_x1) * d_cnv; + return rv; + } + +//------------------------------------------------------------ +//.F DiMap::newFactor +// Re-calculate the conversion factor. +//------------------------------------------------------------ + +void DiMap::newFactor() + { + if (d_x2 != d_x1) + d_cnv = double(d_y2 - d_y1) / (d_x2 - d_x1); + else + d_cnv = 0.0; + } |