Remove bounding-box normalization — compare paths in original dp space
CI / Core C++ Tests (push) Has been cancelled
CI / Android Build (push) Has been cancelled
CI / NDK ABI Build (arm64-v8a) (push) Has been cancelled
CI / NDK ABI Build (armeabi-v7a) (push) Has been cancelled
CI / NDK ABI Build (x86_64) (push) Has been cancelled

This commit is contained in:
2026-07-07 03:40:58 -04:00
parent b4d2f26319
commit e4aef2faaa
2 changed files with 9 additions and 50 deletions
+3 -24
View File
@@ -69,31 +69,12 @@ struct IdealPathGenerator::Impl {
return result;
}
// Normalize to [0,1] bounding box
// Keep coordinates in original dp space
static GesturePath normalizeBB(const std::vector<GesturePoint>& points, float arcLen) {
GesturePath result;
if (points.empty()) return result;
float minX = points[0].x, maxX = points[0].x;
float minY = points[0].y, maxY = points[0].y;
for (const auto& p : points) {
minX = std::min(minX, p.x);
maxX = std::max(maxX, p.x);
minY = std::min(minY, p.y);
maxY = std::max(maxY, p.y);
}
float width = maxX - minX;
float height = maxY - minY;
if (width < 0.001f && height < 0.001f) {
result.points.assign(points.size(), NormalizedPoint(0.5f, 0.5f, 0.5f));
result.aspectRatio = 1.0f;
result.totalArcLength = arcLen;
return result;
}
float scale = std::max(width, height);
result.aspectRatio = (height > 0.001f) ? (width / height) : 1.0f;
result.aspectRatio = 1.0f;
result.totalArcLength = arcLen;
int64_t firstTs = points.front().timestamp;
@@ -102,12 +83,10 @@ struct IdealPathGenerator::Impl {
result.points.reserve(points.size());
for (const auto& p : points) {
float nx = (p.x - minX) / scale;
float ny = (p.y - minY) / scale;
float nt = (tsRange > 0.0f)
? static_cast<float>(p.timestamp - firstTs) / tsRange
: 0.5f;
result.points.emplace_back(nx, ny, nt);
result.points.emplace_back(p.x, p.y, nt);
}
return result;
}
+6 -26
View File
@@ -114,7 +114,10 @@ struct PathProcessor::Impl {
}
/**
* Normalize coordinates to [0,1] bounding box preserving aspect ratio.
* Keep coordinates in original dp space — no bounding-box normalization.
* The gesture and ideal paths naturally share the same coordinate space
* (both derived from the same KeyboardLayout), so DTW on absolute
* positions correctly measures spatial distance on the keyboard.
*/
GesturePath normalizeBoundingBox(const std::vector<GesturePoint>& points,
float totalArcLength) const {
@@ -122,28 +125,7 @@ struct PathProcessor::Impl {
if (points.empty()) return result;
float minX = points[0].x, maxX = points[0].x;
float minY = points[0].y, maxY = points[0].y;
for (const auto& p : points) {
minX = std::min(minX, p.x);
maxX = std::max(maxX, p.x);
minY = std::min(minY, p.y);
maxY = std::max(maxY, p.y);
}
float width = maxX - minX;
float height = maxY - minY;
// Degenerate: near-point path
if (width < 0.001f && height < 0.001f) {
result.points.resize(points.size(), NormalizedPoint(0.5f, 0.5f, 0.5f));
result.aspectRatio = 1.0f;
result.totalArcLength = totalArcLength;
return result;
}
float scale = std::max(width, height);
result.aspectRatio = (height > 0.001f) ? (width / height) : 1.0f;
result.aspectRatio = 1.0f;
result.totalArcLength = totalArcLength;
int64_t firstTs = points.front().timestamp;
@@ -152,12 +134,10 @@ struct PathProcessor::Impl {
result.points.reserve(points.size());
for (const auto& p : points) {
float nx = (p.x - minX) / scale;
float ny = (p.y - minY) / scale;
float nt = (tsRange > 0.0f)
? static_cast<float>(p.timestamp - firstTs) / tsRange
: 0.5f;
result.points.emplace_back(nx, ny, nt);
result.points.emplace_back(p.x, p.y, nt);
}
return result;