summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-12-16 11:58:02 +0100
committerStanislaw Halik <sthalik@misaki.pl>2016-12-16 11:58:02 +0100
commit8cd2a4ee13a086759740dde22d03ab281fa55886 (patch)
treebc5f7ffab761ee5769aeb99b5fec27ce43be4c2a
parentd37bed91649d2acdd9a548cd52730a87d0a28d6d (diff)
tracker/tobii: flush, but still broken
Needs the spline class to allow initializing itself from a function. Even if the passed control points are correct, it still looks like shit. Presently they aren't correct though. Need to work on linear approximation.
-rw-r--r--tracker-tobii-eyex/tobii-eyex-dialog.cpp2
-rw-r--r--tracker-tobii-eyex/tobii-eyex-dialog.ui195
-rw-r--r--tracker-tobii-eyex/tobii-settings.cpp74
-rw-r--r--tracker-tobii-eyex/tobii-settings.hpp5
4 files changed, 106 insertions, 170 deletions
diff --git a/tracker-tobii-eyex/tobii-eyex-dialog.cpp b/tracker-tobii-eyex/tobii-eyex-dialog.cpp
index 0388ddfb..8997c6c2 100644
--- a/tracker-tobii-eyex/tobii-eyex-dialog.cpp
+++ b/tracker-tobii-eyex/tobii-eyex-dialog.cpp
@@ -20,9 +20,7 @@ tobii_eyex_dialog::tobii_eyex_dialog()
tie_setting(rs.expt_len, ui.exponent_len);
tie_setting(rs.expt_norm, ui.exponent_norm);
- tie_setting(rs.log_slope, ui.log_base);
tie_setting(rs.log_len, ui.log_len);
- tie_setting(rs.log_norm, ui.log_norm);
connect(rs.b.get(), &bundle_::changed, this, [this]() { rs.make_spline(); }, Qt::QueuedConnection);
diff --git a/tracker-tobii-eyex/tobii-eyex-dialog.ui b/tracker-tobii-eyex/tobii-eyex-dialog.ui
index 1e622f93..b6138514 100644
--- a/tracker-tobii-eyex/tobii-eyex-dialog.ui
+++ b/tracker-tobii-eyex/tobii-eyex-dialog.ui
@@ -192,19 +192,22 @@
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QLabel" name="speed_label">
- <property name="minimumSize">
- <size>
- <width>24</width>
- <height>0</height>
- </size>
+ <item row="1" column="2">
+ <widget class="QSlider" name="deadzone">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="text">
- <string>0</string>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ <property name="tickPosition">
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ <property name="tickInterval">
+ <number>25</number>
</property>
</widget>
</item>
@@ -224,25 +227,6 @@
</property>
</widget>
</item>
- <item row="1" column="2">
- <widget class="QSlider" name="deadzone">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksAbove</enum>
- </property>
- <property name="tickInterval">
- <number>25</number>
- </property>
- </widget>
- </item>
<item row="2" column="2">
<widget class="QSlider" name="exponent">
<property name="sizePolicy">
@@ -262,8 +246,8 @@
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QLabel" name="deadzone_label">
+ <item row="0" column="1">
+ <widget class="QLabel" name="speed_label">
<property name="minimumSize">
<size>
<width>24</width>
@@ -291,6 +275,22 @@
</property>
</widget>
</item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="deadzone_label">
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
@@ -333,19 +333,6 @@
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_5">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Exponent segment length</string>
- </property>
- </widget>
- </item>
<item row="5" column="2">
<widget class="QSlider" name="log_len">
<property name="sizePolicy">
@@ -365,8 +352,8 @@
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_9">
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -374,42 +361,7 @@
</sizepolicy>
</property>
<property name="text">
- <string>Log slope</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QLabel" name="log_base_label">
- <property name="minimumSize">
- <size>
- <width>24</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>0</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="6" column="2">
- <widget class="QSlider" name="log_base">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksAbove</enum>
- </property>
- <property name="tickInterval">
- <number>25</number>
+ <string>Exponent segment length</string>
</property>
</widget>
</item>
@@ -448,19 +400,6 @@
</property>
</widget>
</item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Exponent norm</string>
- </property>
- </widget>
- </item>
<item row="4" column="2">
<widget class="QSlider" name="exponent_norm">
<property name="sizePolicy">
@@ -480,6 +419,19 @@
</property>
</widget>
</item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Exponent norm</string>
+ </property>
+ </widget>
+ </item>
<item row="3" column="2">
<widget class="QSlider" name="exponent_len">
<property name="sizePolicy">
@@ -515,53 +467,18 @@
</property>
</widget>
</item>
- <item row="7" column="1">
- <widget class="QLabel" name="log_norm_label">
- <property name="minimumSize">
+ <item row="6" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
<size>
- <width>24</width>
+ <width>20</width>
<height>0</height>
</size>
</property>
- <property name="text">
- <string>0</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="7" column="2">
- <widget class="QSlider" name="log_norm">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksAbove</enum>
- </property>
- <property name="tickInterval">
- <number>25</number>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_12">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Log norm</string>
- </property>
- </widget>
+ </spacer>
</item>
</layout>
</widget>
diff --git a/tracker-tobii-eyex/tobii-settings.cpp b/tracker-tobii-eyex/tobii-settings.cpp
index fb5bb8f6..0dcb377f 100644
--- a/tracker-tobii-eyex/tobii-settings.cpp
+++ b/tracker-tobii-eyex/tobii-settings.cpp
@@ -28,14 +28,45 @@
void rel_settings::make_spline()
{
- const double log_c = 1./std::log(log_slope());
+ const double dz_len_ = dz_len(),
+ expt_len_ = expt_len(),
+ expt_norm_ = expt_norm(),
+ expt_slope_ = expt_slope(),
+ log_len_ = log_len();
+
+ const double expt_deriv_at_end = expt_norm_ * expt_slope_ * std::pow(expt_len_, expt_slope_ - 1); // cnx^(n-1)
+ const double expt_at_end = expt_norm_ * std::pow(expt_len_, expt_slope_); // cx^n
+
+ const double lin_len = 1 - dz_len_ - expt_len_ - log_len_;
+
+ // this isn't correct but works.
+ // we use exponentiation of the linear part to get logarithmic approximation of the linear
+ // part rather than linear approximation of the linear part
+
+ const double lin_at_end = std::pow(M_E, lin_len * expt_deriv_at_end - expt_at_end); // e^(cx + a)
+ const double lin_deriv_at_end = expt_deriv_at_end * std::exp(-expt_at_end + expt_deriv_at_end * lin_len); // ce^(a + cx)
+
+ // this was all derived by the awesome linear approximation
+ // calculator <http://www.emathhelp.net/calculators/calculus-1/linear-approximation-calculator/>
+
+ auto expt_part = [=](double x) { return expt_norm_ * std::pow(x, expt_slope_); };
+ const double expt_inv_norm = expt_norm_/expt_part(expt_len_);
+
+ auto lin_part = [=](double x) { return expt_inv_norm * (expt_at_end + expt_deriv_at_end * (x - expt_len_)); };
+ const double lin_inv_norm = (1 - expt_norm_ - .25)/lin_part(lin_len);
+
+ // TODO needs norm for log/lin parts
+ auto log_part = [=](double x) { return expt_inv_norm * lin_inv_norm * std::log(lin_at_end + lin_deriv_at_end * (x - lin_len)); };
+ const double log_inv_norm = .25/log_part(expt_len_);
+
+ qDebug() << "lin" << expt_deriv_at_end << lin_inv_norm;
part functors[]
{
- { 1, dz_len(), 0, [](double) { return 0; } },
- { 5, expt_len(), expt_norm(), [=](double x) { return std::pow(x, expt_slope()); } },
- { 7, 1 - dz_len() - expt_len() - log_len(), std::max(0., 1 - expt_norm() - log_norm()), [](double x) { return x; } },
- { 7, log_len(), log_norm(), [=](double x) { return std::log(1+x)*log_c; } },
+ { dz_len_, [](double) { return 0; } },
+ { expt_len_, [=](double x) { return expt_inv_norm * expt_part(x); } }, // cx^n
+ { lin_len, [=](double x) { return lin_inv_norm * lin_part(x); } }, // cx + a
+ { log_len_, [=](double x) { return log_inv_norm * log_part(x); } }, // ln(cx + a)
};
make_spline_(functors, std::distance(std::begin(functors), std::end(functors)));
@@ -45,12 +76,10 @@ rel_settings::rel_settings() :
opts("tobii-eyex-relative-mode"),
speed(b, "speed", s(3, .1, 10)),
dz_len(b, "deadzone-length", s(.04, 0, .2)),
- expt_slope(b, "exponent-slope", s(1.75, 1.25, 3)),
- expt_len(b, "exponent-length", s(.25, 0, .5)),
- expt_norm(b, "exponent-norm", s(.3, .1, .5)),
- log_slope(b, "log-slope", s(2.75, 1.25, 10)),
+ expt_slope(b, "exponent-slope", s(1.75, 1.5, 3)),
+ expt_len(b, "exponent-length", s(.2, 0, .5)),
+ expt_norm(b, "exponent-norm", s(.4, .1, .5)),
log_len(b, "log-len", s(.1, 0, .2)),
- log_norm(b, "log-norm", s(.1, .05, .3)),
acc_mode_spline(100, 100, "")
{
make_spline();
@@ -68,30 +97,23 @@ void rel_settings::make_spline_(part* functors, unsigned len)
{
acc_mode_spline.removeAllPoints();
- double lastx = 0, lasty = 0;
-
- using std::accumulate;
-
- const double inv_norm_y = 1./accumulate(functors, functors + len, 1e-4, [](double acc, const part& functor) { return acc + functor.norm; });
- const double inv_norm_x = 1./accumulate(functors, functors + len, 1e-4, [](double acc, const part& functor) { return acc + functor.len; });
+ double lastx = 0;
for (unsigned k = 0; k < len; k++)
{
part& fun = functors[k];
- const double xscale = fun.len * spline_max * inv_norm_x;
- const double maxx = fun.f(1);
- const double yscale = fun.norm * spline_max * inv_norm_y * (maxx < 1e-3 ? 0 : 1./maxx);
+ static constexpr unsigned nparts = 7;
- for (unsigned i = 0; i <= fun.nparts; i++)
+ for (unsigned i = 1; i <= nparts; i++)
{
- const double x = lastx + (fun.nparts == 0 ? 1 : i) / (1.+fun.nparts) * xscale;
- const double y = lasty + clamp(fun.f(x) * yscale, 0, spline_max);
- qDebug() << k << i << x << y;
- acc_mode_spline.addPoint(x, y);
+ const double x = i*fun.len/nparts;
+ const double y = clamp(fun.f(x), 0, 1);
+ if (i == nparts/2)
+ qDebug() << k << i << x << y;
+ acc_mode_spline.addPoint((lastx + x) * spline_max, y * spline_max);
}
- lastx += xscale;
- lasty += yscale;
+ lastx += fun.len;
}
}
diff --git a/tracker-tobii-eyex/tobii-settings.hpp b/tracker-tobii-eyex/tobii-settings.hpp
index 4346a156..5c09b201 100644
--- a/tracker-tobii-eyex/tobii-settings.hpp
+++ b/tracker-tobii-eyex/tobii-settings.hpp
@@ -24,8 +24,7 @@ class rel_settings final : public QObject, public opts
struct part
{
- int nparts;
- double len, norm;
+ double len;
functor f;
};
@@ -33,7 +32,7 @@ class rel_settings final : public QObject, public opts
public:
using s = slider_value;
- value<slider_value> speed, dz_len, expt_slope, expt_len, expt_norm, log_slope, log_len, log_norm;
+ value<slider_value> speed, dz_len, expt_slope, expt_len, expt_norm, log_len;
spline acc_mode_spline;
rel_settings();
double gain(double value);