src/analog/functions.h

changeset 316
dcd472be9ae8
child 322
e7ca120d93c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/analog/functions.h	Wed Jun 29 21:28:13 2022 +0200
@@ -0,0 +1,110 @@
+/***************************************************************************
+ *   Copyright (C) 2006-2008 by Tomasz Ziobrowski                          *
+ *   http://www.3electrons.com                                             *
+ *   e-mail: t.ziobrowski@3electrons.com                                   *
+ *                                                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef _FUNCTIONS_H_
+#define _FUNCTIONS_H_
+
+#include <assert.h>
+#include <cmath>
+//#include <iostream> // dla testów 
+
+using namespace std;
+
+/** 
+* Znajduje największą wartość mniejszą od scaleSize/steps i
+* jednocześnie będącą całkowicie podzielną przez wartość 
+* 10^N  gdzie n jest dowolną liczbą całkowitą.
+* dla 5,2,1 jest to  odpowiedniio {...,500,50,5,0.5,...},
+* {...200,20,2,0.2,0.02,...} etc. 
+*/ 
+ 
+
+double minimalStep(double scaleSize, int steps);
+
+
+/**
+* Szablonowa funkcja do wyznaczania skali w zadanym przedziale o wyznaczonej ilości punktów skali.
+* Na podstawie wartości minimalnej oraz maksymalnej, jaką chcemy osiągnać ustawia
+* wartości m_min oraz m_max w taki sposób cały przedział skali (m_max-m_min) był podzielny
+* przez ilość punktów skali a odległość pomiędzy punktami skali była wartoscią która jest
+* wieloktornością liczby 5. Dodatkowo isnieje możliwość przesunięcia skali w lewo lub prawo by
+* rozpoczynała się jak najbliżej wartości minimalnej lub kończyła jak najbliżej wartości
+* maksymalnej.
+*
+* @param m_minimum - wartość minilana na skali jaka ma być widoczna
+* @param m_maximum - wartość maksymalna na skali jaka ma być widoczna
+* @param m_min     - wyliczona wartość początkowa skali
+* @param m_max     - wyliczona wartość końcowa skali
+* @param stesp     - ilość węzłów jaką ma mieć skala
+* @param left      - czy skala ma być wyrównana do lewej czy do prawej (domyślnie do prawej).
+* @return Funkcja zwraca wartość true jeżeli wartości m_min oraz m_max w wyniku zmiany zakresu
+* zmieniły swoją wartość.  Na podstawie tej wartości wiadomo czy należy np. przerysować skalę
+* - podając wcześniej poprzednie wartości zakresu skali.
+*/
+
+template <typename T>
+bool range(T m_minimum,T m_maximum, T & m_min, T & m_max,unsigned int steps, bool left = false,double inc = 5.0)
+{
+  //cout<<"("<<m_minimum<<","<<m_maximum<<")  ("<<m_min<<","<<m_max<<")"<<endl;
+  T max_tmp = m_max, min_tmp = m_min;
+  m_max=m_maximum;
+  m_min=m_minimum;
+  assert( m_max > m_min );
+  //  assert( (m_max - m_min) > 0 );
+  //  if (m_max<0) left!=left; 
+  
+  T diff = abs(m_max - m_min);
+  T scale = 0, factor = 0 ;
+
+  while (inc * steps > (m_maximum-m_minimum))
+  if (inc/10 > 0 ) inc/=10;
+  else break;
+
+  bool done = false;
+  while ( diff > scale ) 
+   { factor+=static_cast<T>(inc);  scale = factor * steps;  }
+   
+  while (!done)
+  {
+    
+    // dirty hack to have zero equal exactly zero 
+    if (m_max<0)  m_max=m_min - fmodf(m_min,steps);
+    else m_max = 0.0; 
+    
+     while ( m_max < m_maximum ) m_max +=factor;
+     m_min = m_max - scale;
+     if (m_min <= m_minimum ) done = true;
+     else { factor+=static_cast<T>(inc); scale = factor * steps; }
+  }
+  // Wprowadzenie koretkty by skala nie przesuwała się w lewo na osi X
+  if (left)
+  	while (m_min + factor <= m_minimum)
+  	{
+	   	m_min+=factor;
+   		m_max+=factor;
+  	}
+//  cout<<"Min:"<<m_min<<" Max:"<<m_max<<endl;
+ return (m_max != max_tmp) | (m_min != min_tmp);
+}
+
+
+#endif // _FUNCTIONS_H_

mercurial