[dasher] Replace iCenterX with iMarginWidth and include in {i,}xmap; tidy header file.



commit 5a1c7c7a129710aa335c0685200743140ac6c4ab
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Mon Dec 13 17:23:02 2010 +0000

    Replace iCenterX with iMarginWidth and include in {i,}xmap; tidy header file.
    
    The rather complex formulae for computing _equivalent_ values of iMarginWidth,
      illustrates how ad-hoc we were being in computing iCenterX etc...
      I omit derivations of these formulae, as the intention is to discard this
      old layout ASAP.

 Src/DasherCore/DasherViewSquare.cpp |   36 ++++++++++++++++++----------------
 Src/DasherCore/DasherViewSquare.h   |   29 +++++++++++++--------------
 Src/DasherCore/DasherViewSquare.inl |   34 ++++++++++++++------------------
 3 files changed, 48 insertions(+), 51 deletions(-)
---
diff --git a/Src/DasherCore/DasherViewSquare.cpp b/Src/DasherCore/DasherViewSquare.cpp
index 1fc2af5..008c5a2 100644
--- a/Src/DasherCore/DasherViewSquare.cpp
+++ b/Src/DasherCore/DasherViewSquare.cpp
@@ -816,19 +816,19 @@ void CDasherViewSquare::Screen2Dasher(screenint iInputX, screenint iInputY, myin
 
   switch(eOrientation) {
   case Dasher::Opts::LeftToRight:
-    iDasherX = iCenterX - ( iInputX - iScreenWidth / 2 ) * m_iScalingFactor / iScaleFactorX;
+    iDasherX = ( iScreenWidth - iInputX ) * m_iScalingFactor / iScaleFactorX;
     iDasherY = iDasherHeight / 2 + ( iInputY - iScreenHeight / 2 ) * m_iScalingFactor / iScaleFactorY;
     break;
   case Dasher::Opts::RightToLeft:
-    iDasherX = myint(iCenterX + ( iInputX - iScreenWidth / 2 ) * m_iScalingFactor/ iScaleFactorX);
+    iDasherX = myint( ( iInputX ) * m_iScalingFactor/ iScaleFactorX);
     iDasherY = myint(iDasherHeight / 2 + ( iInputY - iScreenHeight / 2 ) * m_iScalingFactor/ iScaleFactorY);
     break;
   case Dasher::Opts::TopToBottom:
-    iDasherX = myint(iCenterX - ( iInputY - iScreenHeight / 2 ) * m_iScalingFactor/ iScaleFactorY);
+    iDasherX = myint( ( iScreenHeight - iInputY ) * m_iScalingFactor/ iScaleFactorY);
     iDasherY = myint(iDasherHeight / 2 + ( iInputX - iScreenWidth / 2 ) * m_iScalingFactor/ iScaleFactorX);
     break;
   case Dasher::Opts::BottomToTop:
-    iDasherX = myint(iCenterX + ( iInputY - iScreenHeight / 2 ) * m_iScalingFactor/ iScaleFactorY);
+    iDasherX = myint( ( iInputY  ) * m_iScalingFactor/ iScaleFactorY);
     iDasherY = myint(iDasherHeight / 2 + ( iInputX - iScreenWidth / 2 ) * m_iScalingFactor/ iScaleFactorX);
     break;
   }
@@ -857,14 +857,13 @@ void CDasherViewSquare::SetScaleFactor( void )
 
   // Try doing this a different way:
 
-  myint iDasherMargin( GetLongParameter(LP_MARGIN_WIDTH) ); // Make this a parameter
+  iMarginWidth = GetLongParameter(LP_MARGIN_WIDTH);
 
-  myint iMinX( 0-iDasherMargin );
+  myint iMinX( 0-iMarginWidth );
   myint iMaxX( iDasherWidth );
-  iCenterX = (iMinX + iMaxX)/2;
   myint iMinY( 0 );
   myint iMaxY( iDasherHeight );
-
+  myint iCenterX((iMinX+iMaxX)/2);
   Dasher::Opts::ScreenOrientations eOrientation(Dasher::Opts::ScreenOrientations(GetLongParameter(LP_REAL_ORIENTATION)));
   
   double dScaleFactorX, dScaleFactorY;
@@ -882,11 +881,12 @@ void CDasherViewSquare::SetScaleFactor( void )
     //So, use X scale for Y too...except first, we'll _try_ to reduce the difference
     // by changing the relative scaling of X and Y (by at most 20%):
     double dMul = max(0.8, dScaleFactorX / dScaleFactorY);
-    m_dXmpc *= dMul;
+    m_dXmpc *= dMul; // => m_dXmpc = dMul*0.9
     dScaleFactorX /= dMul;
 
     iScaleFactorX = myint(dScaleFactorX * m_iScalingFactor);
     iScaleFactorY = myint(std::max(dScaleFactorX, dScaleFactorY / 4.0) * m_iScalingFactor);
+    iMarginWidth = (iMaxX/20.0 + iMarginWidth*0.95)*dMul;
   } else {
     //X has more room; use Y scale for both -> will get lots history
     iScaleFactorX = myint(std::max(dScaleFactorY, dScaleFactorX / 4.0) * m_iScalingFactor);
@@ -894,9 +894,11 @@ void CDasherViewSquare::SetScaleFactor( void )
     // however, "compensate" by relaxing the default "relative scaling" of X
     // (normally only 90% of Y) towards 1...
     m_dXmpc = std::min(1.0,0.9 * dScaleFactorX / dScaleFactorY);
+    iMarginWidth = (iScreenWidth*m_iScalingFactor/iScaleFactorX - (4096-iMarginWidth)*m_dXmpc)/2;    
   }
   iCenterX *= m_dXmpc;
   
+  //iMarginWidth = (iMarginWidth + iScreenWidth*m_iScalingFactor/iScaleFactorX)*m_dXmpc/2.0;
 #ifdef DEBUG
   //now test Dasher2Screen & Screen2Dasher are inverses...
   for (screenint x=0; x<iScreenWidth; x++) {
@@ -975,28 +977,28 @@ void CDasherViewSquare::Dasher2Screen(myint iDasherX, myint iDasherY, screenint
 
   switch( eOrientation ) {
   case Dasher::Opts::LeftToRight:
-    iScreenX = screenint(iScreenWidth / 2 - 
-			 CustomIDiv((( iDasherX - iCenterX ) * iScaleFactorX), m_iScalingFactor));
+    iScreenX = screenint(iScreenWidth - 
+			 CustomIDiv((( iDasherX ) * iScaleFactorX), m_iScalingFactor));
     iScreenY = screenint(iScreenHeight / 2 +
 			 CustomIDiv(( iDasherY - iDasherHeight / 2 ) * iScaleFactorY, m_iScalingFactor));
     break;
   case Dasher::Opts::RightToLeft:
-    iScreenX = screenint(iScreenWidth / 2 + 
-			 CustomIDiv(( iDasherX - iCenterX ) * iScaleFactorX, m_iScalingFactor));
+    iScreenX = screenint(
+			 CustomIDiv(( iDasherX ) * iScaleFactorX, m_iScalingFactor));
     iScreenY = screenint(iScreenHeight / 2 + 
 			 CustomIDiv(( iDasherY - iDasherHeight / 2 ) * iScaleFactorY, m_iScalingFactor));
     break;
   case Dasher::Opts::TopToBottom:
     iScreenX = screenint(iScreenWidth / 2 + 
 			 CustomIDiv(( iDasherY - iDasherHeight / 2 ) * iScaleFactorX, m_iScalingFactor));
-    iScreenY = screenint(iScreenHeight / 2 - 
-			 CustomIDiv(( iDasherX - iCenterX ) * iScaleFactorY, m_iScalingFactor));
+    iScreenY = screenint(iScreenHeight - 
+			 CustomIDiv(( iDasherX ) * iScaleFactorY, m_iScalingFactor));
     break;
   case Dasher::Opts::BottomToTop:
     iScreenX = screenint(iScreenWidth / 2 + 
 			 CustomIDiv(( iDasherY - iDasherHeight / 2 ) * iScaleFactorX, m_iScalingFactor));
-    iScreenY = screenint(iScreenHeight / 2 + 
-			 CustomIDiv(( iDasherX - iCenterX ) * iScaleFactorY, m_iScalingFactor));
+    iScreenY = screenint(
+			 CustomIDiv(( iDasherX ) * iScaleFactorY, m_iScalingFactor));
     break;
   }
 }
diff --git a/Src/DasherCore/DasherViewSquare.h b/Src/DasherCore/DasherViewSquare.h
index 67c4a88..920f4aa 100644
--- a/Src/DasherCore/DasherViewSquare.h
+++ b/Src/DasherCore/DasherViewSquare.h
@@ -174,17 +174,18 @@ private:
   /// @name Nonlinearity
   /// Implements the non-linear part of the coordinate space mapping
   
-  /// Maps a dasher Y coordinate to the Y value in a linear version of Dasher space (i.e. still not screen pixels)
-  /// (i.e. screen coordinate = scale(ymap(dasher coord)))
+  /// Maps a dasher coordinate (linear in probability space, -ive x = in margin) to an abstract/resolution-independent
+  /// screen coordinate (linear in screen space, -ive x = offscreen) - i.e. pixel coordinate = scale({x,y}map(dasher coord)))
   inline myint ymap(myint iDasherY) const;
+  inline myint xmap(myint iDasherX) const;
   
   /// Inverse of the previous - i.e. dasher coord = iymap(scale(screen coord))
-  myint iymap(myint y) const;
-  ///parameters used by previous
+  inline myint iymap(myint y) const;
+  inline myint ixmap(myint x) const;
+  
+  ///Parameters for y non-linearity. (TODO Make into preprocessor defines?)
   const myint m_Y1, m_Y2, m_Y3;
 
-  myint xmap(myint x) const;
-  myint ixmap(myint x) const;
   inline void Crosshair(myint sx);
   
   inline myint CustomIDiv(myint iNumerator, myint iDenominator);
@@ -194,19 +195,17 @@ private:
   // Called on screen size or orientation changes
   void SetScaleFactor();
 
-  // Data
- 
+  // Parameters for x non-linearity
   double m_dXmpa, m_dXmpb, m_dXmpc;
-  screenint iCenterX;
-
-  // Cached values for scaling
-  myint iScaleFactorX;
-  myint iScaleFactorY;
+  
+  //width of margin, in abstract screen coords
+  myint iMarginWidth;
 
-  // The factor that scale factors are multipled by 
+  /// There is a ratio of iScaleFactor{X,Y} abstract screen coords to m_iScalingFactor real pixels
+  myint iScaleFactorX, iScaleFactorY;
   myint m_iScalingFactor;
 
-  // Cached extents of visible region
+  /// Cached extents of visible region
   myint m_iDasherMinX;
   myint m_iDasherMaxX;
   myint m_iDasherMinY;
diff --git a/Src/DasherCore/DasherViewSquare.inl b/Src/DasherCore/DasherViewSquare.inl
index b6b5b0f..22ff835 100644
--- a/Src/DasherCore/DasherViewSquare.inl
+++ b/Src/DasherCore/DasherViewSquare.inl
@@ -45,34 +45,30 @@ namespace Dasher {
 
   inline myint CDasherViewSquare::ixmap(myint x) const
   {
-    if (GetLongParameter(LP_NONLINEAR_X)==0) return x;
-    double dx = x / static_cast<double>(GetLongParameter(LP_MAX_Y));
-    if(dx < m_dXmpb * m_dXmpc)
-      dx /= m_dXmpc;
-    else
-      dx =m_dXmpb - m_dXmpa + m_dXmpa * exp((dx / m_dXmpc - m_dXmpb) / m_dXmpa);
+    double dx = (x - iMarginWidth) / static_cast<double>(GetLongParameter(LP_MAX_Y));
+    dx /= m_dXmpc;
+    if(GetLongParameter(LP_NONLINEAR_X)>0 && dx >= m_dXmpb)
+      dx = m_dXmpb - m_dXmpa + m_dXmpa * exp((dx - m_dXmpb) / m_dXmpa);
     return myint(dx * GetLongParameter(LP_MAX_Y));
   }
 
   inline myint CDasherViewSquare::xmap(myint x) const
   {
-    if (GetLongParameter(LP_NONLINEAR_X)==0) return x;
     double dx = x / static_cast<double>(GetLongParameter(LP_MAX_Y));
-    if(dx < m_dXmpb)
-      dx *= m_dXmpc;
-    else
-      dx = m_dXmpc * (m_dXmpa * log((dx + m_dXmpa - m_dXmpb) / m_dXmpa) + m_dXmpb);
-    return myint(ceil(dx * GetLongParameter(LP_MAX_Y)));
+    if(GetLongParameter(LP_NONLINEAR_X) && dx >= m_dXmpb)
+      dx = (m_dXmpa * log((dx + m_dXmpa - m_dXmpb) / m_dXmpa) + m_dXmpb);
+    dx *= m_dXmpc * GetLongParameter(LP_MAX_Y);
+    return myint(dx>0 ? ceil(dx) : floor(dx)) + iMarginWidth;
   }
 
   inline myint CDasherViewSquare::ymap(myint y) const {
-    if (!GetBoolParameter(BP_NONLINEAR_Y)) return y;
-    if(y > m_Y2)
-      return m_Y2 + (y - m_Y2) / m_Y1;
-    else if(y < m_Y3)
-      return m_Y3 + (y - m_Y3) / m_Y1;
-    else
-      return y;
+    if (GetBoolParameter(BP_NONLINEAR_Y)) {
+      if(y > m_Y2)
+        return m_Y2 + (y - m_Y2) / m_Y1;
+      else if(y < m_Y3)
+        return m_Y3 + (y - m_Y3) / m_Y1;
+    }
+    return y;
   }
 
   inline myint CDasherViewSquare::iymap(myint ydash) const {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]