Fix one dollar recognizer implementation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#include "UniStrokePoint.h"
|
||||
|
||||
#include "ScreenPass.h"
|
||||
#include "WizardingCentral/Logger/LogLumiCharacter.h"
|
||||
|
||||
FUniStrokePoint::FUniStrokePoint()
|
||||
{
|
||||
@@ -49,9 +49,7 @@ FUniStrokePoint::BoundingBox(const TArray<FUniStrokePoint>& Points)
|
||||
{
|
||||
// Edge case
|
||||
if (Points.Num() == 0)
|
||||
{
|
||||
return FUniStrokeRectangle();
|
||||
}
|
||||
|
||||
float MinX = Points[0].X;
|
||||
float MinY = Points[0].Y;
|
||||
@@ -86,14 +84,16 @@ FUniStrokePoint::Vectorize(const TArray<FUniStrokePoint>& Points)
|
||||
const float Magnitude = FMath::Sqrt(Sum);
|
||||
|
||||
for (float& V : Vector)
|
||||
{
|
||||
V /= Magnitude;
|
||||
}
|
||||
|
||||
return Vector;
|
||||
}
|
||||
|
||||
// TODO: Proofread this function
|
||||
FString FUniStrokePoint::ToString() const
|
||||
{
|
||||
return FString::Printf(TEXT("X=%.3f Y=%.3f"), X, Y);
|
||||
}
|
||||
|
||||
float
|
||||
FUniStrokePoint::OptimalCosineDistance(const TArray<float>& VectorA,
|
||||
const TArray<float>& VectorB)
|
||||
@@ -173,9 +173,7 @@ FUniStrokePoint::Resample(TArray<FUniStrokePoint>& Points,
|
||||
|
||||
// Edge case
|
||||
if (Points.Num() == Num - 1)
|
||||
{
|
||||
Points.Add(OldPoints.Last());
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
@@ -385,9 +383,7 @@ FUniStrokePoint::PathDistance(const TArray<FUniStrokePoint>& PathA,
|
||||
{
|
||||
// Edge case: Different number of points
|
||||
if (PathA.Num() != PathB.Num())
|
||||
{
|
||||
return TNumericLimits<float>::Max();
|
||||
}
|
||||
|
||||
// d <- 0
|
||||
float d = 0;
|
||||
|
||||
@@ -84,6 +84,9 @@ struct WIZARDINGCENTRAL_API FUniStrokePoint
|
||||
static TArray<float>
|
||||
Vectorize(const TArray<FUniStrokePoint>& Points);
|
||||
|
||||
FString
|
||||
ToString() const;
|
||||
|
||||
private:
|
||||
float X;
|
||||
float Y;
|
||||
|
||||
@@ -12,16 +12,13 @@ FUniStrokeRecognizer::~FUniStrokeRecognizer()
|
||||
|
||||
// TODO: Review this function
|
||||
FUniStrokeResult
|
||||
FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints,
|
||||
const bool& UseProtractor)
|
||||
FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints)
|
||||
{
|
||||
TArray<FUniStrokePoint> Points = FUniStrokePoint::From(VectorPoints);
|
||||
|
||||
// Edge case: Not enough points
|
||||
if (Points.Num() < 2 || FUniStrokePoint::PathLength(Points) < 100.0f)
|
||||
{
|
||||
return FUniStrokeResult("Too few points made", 0.0);
|
||||
}
|
||||
|
||||
const FUniStrokeTemplate Candidate = FUniStrokeTemplate("", Points);
|
||||
int TemplateIndex = -1;
|
||||
@@ -33,18 +30,13 @@ FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints,
|
||||
for (int i = 0; i < Templates.Num(); i++)
|
||||
{
|
||||
// d <- DistanceAtBestAngle(points, T, -theta, theta, threshold)
|
||||
const float d = UseProtractor
|
||||
? FUniStrokePoint::OptimalCosineDistance(
|
||||
Templates[i].Vector,
|
||||
Candidate.Vector
|
||||
)
|
||||
: FUniStrokePoint::DistanceAtBestAngle(
|
||||
Candidate.Points,
|
||||
Templates[i].Points,
|
||||
-AngleRange,
|
||||
AngleRange,
|
||||
AnglePrecision
|
||||
);
|
||||
const float d = FUniStrokePoint::DistanceAtBestAngle(
|
||||
Candidate.Points,
|
||||
Templates[i].Points,
|
||||
-AngleRange,
|
||||
AngleRange,
|
||||
AnglePrecision
|
||||
);
|
||||
|
||||
// if d < b then
|
||||
if (d < b)
|
||||
@@ -57,7 +49,8 @@ FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints,
|
||||
}
|
||||
|
||||
// score <- 1 – b / 0.5 sqrt(size^2 + size^2)
|
||||
const float Score = UseProtractor ? 1.0 - b : 1.0 - b / HalfDiagonal;
|
||||
static const float HalfDiagonal = 0.5 * FMath::Sqrt(2 * FMath::Square(SquareSize));
|
||||
const float Score = 1.0 - b / HalfDiagonal;
|
||||
|
||||
// return <T', score>
|
||||
return TemplateIndex == -1
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "UniStrokeRecognizer.generated.h"
|
||||
|
||||
static constexpr int NumTemplates = 16;
|
||||
static const float Diagonal = FMath::Sqrt(2 * FMath::Square(SquareSize));
|
||||
static const float HalfDiagonal = 0.5 * Diagonal;
|
||||
static constexpr float AngleRange = FMath::DegreesToRadians(45.0);
|
||||
static constexpr float AnglePrecision = FMath::DegreesToRadians(2.0);
|
||||
|
||||
@@ -22,7 +20,7 @@ struct WIZARDINGCENTRAL_API FUniStrokeRecognizer
|
||||
~FUniStrokeRecognizer();
|
||||
|
||||
FUniStrokeResult
|
||||
Recognize(const TArray<FVector2D>& VectorPoints, const bool& UseProtractor);
|
||||
Recognize(const TArray<FVector2D>& VectorPoints);
|
||||
|
||||
void
|
||||
AddTemplate(const FString& Name, const TArray<FVector2D>& VectorPoints);
|
||||
|
||||
@@ -8,7 +8,7 @@ FUniStrokeTemplate::FUniStrokeTemplate()
|
||||
}
|
||||
|
||||
FUniStrokeTemplate::FUniStrokeTemplate(const FString& Name,
|
||||
const TArray<FUniStrokePoint>)
|
||||
const TArray<FUniStrokePoint>& Points)
|
||||
{
|
||||
this->Name = Name;
|
||||
this->Points = Points;
|
||||
|
||||
@@ -16,7 +16,7 @@ struct WIZARDINGCENTRAL_API FUniStrokeTemplate
|
||||
|
||||
FUniStrokeTemplate();
|
||||
FUniStrokeTemplate(const FString& Name,
|
||||
const TArray<FUniStrokePoint>);
|
||||
const TArray<FUniStrokePoint>& Points);
|
||||
~FUniStrokeTemplate();
|
||||
|
||||
FString Name;
|
||||
|
||||
Reference in New Issue
Block a user