Likely performance improvement by limiting points
Instead of just deleting points in the triangle, we only check specific ones which are relevant
This commit is contained in:
parent
7dd46556c8
commit
535d912742
12
Line.h
12
Line.h
@ -12,6 +12,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
Line(Point from, Point to) : m_from(from), m_to(to), m_to_from_origin(to - from) {}
|
Line(Point from, Point to) : m_from(from), m_to(to), m_to_from_origin(to - from) {}
|
||||||
|
|
||||||
|
Line() = default;
|
||||||
|
|
||||||
Point from() const
|
Point from() const
|
||||||
{
|
{
|
||||||
return m_from;
|
return m_from;
|
||||||
@ -22,6 +24,16 @@ public:
|
|||||||
return m_to;
|
return m_to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_from(Point from)
|
||||||
|
{
|
||||||
|
m_from = from;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_to(Point to)
|
||||||
|
{
|
||||||
|
m_to = to;
|
||||||
|
}
|
||||||
|
|
||||||
// Return true if the given point is to the right of this line.
|
// Return true if the given point is to the right of this line.
|
||||||
// False is also returned if the point is directly on the line.
|
// False is also returned if the point is directly on the line.
|
||||||
bool is_point_right(Point other) const
|
bool is_point_right(Point other) const
|
||||||
|
53
Quickhull.h
53
Quickhull.h
@ -80,38 +80,49 @@ private:
|
|||||||
|
|
||||||
// Build a triangle with these 3 points
|
// Build a triangle with these 3 points
|
||||||
|
|
||||||
// The order with which we must pass the points depends on where the new furthest point is
|
// We need to differentiate based on which side the furthest point is on
|
||||||
// TODO: Is there a nicer way to do this?
|
// in order to keep the meaning of left/right consistent.
|
||||||
Point a, b, c;
|
|
||||||
|
Line new_line1, new_line2;
|
||||||
|
|
||||||
if (line.is_point_right(furthest_point))
|
if (line.is_point_right(furthest_point))
|
||||||
{
|
{
|
||||||
a = line.from();
|
// TOOD: It's probably more efficient to set the fields?
|
||||||
b = line.to();
|
new_line1 = Line(line.to(), furthest_point);
|
||||||
c = furthest_point;
|
new_line2 = Line(furthest_point, line.from());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a = line.from();
|
new_line1 = Line(line.from(), furthest_point);
|
||||||
b = furthest_point;
|
new_line2 = Line(furthest_point, line.to());
|
||||||
c = line.to();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle triangle(a, b, c);
|
// TODO: Test if this improves performance
|
||||||
|
//Triangle triangle(a, b, c);
|
||||||
|
//input.remove_if([triangle](Point point)
|
||||||
|
//{
|
||||||
|
// return triangle.is_point_inside(point);
|
||||||
|
//});
|
||||||
|
|
||||||
// Remove points inside this triangle
|
// Get points right of new_line1 and 2
|
||||||
// TODO: I think we can actually skip this, and instead only
|
std::list<Point> left_of_line1, left_of_line2;
|
||||||
// pass points to the left (?) of the individual line to the
|
|
||||||
// new get_hull_with_line call. That way the ones inside are
|
for (const Point& point : input)
|
||||||
// implicitly ignored.
|
|
||||||
input.remove_if([triangle](Point point)
|
|
||||||
{
|
{
|
||||||
return triangle.is_point_inside(point);
|
if (!new_line1.is_point_right(point))
|
||||||
});
|
{
|
||||||
|
left_of_line1.emplace_back(point);
|
||||||
|
}
|
||||||
|
// TODO: Can we do else if here, or could we then miss out on points?
|
||||||
|
if (!new_line2.is_point_right(point))
|
||||||
|
{
|
||||||
|
left_of_line2.emplace_back(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Recursively call get_hull_with_line for each side of the triangle
|
// Recursively call get_hull_with_line for each side of the triangle
|
||||||
// TODO: We can skip the original one
|
// TODO: We can skip the original one
|
||||||
get_hull_with_line(input, output, triangle.l1());
|
get_hull_with_line(left_of_line1, output, new_line1);
|
||||||
get_hull_with_line(input, output, triangle.l2());
|
get_hull_with_line(left_of_line2, output, new_line2);
|
||||||
get_hull_with_line(input, output, triangle.l3());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -3,10 +3,10 @@
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::list<Point> points = {
|
std::list<Point> points = {
|
||||||
|
Point(1, 1),
|
||||||
Point(-1, -1),
|
Point(-1, -1),
|
||||||
Point(-1, 1),
|
Point(-1, 1),
|
||||||
Point(1, -1),
|
Point(1, -1),
|
||||||
Point(1, 1),
|
|
||||||
Point(0.5, 0) // Should not be in the hull
|
Point(0.5, 0) // Should not be in the hull
|
||||||
};
|
};
|
||||||
std::list<Point> hull;
|
std::list<Point> hull;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user