Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions src/core/path_coord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,12 +383,15 @@ SplitPathCoord SplitPathCoord::at(
length_type length,
const SplitPathCoord& first )
{
auto& path_coords = *first.path_coords;
auto& coords = path_coords.coords();
auto& flags = path_coords.flags();
const auto& path_coords = *first.path_coords;
const auto& coords = path_coords.coords();
const auto& flags = path_coords.flags();

SplitPathCoord split = first;
split.path_coord_index = path_coords.upperBound(length, first.path_coord_index, first.path_coords->size()-1);
if (length > first.clen)
{
split.path_coord_index = path_coords.upperBound(length, first.path_coord_index, first.path_coords->size()-1);
}
Comment on lines -391 to +394
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix for monotony.

if (split.path_coord_index > first.path_coord_index)
{
// New path coordinate, really
Expand All @@ -403,10 +406,12 @@ SplitPathCoord SplitPathCoord::at(

auto factor = 1.0f;
if (qFuzzyCompare(1.0f + length, 1.0f + current_coord.clen) ||
qFuzzyCompare(1.0f + curve_length, 1.0f))
qFuzzyCompare(1.0f + curve_length, 1.0f) ||
length > current_coord.clen)
{
// Close match at current path coordinate,
// or near-zero curve length.
// or near-zero curve length,
// or length exceeding path length.
Comment on lines 408 to +414
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix for upper bound.

split.pos = current_coord.pos;
split.clen = current_coord.clen;
split.param = current_coord.param;
Expand Down Expand Up @@ -506,9 +511,10 @@ SplitPathCoord SplitPathCoord::at(
{
--split.path_coord_index;
}

split.index = path_coords[split.path_coord_index].index;
}

split.index = path_coords[split.path_coord_index].index;
Comment on lines +514 to -511
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by change. When not entering the if branch, the right split.index is implied by initialization of split.

return split;
}

Expand Down
80 changes: 80 additions & 0 deletions test/path_object_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

#include "path_object_t.h"

#include <iterator>

#include <Qt>
#include <QtTest>

#include "core/map.h"
Expand Down Expand Up @@ -1206,6 +1209,83 @@ void PathObjectTest::recalculatePartsTest()
}
}

void PathObjectTest::splitPathCoordAtTest()
{
const PathCoord::length_type lengths_to_check[] = {
-0.2f, 0.2f, 1.0f, 1.2f, 1.4f, 1.5f, 1.8, 2.0f, 2.2f, 3.2f, 5.0f
};
using std::begin; using std::end;
{
// Square, straight, closed
const MapCoordVector coords = {
{ 0.0, 0.0 }, { 1.0, 0.0 }, { 1.0, 1.0 }, { 0.0, 1.0 }, { 0.0, 0.0, MapCoord::HolePoint }
};

PathCoordVector path_coords { coords };
path_coords.update(0);
QCOMPARE(path_coords.size(), std::size_t(5));

const auto max_clen = path_coords.back().clen;
QCOMPARE(max_clen, 4.0f);

const auto split = SplitPathCoord::at(1.5f, SplitPathCoord::begin(path_coords));
{
const auto& prev = path_coords[split.path_coord_index];
QCOMPARE(prev.clen, 1.0f);
const auto& next = path_coords[split.path_coord_index + 1];
QCOMPARE(next.clen, 2.0f);
}

auto prev_clen = SplitPathCoord::at(lengths_to_check[0], split).clen;
for (auto it = begin(lengths_to_check)+1, last = end(lengths_to_check); it != last; ++it)
{
const auto requested_clen = *it;
const auto clen = SplitPathCoord::at(requested_clen, split).clen;
QVERIFY(clen >= prev_clen); // monotone
if (requested_clen >= max_clen)
QCOMPARE(clen, max_clen); // upper bound
else if (requested_clen >= split.clen)
QCOMPARE(clen, requested_clen); // expected case
prev_clen = clen;
}
}

{
// Line, curved
const MapCoordVector coords = {
{ 0.0, 0.0, MapCoord::CurveStart }, { 1.0, 0.0 }, { 1.0, 1.0 }, { 0.0, 1.0, MapCoord::HolePoint }
};

PathCoordVector path_coords { coords };
path_coords.update(0);
QCOMPARE(path_coords.size(), std::size_t(10));

const auto max_clen = path_coords.back().clen;
QCOMPARE(max_clen, 2.00034f);

const auto split = SplitPathCoord::at(1.5f, SplitPathCoord::begin(path_coords));
{
const auto& prev = path_coords[split.path_coord_index];
QCOMPARE(prev.clen, 1.29314f);
const auto& next = path_coords[split.path_coord_index + 1];
QCOMPARE(next.clen, 1.52751f);
}

auto prev_clen = SplitPathCoord::at(lengths_to_check[0], split).clen;
for (auto it = begin(lengths_to_check)+1, last = end(lengths_to_check); it != last; ++it)
{
const auto requested_clen = *it;
const auto clen = SplitPathCoord::at(requested_clen, split).clen;
QVERIFY(clen >= prev_clen); // monotone
if (requested_clen >= max_clen)
QCOMPARE(clen, max_clen); // upper bound
else if (requested_clen >= split.clen)
QCOMPARE(clen, requested_clen); // expected case
prev_clen = clen;
}
}
}



/*
Expand Down
3 changes: 3 additions & 0 deletions test/path_object_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ private slots:
/** Tests recalculation of path parts from input coords. */
void recalculatePartsTest();
void recalculatePartsTest_data();

/** Test SplitPathCoord.at stability. */
void splitPathCoordAtTest();
};

#endif