summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/widgets/dimap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/widgets/dimap.cpp')
-rw-r--r--attic/muse2-oom/muse2/muse/widgets/dimap.cpp308
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;
+ }