Commit fe5983e9 authored by Rob Schonberger's avatar Rob Schonberger Committed by Commit Bot

Implement Centroid calculation using a Kahan sum. Makes calc O(1).

This modifies Centroid calculation to be O(1) when calculating a
centroid of a stroke. Centroid fetching/checking happens a lot, so
it's worthwhile to optimize.

Nevertheless this is still a heavy O(1) - so alternatives are happily
considered.

Bug: 1009290
Change-Id: Ia421502c1cdf5e37bd5c6f80dc4f866af2119b7f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1880237Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Commit-Queue: Rob Schonberger <robsc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709777}
parent b3932680
...@@ -91,22 +91,27 @@ void PalmFilterStroke::AddSample(const PalmFilterSample& sample) { ...@@ -91,22 +91,27 @@ void PalmFilterStroke::AddSample(const PalmFilterSample& sample) {
} }
DCHECK_EQ(tracking_id_, sample.tracking_id); DCHECK_EQ(tracking_id_, sample.tracking_id);
samples_.push_back(sample); samples_.push_back(sample);
AddToUnscaledCentroid(sample.point.OffsetFromOrigin());
while (samples_.size() > max_length_) { while (samples_.size() > max_length_) {
AddToUnscaledCentroid(-samples_.front().point.OffsetFromOrigin());
samples_.pop_front(); samples_.pop_front();
} }
} }
void PalmFilterStroke::AddToUnscaledCentroid(const gfx::Vector2dF point) {
const gfx::Vector2dF corrected_point = point - unscaled_centroid_sum_error_;
const gfx::PointF new_unscaled_centroid =
unscaled_centroid_ + corrected_point;
unscaled_centroid_sum_error_ =
(new_unscaled_centroid - unscaled_centroid_) - corrected_point;
unscaled_centroid_ = new_unscaled_centroid;
}
gfx::PointF PalmFilterStroke::GetCentroid() const { gfx::PointF PalmFilterStroke::GetCentroid() const {
// TODO(robsc): Implement a Kahan sum to accurately track running sum instead
// of brute force.
if (samples_.size() == 0) { if (samples_.size() == 0) {
return gfx::PointF(0., 0.); return gfx::PointF(0., 0.);
} }
gfx::PointF unscaled_centroid; return gfx::ScalePoint(unscaled_centroid_, 1.f / samples_.size());
for (const auto& sample : samples_) {
unscaled_centroid += sample.point.OffsetFromOrigin();
}
return gfx::ScalePoint(unscaled_centroid, 1.f / samples_.size());
} }
const std::deque<PalmFilterSample>& PalmFilterStroke::samples() const { const std::deque<PalmFilterSample>& PalmFilterStroke::samples() const {
......
...@@ -65,10 +65,16 @@ class EVENTS_OZONE_EVDEV_EXPORT PalmFilterStroke { ...@@ -65,10 +65,16 @@ class EVENTS_OZONE_EVDEV_EXPORT PalmFilterStroke {
int tracking_id() const; int tracking_id() const;
private: private:
void AddToUnscaledCentroid(const gfx::Vector2dF point);
std::deque<PalmFilterSample> samples_; std::deque<PalmFilterSample> samples_;
int tracking_id_ = 0; int tracking_id_ = 0;
uint64_t samples_seen_ = 0; uint64_t samples_seen_ = 0;
uint64_t max_length_; uint64_t max_length_;
gfx::PointF unscaled_centroid_ = gfx::PointF(0., 0.);
// Used in part of the kahan summation.
gfx::Vector2dF unscaled_centroid_sum_error_ =
gfx::PointF(0., 0.).OffsetFromOrigin();
}; };
} // namespace ui } // namespace ui
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment