forked from mirrors/0ad
Consider that the point could be inside the goal area in some PathGoal functions
Reviewed By: wraitii Comments By: mimo Differential Revision: https://code.wildfiregames.com/D1089 This was SVN commit r20878.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -64,6 +64,53 @@ public:
|
||||
TS_ASSERT_EQUALS((Pathfinding::NAVCELL_SIZE >> 1).ToInt_RoundToZero(), Pathfinding::NAVCELL_SIZE_LOG2);
|
||||
}
|
||||
|
||||
void test_pathgoal()
|
||||
{
|
||||
entity_pos_t i = Pathfinding::NAVCELL_SIZE;
|
||||
CFixedVector2D u(i*1, i*0);
|
||||
CFixedVector2D v(i*0, i*1);
|
||||
|
||||
{
|
||||
PathGoal goal = { PathGoal::POINT, i*8, i*6 };
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*8 + v*4), u*8 + v*6);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*8 + v*4), i*2);
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*0 + v*0), u*8 + v*6);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*0 + v*0), i*10);
|
||||
}
|
||||
|
||||
{
|
||||
PathGoal goal = { PathGoal::CIRCLE, i*8, i*6, i*5 };
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*8 + v*4), u*8 + v*4);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*8 + v*4), i*0);
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*0 + v*0), u*4 + v*3);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*0 + v*0), i*5);
|
||||
}
|
||||
|
||||
{
|
||||
PathGoal goal = { PathGoal::INVERTED_CIRCLE, i*8, i*6, i*5 };
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*8 + v*4), u*8 + v*1);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*8 + v*4), i*3);
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*0 + v*0), u*0 + v*0);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*0 + v*0), i*0);
|
||||
}
|
||||
|
||||
{
|
||||
PathGoal goal = { PathGoal::SQUARE, i*8, i*6, i*4, i*3, u, v };
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*8 + v*4), u*8 + v*4);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*8 + v*4), i*0);
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*0 + v*0), u*4 + v*3);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*0 + v*0), i*5);
|
||||
}
|
||||
|
||||
{
|
||||
PathGoal goal = { PathGoal::INVERTED_SQUARE, i*8, i*6, i*4, i*3, u, v };
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*8 + v*4), u*8 + v*3);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*8 + v*4), i*1);
|
||||
TS_ASSERT_EQUALS(goal.NearestPointOnGoal(u*0 + v*0), u*0 + v*0);
|
||||
TS_ASSERT_EQUALS(goal.DistanceToPoint(u*0 + v*0), i*0);
|
||||
}
|
||||
}
|
||||
|
||||
void test_performance_DISABLED()
|
||||
{
|
||||
CTerrain terrain;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -293,21 +293,31 @@ bool PathGoal::RectContainsGoal(entity_pos_t x0, entity_pos_t z0, entity_pos_t x
|
||||
|
||||
fixed PathGoal::DistanceToPoint(CFixedVector2D pos) const
|
||||
{
|
||||
CFixedVector2D d(pos.X - x, pos.Y - z);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case POINT:
|
||||
return (pos - CFixedVector2D(x, z)).Length();
|
||||
return d.Length();
|
||||
|
||||
case CIRCLE:
|
||||
return d.CompareLength(hw) <= 0 ? fixed::Zero() : d.Length() - hw;
|
||||
|
||||
case INVERTED_CIRCLE:
|
||||
return ((pos - CFixedVector2D(x, z)).Length() - hw).Absolute();
|
||||
return d.CompareLength(hw) >= 0 ? fixed::Zero() : hw - d.Length();
|
||||
|
||||
case SQUARE:
|
||||
{
|
||||
CFixedVector2D halfSize(hw, hh);
|
||||
return Geometry::PointIsInSquare(d, u, v, halfSize) ?
|
||||
fixed::Zero() : Geometry::DistanceToSquare(d, u, v, halfSize);
|
||||
}
|
||||
|
||||
case INVERTED_SQUARE:
|
||||
{
|
||||
CFixedVector2D halfSize(hw, hh);
|
||||
CFixedVector2D d(pos.X - x, pos.Y - z);
|
||||
return Geometry::DistanceToSquare(d, u, v, halfSize);
|
||||
return !Geometry::PointIsInSquare(d, u, v, halfSize) ?
|
||||
fixed::Zero() : Geometry::DistanceToSquare(d, u, v, halfSize);
|
||||
}
|
||||
|
||||
NODEFAULT;
|
||||
@@ -324,9 +334,21 @@ CFixedVector2D PathGoal::NearestPointOnGoal(CFixedVector2D pos) const
|
||||
return g;
|
||||
|
||||
case CIRCLE:
|
||||
{
|
||||
CFixedVector2D d(pos.X - x, pos.Y - z);
|
||||
if (d.CompareLength(hw) <= 0)
|
||||
return pos;
|
||||
|
||||
d.Normalize(hw);
|
||||
return g + d;
|
||||
}
|
||||
|
||||
case INVERTED_CIRCLE:
|
||||
{
|
||||
CFixedVector2D d = pos - g;
|
||||
CFixedVector2D d(pos.X - x, pos.Y - z);
|
||||
if (d.CompareLength(hw) >= 0)
|
||||
return pos;
|
||||
|
||||
if (d.IsZero())
|
||||
d = CFixedVector2D(fixed::FromInt(1), fixed::Zero()); // some arbitrary direction
|
||||
d.Normalize(hw);
|
||||
@@ -334,11 +356,19 @@ CFixedVector2D PathGoal::NearestPointOnGoal(CFixedVector2D pos) const
|
||||
}
|
||||
|
||||
case SQUARE:
|
||||
{
|
||||
CFixedVector2D halfSize(hw, hh);
|
||||
CFixedVector2D d(pos.X - x, pos.Y - z);
|
||||
return Geometry::PointIsInSquare(d, u, v, halfSize) ?
|
||||
pos : g + Geometry::NearestPointOnSquare(d, u, v, halfSize);
|
||||
}
|
||||
|
||||
case INVERTED_SQUARE:
|
||||
{
|
||||
CFixedVector2D halfSize(hw, hh);
|
||||
CFixedVector2D d = pos - g;
|
||||
return g + Geometry::NearestPointOnSquare(d, u, v, halfSize);
|
||||
CFixedVector2D d(pos.X - x, pos.Y - z);
|
||||
return !Geometry::PointIsInSquare(d, u, v, halfSize) ?
|
||||
pos : g + Geometry::NearestPointOnSquare(d, u, v, halfSize);
|
||||
}
|
||||
|
||||
NODEFAULT;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -42,10 +42,10 @@ public:
|
||||
|
||||
entity_pos_t x, z; // position of center
|
||||
|
||||
CFixedVector2D u, v; // if [INVERTED_]SQUARE, then orthogonal unit axes
|
||||
|
||||
entity_pos_t hw, hh; // if [INVERTED_]SQUARE, then half width & height; if [INVERTED_]CIRCLE, then hw is radius
|
||||
|
||||
CFixedVector2D u, v; // if [INVERTED_]SQUARE, then orthogonal unit axes
|
||||
|
||||
entity_pos_t maxdist; // maximum distance wanted between two path waypoints
|
||||
|
||||
/**
|
||||
@@ -70,13 +70,12 @@ public:
|
||||
bool RectContainsGoal(entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1) const;
|
||||
|
||||
/**
|
||||
* Returns the minimum distance from the point with the given @p pos
|
||||
* to any point on the outline of the goal shape.
|
||||
* Returns the minimum distance from the point pos to any point on the goal shape.
|
||||
*/
|
||||
fixed DistanceToPoint(CFixedVector2D pos) const;
|
||||
|
||||
/**
|
||||
* Returns the coordinates of the point on the goal that is closest to pos in a straight line.
|
||||
* Returns the coordinates of the point on the goal that is closest to the point pos.
|
||||
*/
|
||||
CFixedVector2D NearestPointOnGoal(CFixedVector2D pos) const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user