Clean up in geometry_utils.h
Change-Id: I876bceed12cf533cb29d290fbc05a686f4030579main
parent
64cc10769f
commit
0c2227ab99
|
@ -392,6 +392,8 @@ static inline void prof_out(void) {
|
||||||
template<typename T> inline T min(T a, T b) { return a < b ? a : b; }
|
template<typename T> inline T min(T a, T b) { return a < b ? a : b; }
|
||||||
template<typename T> inline T max(T a, T b) { return a > b ? a : b; }
|
template<typename T> inline T max(T a, T b) { return a > b ? a : b; }
|
||||||
|
|
||||||
|
#define M_PI_F 3.14159265f
|
||||||
|
|
||||||
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
|
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
// The ratio of neutral area radius to sweet spot radius.
|
// The ratio of neutral area radius to sweet spot radius.
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
#define M_PI_F 3.14159265f
|
|
||||||
#define ROUND_FLOAT_10000(f) ((f) < 1000.0f && (f) > 0.001f) \
|
#define ROUND_FLOAT_10000(f) ((f) < 1000.0f && (f) > 0.001f) \
|
||||||
? (floorf((f) * 10000.0f) / 10000.0f) : (f)
|
? (floorf((f) * 10000.0f) / 10000.0f) : (f)
|
||||||
|
|
||||||
|
@ -29,15 +28,6 @@ namespace latinime {
|
||||||
|
|
||||||
static inline float SQUARE_FLOAT(const float x) { return x * x; }
|
static inline float SQUARE_FLOAT(const float x) { return x * x; }
|
||||||
|
|
||||||
static inline float getSquaredDistanceFloat(const float x1, const float y1, const float x2,
|
|
||||||
const float y2) {
|
|
||||||
return SQUARE_FLOAT(x1 - x2) + SQUARE_FLOAT(y1 - y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static AK_FORCE_INLINE int getDistanceInt(const int x1, const int y1, const int x2, const int y2) {
|
|
||||||
return static_cast<int>(hypotf(static_cast<float>(x1 - x2), static_cast<float>(y1 - y2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static AK_FORCE_INLINE float getAngle(const int x1, const int y1, const int x2, const int y2) {
|
static AK_FORCE_INLINE float getAngle(const int x1, const int y1, const int x2, const int y2) {
|
||||||
const int dx = x1 - x2;
|
const int dx = x1 - x2;
|
||||||
const int dy = y1 - y2;
|
const int dy = y1 - y2;
|
||||||
|
@ -54,52 +44,5 @@ static AK_FORCE_INLINE float getAngleDiff(const float a1, const float a2) {
|
||||||
}
|
}
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float pointToLineSegSquaredDistanceFloat(const float x, const float y, const float x1,
|
|
||||||
const float y1, const float x2, const float y2, const bool extend) {
|
|
||||||
const float ray1x = x - x1;
|
|
||||||
const float ray1y = y - y1;
|
|
||||||
const float ray2x = x2 - x1;
|
|
||||||
const float ray2y = y2 - y1;
|
|
||||||
|
|
||||||
const float dotProduct = ray1x * ray2x + ray1y * ray2y;
|
|
||||||
const float lineLengthSqr = SQUARE_FLOAT(ray2x) + SQUARE_FLOAT(ray2y);
|
|
||||||
const float projectionLengthSqr = dotProduct / lineLengthSqr;
|
|
||||||
|
|
||||||
float projectionX;
|
|
||||||
float projectionY;
|
|
||||||
if (!extend && projectionLengthSqr < 0.0f) {
|
|
||||||
projectionX = x1;
|
|
||||||
projectionY = y1;
|
|
||||||
} else if (!extend && projectionLengthSqr > 1.0f) {
|
|
||||||
projectionX = x2;
|
|
||||||
projectionY = y2;
|
|
||||||
} else {
|
|
||||||
projectionX = x1 + projectionLengthSqr * ray2x;
|
|
||||||
projectionY = y1 + projectionLengthSqr * ray2y;
|
|
||||||
}
|
|
||||||
return getSquaredDistanceFloat(x, y, projectionX, projectionY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normal distribution N(u, sigma^2).
|
|
||||||
struct NormalDistribution {
|
|
||||||
public:
|
|
||||||
NormalDistribution(const float u, const float sigma)
|
|
||||||
: mU(u), mSigma(sigma),
|
|
||||||
mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F * SQUARE_FLOAT(sigma))),
|
|
||||||
mPreComputedExponentPart(-1.0f / (2.0f * SQUARE_FLOAT(sigma))) {}
|
|
||||||
|
|
||||||
float getProbabilityDensity(const float x) const {
|
|
||||||
const float shiftedX = x - mU;
|
|
||||||
return mPreComputedNonExpPart * expf(mPreComputedExponentPart * SQUARE_FLOAT(shiftedX));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution);
|
|
||||||
const float mU; // mean value
|
|
||||||
const float mSigma; // standard deviation
|
|
||||||
const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2)
|
|
||||||
const float mPreComputedExponentPart; // = -1 / (2 * sigma^2)
|
|
||||||
}; // struct NormalDistribution
|
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
#endif // LATINIME_GEOMETRY_UTILS_H
|
#endif // LATINIME_GEOMETRY_UTILS_H
|
||||||
|
|
|
@ -140,7 +140,8 @@ float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG(
|
||||||
const float touchX = static_cast<float>(x);
|
const float touchX = static_cast<float>(x);
|
||||||
const float touchY = static_cast<float>(y);
|
const float touchY = static_cast<float>(y);
|
||||||
const float keyWidth = static_cast<float>(getMostCommonKeyWidth());
|
const float keyWidth = static_cast<float>(getMostCommonKeyWidth());
|
||||||
return getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth);
|
return ProximityInfoUtils::getSquaredDistanceFloat(centerX, centerY, touchX, touchY)
|
||||||
|
/ SQUARE_FLOAT(keyWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProximityInfo::getCodePointOf(const int keyIndex) const {
|
int ProximityInfo::getCodePointOf(const int keyIndex) const {
|
||||||
|
@ -163,7 +164,7 @@ void ProximityInfo::initializeG() {
|
||||||
for (int i = 0; i < KEY_COUNT; i++) {
|
for (int i = 0; i < KEY_COUNT; i++) {
|
||||||
mKeyKeyDistancesG[i][i] = 0;
|
mKeyKeyDistancesG[i][i] = 0;
|
||||||
for (int j = i + 1; j < KEY_COUNT; j++) {
|
for (int j = i + 1; j < KEY_COUNT; j++) {
|
||||||
mKeyKeyDistancesG[i][j] = getDistanceInt(
|
mKeyKeyDistancesG[i][j] = ProximityInfoUtils::getDistanceInt(
|
||||||
mCenterXsG[i], mCenterYsG[i], mCenterXsG[j], mCenterYsG[j]);
|
mCenterXsG[i], mCenterYsG[i], mCenterXsG[j], mCenterYsG[j]);
|
||||||
mKeyKeyDistancesG[j][i] = mKeyKeyDistancesG[i][j];
|
mKeyKeyDistancesG[j][i] = mKeyKeyDistancesG[i][j];
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,6 @@ class ProximityInfo {
|
||||||
return MOST_COMMON_KEY_WIDTH_SQUARE;
|
return MOST_COMMON_KEY_WIDTH_SQUARE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getLocaleStr() const {
|
|
||||||
return mLocaleStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getKeyCount() const {
|
int getKeyCount() const {
|
||||||
return KEY_COUNT;
|
return KEY_COUNT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "geometry_utils.h"
|
#include "geometry_utils.h"
|
||||||
#include "proximity_info.h"
|
#include "proximity_info.h"
|
||||||
#include "proximity_info_state.h"
|
#include "proximity_info_state.h"
|
||||||
|
#include "proximity_info_utils.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
|
@ -46,7 +47,6 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
|
||||||
mProximityInfo = proximityInfo;
|
mProximityInfo = proximityInfo;
|
||||||
mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData();
|
mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData();
|
||||||
mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare();
|
mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare();
|
||||||
mLocaleStr = proximityInfo->getLocaleStr();
|
|
||||||
mKeyCount = proximityInfo->getKeyCount();
|
mKeyCount = proximityInfo->getKeyCount();
|
||||||
mCellHeight = proximityInfo->getCellHeight();
|
mCellHeight = proximityInfo->getCellHeight();
|
||||||
mCellWidth = proximityInfo->getCellWidth();
|
mCellWidth = proximityInfo->getCellWidth();
|
||||||
|
@ -324,7 +324,7 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const
|
||||||
if (i < mSampledInputSize - 1 && j >= mInputIndice[i + 1]) {
|
if (i < mSampledInputSize - 1 && j >= mInputIndice[i + 1]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
length += getDistanceInt(xCoordinates[j], yCoordinates[j],
|
length += ProximityInfoUtils::getDistanceInt(xCoordinates[j], yCoordinates[j],
|
||||||
xCoordinates[j + 1], yCoordinates[j + 1]);
|
xCoordinates[j + 1], yCoordinates[j + 1]);
|
||||||
duration += times[j + 1] - times[j];
|
duration += times[j + 1] - times[j];
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: use mLengthCache instead?
|
// TODO: use mLengthCache instead?
|
||||||
length += getDistanceInt(xCoordinates[j], yCoordinates[j],
|
length += ProximityInfoUtils::getDistanceInt(xCoordinates[j], yCoordinates[j],
|
||||||
xCoordinates[j + 1], yCoordinates[j + 1]);
|
xCoordinates[j + 1], yCoordinates[j + 1]);
|
||||||
duration += times[j + 1] - times[j];
|
duration += times[j + 1] - times[j];
|
||||||
}
|
}
|
||||||
|
@ -388,7 +388,8 @@ float ProximityInfoState::calculateBeelineSpeedRate(
|
||||||
while (start > 0 && tempBeelineDistance < lookupRadius) {
|
while (start > 0 && tempBeelineDistance < lookupRadius) {
|
||||||
tempTime += times[start] - times[start - 1];
|
tempTime += times[start] - times[start - 1];
|
||||||
--start;
|
--start;
|
||||||
tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]);
|
tempBeelineDistance = ProximityInfoUtils::getDistanceInt(x0, y0, xCoordinates[start],
|
||||||
|
yCoordinates[start]);
|
||||||
}
|
}
|
||||||
// Exclusive unless this is an edge point
|
// Exclusive unless this is an edge point
|
||||||
if (start > 0 && start < actualInputIndex) {
|
if (start > 0 && start < actualInputIndex) {
|
||||||
|
@ -401,7 +402,8 @@ float ProximityInfoState::calculateBeelineSpeedRate(
|
||||||
while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) {
|
while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) {
|
||||||
tempTime += times[end + 1] - times[end];
|
tempTime += times[end + 1] - times[end];
|
||||||
++end;
|
++end;
|
||||||
tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]);
|
tempBeelineDistance = ProximityInfoUtils::getDistanceInt(x0, y0, xCoordinates[end],
|
||||||
|
yCoordinates[end]);
|
||||||
}
|
}
|
||||||
// Exclusive unless this is an edge point
|
// Exclusive unless this is an edge point
|
||||||
if (end > actualInputIndex && end < (inputSize - 1)) {
|
if (end > actualInputIndex && end < (inputSize - 1)) {
|
||||||
|
@ -419,7 +421,7 @@ float ProximityInfoState::calculateBeelineSpeedRate(
|
||||||
const int y2 = yCoordinates[start];
|
const int y2 = yCoordinates[start];
|
||||||
const int x3 = xCoordinates[end];
|
const int x3 = xCoordinates[end];
|
||||||
const int y3 = yCoordinates[end];
|
const int y3 = yCoordinates[end];
|
||||||
const int beelineDistance = getDistanceInt(x2, y2, x3, y3);
|
const int beelineDistance = ProximityInfoUtils::getDistanceInt(x2, y2, x3, y3);
|
||||||
int adjustedStartTime = times[start];
|
int adjustedStartTime = times[start];
|
||||||
if (start == 0 && actualInputIndex == 0 && inputSize > 1) {
|
if (start == 0 && actualInputIndex == 0 && inputSize > 1) {
|
||||||
adjustedStartTime += FIRST_POINT_TIME_OFFSET_MILLIS;
|
adjustedStartTime += FIRST_POINT_TIME_OFFSET_MILLIS;
|
||||||
|
@ -539,7 +541,8 @@ float ProximityInfoState::getPointScore(
|
||||||
}
|
}
|
||||||
|
|
||||||
const int baseSampleRate = mProximityInfo->getMostCommonKeyWidth();
|
const int baseSampleRate = mProximityInfo->getMostCommonKeyWidth();
|
||||||
const int distPrev = getDistanceInt(mSampledInputXs.back(), mSampledInputYs.back(),
|
const int distPrev = ProximityInfoUtils::getDistanceInt(
|
||||||
|
mSampledInputXs.back(), mSampledInputYs.back(),
|
||||||
mSampledInputXs[size - 2], mSampledInputYs[size - 2]) * DISTANCE_BASE_SCALE;
|
mSampledInputXs[size - 2], mSampledInputYs[size - 2]) * DISTANCE_BASE_SCALE;
|
||||||
float score = 0.0f;
|
float score = 0.0f;
|
||||||
|
|
||||||
|
@ -590,13 +593,15 @@ bool ProximityInfoState::pushTouchPoint(const int inputIndex, const int nodeCode
|
||||||
}
|
}
|
||||||
// Check if the last point should be skipped.
|
// Check if the last point should be skipped.
|
||||||
if (isLastPoint && size > 0) {
|
if (isLastPoint && size > 0) {
|
||||||
if (getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back())
|
if (ProximityInfoUtils::getDistanceInt(x, y, mSampledInputXs.back(),
|
||||||
* LAST_POINT_SKIP_DISTANCE_SCALE < mProximityInfo->getMostCommonKeyWidth()) {
|
mSampledInputYs.back()) * LAST_POINT_SKIP_DISTANCE_SCALE
|
||||||
|
< mProximityInfo->getMostCommonKeyWidth()) {
|
||||||
// This point is not used because it's too close to the previous point.
|
// This point is not used because it's too close to the previous point.
|
||||||
if (DEBUG_GEO_FULL) {
|
if (DEBUG_GEO_FULL) {
|
||||||
AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
|
AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
|
||||||
"width = %d", size, x, y, mSampledInputXs.back(), mSampledInputYs.back(),
|
"width = %d", size, x, y, mSampledInputXs.back(), mSampledInputYs.back(),
|
||||||
getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()),
|
ProximityInfoUtils::getDistanceInt(x, y, mSampledInputXs.back(),
|
||||||
|
mSampledInputYs.back()),
|
||||||
mProximityInfo->getMostCommonKeyWidth()
|
mProximityInfo->getMostCommonKeyWidth()
|
||||||
/ LAST_POINT_SKIP_DISTANCE_SCALE);
|
/ LAST_POINT_SKIP_DISTANCE_SCALE);
|
||||||
}
|
}
|
||||||
|
@ -616,7 +621,7 @@ bool ProximityInfoState::pushTouchPoint(const int inputIndex, const int nodeCode
|
||||||
// Pushing point information.
|
// Pushing point information.
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
mLengthCache.push_back(
|
mLengthCache.push_back(
|
||||||
mLengthCache.back() + getDistanceInt(
|
mLengthCache.back() + ProximityInfoUtils::getDistanceInt(
|
||||||
x, y, mSampledInputXs.back(), mSampledInputYs.back()));
|
x, y, mSampledInputXs.back(), mSampledInputYs.back()));
|
||||||
} else {
|
} else {
|
||||||
mLengthCache.push_back(0);
|
mLengthCache.push_back(0);
|
||||||
|
@ -867,7 +872,8 @@ float ProximityInfoState::getLineToKeyDistance(
|
||||||
const int keyX = mProximityInfo->getKeyCenterXOfKeyIdG(keyId);
|
const int keyX = mProximityInfo->getKeyCenterXOfKeyIdG(keyId);
|
||||||
const int keyY = mProximityInfo->getKeyCenterYOfKeyIdG(keyId);
|
const int keyY = mProximityInfo->getKeyCenterYOfKeyIdG(keyId);
|
||||||
|
|
||||||
return pointToLineSegSquaredDistanceFloat(keyX, keyY, x0, y0, x1, y1, extend);
|
return ProximityInfoUtils::pointToLineSegSquaredDistanceFloat(
|
||||||
|
keyX, keyY, x0, y0, x1, y1, extend);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates probabilities of aligning to some keys and skipping.
|
// Updates probabilities of aligning to some keys and skipping.
|
||||||
|
@ -986,7 +992,8 @@ void ProximityInfoState::updateAlignPointProbabilities(const int start) {
|
||||||
MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
|
MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
|
||||||
const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
|
const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
|
||||||
|
|
||||||
NormalDistribution distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
|
ProximityInfoUtils::NormalDistribution
|
||||||
|
distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
|
||||||
static const float PREV_DISTANCE_WEIGHT = 0.5f;
|
static const float PREV_DISTANCE_WEIGHT = 0.5f;
|
||||||
static const float NEXT_DISTANCE_WEIGHT = 0.6f;
|
static const float NEXT_DISTANCE_WEIGHT = 0.6f;
|
||||||
// Summing up probability densities of all near keys.
|
// Summing up probability densities of all near keys.
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cstring> // for memset()
|
#include <cstring> // for memset()
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "char_utils.h"
|
#include "char_utils.h"
|
||||||
|
@ -55,7 +54,7 @@ class ProximityInfoState {
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
AK_FORCE_INLINE ProximityInfoState()
|
AK_FORCE_INLINE ProximityInfoState()
|
||||||
: mProximityInfo(0), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
|
: mProximityInfo(0), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
|
||||||
mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0), mLocaleStr(),
|
mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0),
|
||||||
mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
|
mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
|
||||||
mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mTimes(),
|
mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mTimes(),
|
||||||
mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache_G(),
|
mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache_G(),
|
||||||
|
@ -262,7 +261,6 @@ class ProximityInfoState {
|
||||||
float mAverageSpeed;
|
float mAverageSpeed;
|
||||||
bool mHasTouchPositionCorrectionData;
|
bool mHasTouchPositionCorrectionData;
|
||||||
int mMostCommonKeyWidthSquare;
|
int mMostCommonKeyWidthSquare;
|
||||||
std::string mLocaleStr;
|
|
||||||
int mKeyCount;
|
int mKeyCount;
|
||||||
int mCellHeight;
|
int mCellHeight;
|
||||||
int mCellWidth;
|
int mCellWidth;
|
||||||
|
|
|
@ -17,9 +17,12 @@
|
||||||
#ifndef LATINIME_PROXIMITY_INFO_UTILS_H
|
#ifndef LATINIME_PROXIMITY_INFO_UTILS_H
|
||||||
#define LATINIME_PROXIMITY_INFO_UTILS_H
|
#define LATINIME_PROXIMITY_INFO_UTILS_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "additional_proximity_chars.h"
|
#include "additional_proximity_chars.h"
|
||||||
#include "char_utils.h"
|
#include "char_utils.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "geometry_utils.h"
|
||||||
#include "hash_map_compat.h"
|
#include "hash_map_compat.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
@ -78,12 +81,69 @@ class ProximityInfoUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE static int getStartIndexFromCoordinates(const int maxProximityCharsSize,
|
static AK_FORCE_INLINE int getStartIndexFromCoordinates(const int maxProximityCharsSize,
|
||||||
const int x, const int y, const int cellHeight, const int cellWidth,
|
const int x, const int y, const int cellHeight, const int cellWidth,
|
||||||
const int gridWidth) {
|
const int gridWidth) {
|
||||||
return ((y / cellHeight) * gridWidth + (x / cellWidth)) * maxProximityCharsSize;
|
return ((y / cellHeight) * gridWidth + (x / cellWidth)) * maxProximityCharsSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline float getSquaredDistanceFloat(const float x1, const float y1, const float x2,
|
||||||
|
const float y2) {
|
||||||
|
return SQUARE_FLOAT(x1 - x2) + SQUARE_FLOAT(y1 - y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AK_FORCE_INLINE int getDistanceInt(const int x1, const int y1, const int x2,
|
||||||
|
const int y2) {
|
||||||
|
return static_cast<int>(hypotf(static_cast<float>(x1 - x2), static_cast<float>(y1 - y2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float pointToLineSegSquaredDistanceFloat(const float x, const float y,
|
||||||
|
const float x1, const float y1, const float x2, const float y2, const bool extend) {
|
||||||
|
const float ray1x = x - x1;
|
||||||
|
const float ray1y = y - y1;
|
||||||
|
const float ray2x = x2 - x1;
|
||||||
|
const float ray2y = y2 - y1;
|
||||||
|
|
||||||
|
const float dotProduct = ray1x * ray2x + ray1y * ray2y;
|
||||||
|
const float lineLengthSqr = SQUARE_FLOAT(ray2x) + SQUARE_FLOAT(ray2y);
|
||||||
|
const float projectionLengthSqr = dotProduct / lineLengthSqr;
|
||||||
|
|
||||||
|
float projectionX;
|
||||||
|
float projectionY;
|
||||||
|
if (!extend && projectionLengthSqr < 0.0f) {
|
||||||
|
projectionX = x1;
|
||||||
|
projectionY = y1;
|
||||||
|
} else if (!extend && projectionLengthSqr > 1.0f) {
|
||||||
|
projectionX = x2;
|
||||||
|
projectionY = y2;
|
||||||
|
} else {
|
||||||
|
projectionX = x1 + projectionLengthSqr * ray2x;
|
||||||
|
projectionY = y1 + projectionLengthSqr * ray2y;
|
||||||
|
}
|
||||||
|
return getSquaredDistanceFloat(x, y, projectionX, projectionY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal distribution N(u, sigma^2).
|
||||||
|
struct NormalDistribution {
|
||||||
|
public:
|
||||||
|
NormalDistribution(const float u, const float sigma)
|
||||||
|
: mU(u), mSigma(sigma),
|
||||||
|
mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F * SQUARE_FLOAT(sigma))),
|
||||||
|
mPreComputedExponentPart(-1.0f / (2.0f * SQUARE_FLOAT(sigma))) {}
|
||||||
|
|
||||||
|
float getProbabilityDensity(const float x) const {
|
||||||
|
const float shiftedX = x - mU;
|
||||||
|
return mPreComputedNonExpPart * expf(mPreComputedExponentPart * SQUARE_FLOAT(shiftedX));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution);
|
||||||
|
const float mU; // mean value
|
||||||
|
const float mSigma; // standard deviation
|
||||||
|
const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2)
|
||||||
|
const float mPreComputedExponentPart; // = -1 / (2 * sigma^2)
|
||||||
|
}; // struct NormalDistribution
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoUtils);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoUtils);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue