[dasher] ScaleFactor and Non-linearity
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher] ScaleFactor and Non-linearity
- Date: Mon, 17 May 2010 11:43:34 +0000 (UTC)
commit 647dfee20b6c4267611e5efa264ca4c4645cc77c
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Fri Jan 8 21:06:49 2010 +0000
ScaleFactor and Non-linearity
*Centralise scale-factor and computation of nonlinearity in SetScaleFactor
*Result for current orientation _only_ in iScalingFactor{X,Y}
*Changed margin to no longer reduce maxX; aspect ratio varies 0.72-1
*New, separate, LP_NONLINEAR_X parameter to control degree of X log-scaling
*Thus BP_NONLINEAR_Y controls Y-axis only => is no longer a misnomer(!)
*Moved tests of nonlinearity into DasherViewSquare::{i,}{x,y}map
*iPhone: replaced BP_NONLINEAR_Y on/off misc setting w/ LP_NONLINEAR_X slider
Src/DasherCore/DasherInterfaceBase.cpp | 1 +
Src/DasherCore/DasherViewSquare.cpp | 124 +++++++++++++++----------------
Src/DasherCore/DasherViewSquare.h | 15 +---
Src/DasherCore/DasherViewSquare.inl | 16 +++--
Src/DasherCore/Parameters.h | 11 ++-
Src/iPhone/Classes/MiscSettings.mm | 2 +-
6 files changed, 83 insertions(+), 86 deletions(-)
---
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index d8b785f..6bedc92 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -327,6 +327,7 @@ void CDasherInterfaceBase::InterfaceEventHandler(Dasher::CEvent *pEvent) {
break;
case LP_MARGIN_WIDTH:
case BP_NONLINEAR_Y:
+ case LP_NONLINEAR_X:
ScheduleRedraw();
break;
case LP_NODE_BUDGET:
diff --git a/Src/DasherCore/DasherViewSquare.cpp b/Src/DasherCore/DasherViewSquare.cpp
index 52f0c0a..9ae0fce 100644
--- a/Src/DasherCore/DasherViewSquare.cpp
+++ b/Src/DasherCore/DasherViewSquare.cpp
@@ -67,12 +67,7 @@ CDasherViewSquare::CDasherViewSquare(CEventHandler *pEventHandler, CSettingsStor
ChangeScreen(DasherScreen);
- // TODO - Make these parameters
- // tweak these if you know what you are doing
- m_dXmpa = 0.2; // these are for the x non-linearity
- m_dXmpb = 0.5;
- m_dXmpc = 0.9;
-
+ //Note, nonlinearity parameters set in SetScaleFactor
m_bVisibleRegionValid = false;
}
@@ -88,10 +83,9 @@ void CDasherViewSquare::HandleEvent(Dasher::CEvent *pEvent) {
Dasher::CParameterNotificationEvent * pEvt(static_cast < Dasher::CParameterNotificationEvent * >(pEvent));
switch (pEvt->m_iParameter) {
case LP_REAL_ORIENTATION:
- m_bVisibleRegionValid = false;
- break;
case LP_MARGIN_WIDTH:
case BP_NONLINEAR_Y:
+ case LP_NONLINEAR_X:
m_bVisibleRegionValid = false;
SetScaleFactor();
break;
@@ -617,11 +611,6 @@ void CDasherViewSquare::Screen2Dasher(screenint iInputX, screenint iInputY, myin
int eOrientation(GetLongParameter(LP_REAL_ORIENTATION));
- myint iScaleFactorX;
- myint iScaleFactorY;
-
- GetScaleFactor(eOrientation, &iScaleFactorX, &iScaleFactorY);
-
switch(eOrientation) {
case Dasher::Opts::LeftToRight:
iDasherX = iCenterX - ( iInputX - iScreenWidth / 2 ) * m_iScalingFactor / iScaleFactorX;
@@ -641,15 +630,22 @@ void CDasherViewSquare::Screen2Dasher(screenint iInputX, screenint iInputY, myin
break;
}
- if (GetBoolParameter(BP_NONLINEAR_Y)) {
- iDasherX = ixmap(iDasherX);
- iDasherY = iymap(iDasherY);
- }
+ iDasherX = ixmap(iDasherX);
+ iDasherY = iymap(iDasherY);
}
void CDasherViewSquare::SetScaleFactor( void )
{
+ //Parameters for X non-linearity.
+ // Set some defaults here, in case we change(d) them later...
+ m_dXmpb = 0.5; //threshold: DasherX's less than (m_dXmpb * MAX_Y) are linear...
+ m_dXmpc = 0.9; //...but multiplied by m_dXmpc; DasherX's above that, are logarithmic...
+
+ //set log scaling coefficient (unused if LP_NONLINEAR_X==0)
+ // note previous value of m_dXmpa = 0.2, i.e. a value of LP_NONLINEAR_X =~= 4.8
+ m_dXmpa = exp(GetLongParameter(LP_NONLINEAR_X)/-3.0);
+
myint iDasherWidth = (myint)GetLongParameter(LP_MAX_Y);
myint iDasherHeight = iDasherWidth;
@@ -661,35 +657,42 @@ void CDasherViewSquare::SetScaleFactor( void )
myint iDasherMargin( GetLongParameter(LP_MARGIN_WIDTH) ); // Make this a parameter
myint iMinX( 0-iDasherMargin );
- myint iMaxX( iDasherWidth - 2*iDasherMargin );
+ myint iMaxX( iDasherWidth );
iCenterX = (iMinX + iMaxX)/2;
myint iMinY( 0 );
myint iMaxY( iDasherHeight );
- double dLRHScaleFactor;
- double dLRVScaleFactor;
- double dTBHScaleFactor;
- double dTBVScaleFactor;
-
- dLRHScaleFactor = iScreenWidth / static_cast<double>( iMaxX - iMinX );
- dLRVScaleFactor = iScreenHeight / static_cast<double>( iMaxY - iMinY );
- dTBHScaleFactor = iScreenWidth / static_cast<double>( iMaxY - iMinY );
- dTBVScaleFactor = iScreenHeight / static_cast<double>( iMaxX - iMinX );
-
- iLRScaleFactorX = myint(std::max(std::min(dLRHScaleFactor, dLRVScaleFactor), dLRHScaleFactor / 4.0) * m_iScalingFactor);
- iLRScaleFactorY = myint(std::max(std::min(dLRHScaleFactor, dLRVScaleFactor), dLRVScaleFactor / 4.0) * m_iScalingFactor);
- iTBScaleFactorX = myint(std::max(std::min(dTBHScaleFactor, dTBVScaleFactor), dTBVScaleFactor / 4.0) * m_iScalingFactor);
- iTBScaleFactorY = myint(std::max(std::min(dTBHScaleFactor, dTBVScaleFactor), dTBHScaleFactor / 4.0) * m_iScalingFactor);
-}
+ Dasher::Opts::ScreenOrientations eOrientation(Dasher::Opts::ScreenOrientations(GetLongParameter(LP_REAL_ORIENTATION)));
+
+ double dScaleFactorX, dScaleFactorY;
+
+ if (eOrientation == Dasher::Opts::LeftToRight || eOrientation == Dasher::Opts::RightToLeft) {
+ dScaleFactorX = iScreenWidth / static_cast<double>( iMaxX - iMinX );
+ dScaleFactorY = iScreenHeight / static_cast<double>( iMaxY - iMinY );
+ } else {
+ dScaleFactorX = iScreenHeight / static_cast<double>( iMaxX - iMinX );
+ dScaleFactorY = iScreenWidth / static_cast<double>( iMaxY - iMinY );
+ }
+
+ if (dScaleFactorX < dScaleFactorY) {
+ //fewer (pixels per dasher coord) in X direction - i.e., X is more compressed.
+ //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;
+ dScaleFactorX /= dMul;
-void CDasherViewSquare::GetScaleFactor( int eOrientation, myint *iScaleFactorX, myint *iScaleFactorY ) {
- if(( eOrientation == Dasher::Opts::LeftToRight ) || ( eOrientation == Dasher::Opts::RightToLeft )) {
- *iScaleFactorX = iLRScaleFactorX;
- *iScaleFactorY = iLRScaleFactorY;
+ iScaleFactorX = myint(dScaleFactorX * m_iScalingFactor);
+ iScaleFactorY = myint(std::max(dScaleFactorX, dScaleFactorY / 4.0) * m_iScalingFactor);
} else {
- *iScaleFactorX = iTBScaleFactorX;
- *iScaleFactorY = iTBScaleFactorY;
+ //X has more room; use Y scale for both -> will get lots history
+ iScaleFactorX = myint(std::max(dScaleFactorY, dScaleFactorX / 4.0) * m_iScalingFactor);
+ iScaleFactorY = myint(dScaleFactorY * m_iScalingFactor);
+ // 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);
}
+ iCenterX *= m_dXmpc;
}
@@ -730,11 +733,9 @@ void CDasherViewSquare::Dasher2Screen(myint iDasherX, myint iDasherY, screenint
// Apply the nonlinearities
- if (GetBoolParameter(BP_NONLINEAR_Y)) {
- iDasherX = xmap(iDasherX);
- iDasherY = ymap(iDasherY);
- }
-
+ iDasherX = xmap(iDasherX);
+ iDasherY = ymap(iDasherY);
+
// Things we're likely to need:
//myint iDasherWidth = (myint)GetLongParameter(LP_MAX_Y);
@@ -745,12 +746,6 @@ void CDasherViewSquare::Dasher2Screen(myint iDasherX, myint iDasherY, screenint
int eOrientation( GetLongParameter(LP_REAL_ORIENTATION) );
- myint iScaleFactorX;
- myint iScaleFactorY;
-
- GetScaleFactor( eOrientation, &iScaleFactorX, &iScaleFactorY);
-
-
// Note that integer division is rounded *away* from zero here to
// ensure that this really is the inverse of the map the other way
// around.
@@ -797,22 +792,23 @@ void CDasherViewSquare::Dasher2Polar(myint iDasherX, myint iDasherY, double &r,
}
void CDasherViewSquare::DasherLine2Screen(myint x1, myint y1, myint x2, myint y2, vector<CDasherScreen::point> &vPoints) {
- if (x1!=x2 && y1!=y2 && GetBoolParameter(BP_NONLINEAR_Y)) {
- //only diagonal lines ever get changed...
- if ((y1 < m_Y3 && y2 > m_Y3) ||(y2 < m_Y3 && y1 > m_Y3)) {
- //crosses bottom non-linearity border
- int x_mid = x1+(x2-x1) * (m_Y3-y1)/(y2-y1);
- DasherLine2Screen(x1, y1, x_mid, m_Y3, vPoints);
- x1=x_mid; y1=m_Y3;
- }//else //no, a single line might cross _both_ borders!
- if ((y1 > m_Y2 && y2 < m_Y2) || (y2 > m_Y2 && y1 < m_Y2)) {
- //crosses top non-linearity border
- int x_mid = x1 + (x2-x1) * (m_Y2-y1)/(y2-y1);
- DasherLine2Screen(x1, y1, x_mid, m_Y2, vPoints);
- x1=x_mid; y1=m_Y2;
+ if (x1!=x2 && y1!=y2) { //only diagonal lines ever get changed...
+ if (GetBoolParameter(BP_NONLINEAR_Y)) {
+ if ((y1 < m_Y3 && y2 > m_Y3) ||(y2 < m_Y3 && y1 > m_Y3)) {
+ //crosses bottom non-linearity border
+ int x_mid = x1+(x2-x1) * (m_Y3-y1)/(y2-y1);
+ DasherLine2Screen(x1, y1, x_mid, m_Y3, vPoints);
+ x1=x_mid; y1=m_Y3;
+ }//else //no, a single line might cross _both_ borders!
+ if ((y1 > m_Y2 && y2 < m_Y2) || (y2 > m_Y2 && y1 < m_Y2)) {
+ //crosses top non-linearity border
+ int x_mid = x1 + (x2-x1) * (m_Y2-y1)/(y2-y1);
+ DasherLine2Screen(x1, y1, x_mid, m_Y2, vPoints);
+ x1=x_mid; y1=m_Y2;
+ }
}
double dMax(static_cast<double>(GetLongParameter(LP_MAX_Y)));
- if (GetBoolParameter(BP_NONLINEAR_Y) && (x1 / dMax > m_dXmpb || x2 / dMax > m_dXmpb)) {
+ if (GetLongParameter(LP_NONLINEAR_X) && (x1 / dMax > m_dXmpb || x2 / dMax > m_dXmpb)) {
//into logarithmic section
CDasherScreen::point pStart, pScreenMid, pEnd;
Dasher2Screen(x2, y2, pEnd.x, pEnd.y);
diff --git a/Src/DasherCore/DasherViewSquare.h b/Src/DasherCore/DasherViewSquare.h
index 81ca815..79140ad 100644
--- a/Src/DasherCore/DasherViewSquare.h
+++ b/Src/DasherCore/DasherViewSquare.h
@@ -174,26 +174,17 @@ private:
void DasherLine2Screen(myint x1, myint y1, myint x2, myint y2, vector<CDasherScreen::point> &vPoints);
- // Called on screen size changes
+ // Called on screen size or orientation changes
void SetScaleFactor();
-
- /// Get the scale factor for conversion between Dasher co-ordinates
- /// and screen co-ordinates
-
- void GetScaleFactor( int eOrientation, myint *iScaleFactorX, myint *iScaleFactorY );
-
-
// Data
double m_dXmpa, m_dXmpb, m_dXmpc;
screenint iCenterX;
// Cached values for scaling
- myint iLRScaleFactorX;
- myint iLRScaleFactorY;
- myint iTBScaleFactorX;
- myint iTBScaleFactorY;
+ myint iScaleFactorX;
+ myint iScaleFactorY;
// The factor that scale factors are multipled by
myint m_iScalingFactor;
diff --git a/Src/DasherCore/DasherViewSquare.inl b/Src/DasherCore/DasherViewSquare.inl
index 99856bc..446ffd4 100644
--- a/Src/DasherCore/DasherViewSquare.inl
+++ b/Src/DasherCore/DasherViewSquare.inl
@@ -45,6 +45,7 @@ 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;
@@ -55,6 +56,7 @@ namespace Dasher {
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;
@@ -64,6 +66,7 @@ namespace Dasher {
}
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)
@@ -73,11 +76,12 @@ namespace Dasher {
}
inline myint CDasherViewSquare::iymap(myint ydash) const {
- if(ydash > m_Y2)
- return (ydash - m_Y2) * m_Y1 + m_Y2;
- else if(ydash < m_Y3)
- return (ydash - m_Y3) * m_Y1 + m_Y3;
- else
- return ydash;
+ if (GetBoolParameter(BP_NONLINEAR_Y)) {
+ if(ydash > m_Y2)
+ return (ydash - m_Y2) * m_Y1 + m_Y2;
+ else if(ydash < m_Y3)
+ return (ydash - m_Y3) * m_Y1 + m_Y3;
+ }
+ return ydash;
}
}
diff --git a/Src/DasherCore/Parameters.h b/Src/DasherCore/Parameters.h
index a7436a2..1dbebb3 100644
--- a/Src/DasherCore/Parameters.h
+++ b/Src/DasherCore/Parameters.h
@@ -57,7 +57,7 @@ enum {
LP_LM_MIXTURE, LP_MOUSE_POS_BOX, LP_NORMALIZATION, LP_LINE_WIDTH,
LP_LM_WORD_ALPHA, LP_USER_LOG_LEVEL_MASK,
LP_ZOOMSTEPS, LP_B, LP_S, LP_BUTTON_SCAN_TIME, LP_R, LP_RIGHTZOOM,
- LP_NODE_BUDGET,
+ LP_NODE_BUDGET, LP_NONLINEAR_X,
LP_BOOSTFACTOR, LP_AUTOSPEED_SENSITIVITY, LP_SOCKET_PORT, LP_SOCKET_INPUT_X_MIN, LP_SOCKET_INPUT_X_MAX,
LP_SOCKET_INPUT_Y_MIN, LP_SOCKET_INPUT_Y_MAX, LP_OX, LP_OY, LP_MAX_Y, LP_INPUT_FILTER,
LP_CIRCLE_PERCENT, LP_TWO_BUTTON_OFFSET, LP_HOLD_TIME, LP_MULTIPRESS_TIME,
@@ -154,7 +154,7 @@ static bp_table boolparamtable[] = {
{BP_SOCKET_DEBUG, "SocketInputDebug", PERS, false, "Print information about socket input processing to console"},
{BP_CIRCLE_START, "CircleStart", PERS, false, "Start on circle mode"},
{BP_GLOBAL_KEYBOARD, "GlobalKeyboard", PERS, false, "Whether to assume global control of the keyboard"},
-#if defined(WITH_MAEMO) || defined(TARGET_OS_IPHONE)
+#ifdef WITH_MAEMO
{BP_NONLINEAR_Y, "NonlinearY", PERS, false, "Apply nonlinearities to Y axis (i.e. compress top & bottom)"},
#else
{BP_NONLINEAR_Y, "NonlinearY", PERS, true, "Apply nonlinearities to Y axis (i.e. compress top & bottom)"},
@@ -209,11 +209,16 @@ static lp_table longparamtable[] = {
#endif
{LP_R, "ButtonModeNonuniformity", PERS, 0, "Button mode box non-uniformity"},
{LP_RIGHTZOOM, "ButtonCompassModeRightZoom", PERS, 5120, "Zoomfactor (*1024) for compass mode"},
-#ifdef TARGET_OS_IPHONE
+#if defined(WITH_MAEMO) || defined (TARGET_OS_IPHONE)
{LP_NODE_BUDGET, "NodeBudget", PERS, 1000, "Target (min) number of node objects to maintain"},
#else
{LP_NODE_BUDGET, "NodeBudget", PERS, 3000, "Target (min) number of node objects to maintain"},
#endif
+#ifdef WITH_MAEMO
+ {LP_NONLINEAR_X, "NonLinearX", PERS, 0, "Nonlinear compression of X-axis (0 = none, higher = more extreme)"},
+#else
+ {LP_NONLINEAR_X, "NonLinearX", PERS, 5, "Nonlinear compression of X-axis (0 = none, higher = more extreme)"},
+#endif
{LP_BOOSTFACTOR, "BoostFactor", !PERS, 100, "Boost/brake factor (multiplied by 100)"},
{LP_AUTOSPEED_SENSITIVITY, "AutospeedSensitivity", PERS, 100, "Sensitivity of automatic speed control (percent)"},
{LP_SOCKET_PORT, "SocketPort", PERS, 20320, "UDP/TCP socket to use for network socket input"},
diff --git a/Src/iPhone/Classes/MiscSettings.mm b/Src/iPhone/Classes/MiscSettings.mm
index 4593f88..43f9c01 100644
--- a/Src/iPhone/Classes/MiscSettings.mm
+++ b/Src/iPhone/Classes/MiscSettings.mm
@@ -15,7 +15,7 @@ static SModuleSettings _settings[] = { //note iStep and string description are i
{LP_NODE_BUDGET, T_LONG, 400, 10000, 1, 0, ""}, //hopefully appropriate for an iPhone 3GS?
{LP_MARGIN_WIDTH, T_LONG, 100, 900, 1, 0, ""},
{BP_AUTO_SPEEDCONTROL, T_BOOL, -1, -1, -1, -1, ""},
- {BP_NONLINEAR_Y, T_BOOL, -1, -1, -1, -1, ""},
+ {LP_NONLINEAR_X, T_LONG, 0, 10, 1, -1, ""},
{BP_DOUBLE_X, T_BOOL, -1, -1, -1, -1, ""},
};
static int _count = sizeof(_settings) / sizeof(_settings[0]);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]