mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-04 03:43:46 +00:00
Format all C++ and Java code via clang-format
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
@@ -42,8 +42,7 @@ CalculatePointOnSurface::CalculatePointOnSurface(m2::RectD const & rect)
|
||||
: m_rectCenter(rect.Center())
|
||||
, m_center(m_rectCenter)
|
||||
, m_squareDistanceToApproximate(std::numeric_limits<double>::max())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void CalculatePointOnSurface::operator()(PointD const & p1, PointD const & p2, PointD const & p3)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
void operator()(PointD const & p1, PointD const & p2, PointD const & p3);
|
||||
PointD GetResult() const { return m_center; }
|
||||
|
||||
private:
|
||||
PointD m_rectCenter;
|
||||
PointD m_center;
|
||||
@@ -56,6 +57,7 @@ class CalculateBoundingBox
|
||||
public:
|
||||
void operator()(PointD const & p);
|
||||
RectD GetResult() const { return m_boundingBox; }
|
||||
|
||||
private:
|
||||
RectD m_boundingBox;
|
||||
};
|
||||
@@ -80,8 +82,7 @@ m2::PointD ApplyPointOnSurfaceCalculator(TIterator begin, TIterator end, TCalcul
|
||||
}
|
||||
|
||||
template <typename TCalculator, typename TIterator>
|
||||
auto ApplyCalculator(TIterator begin, TIterator end, TCalculator && calc)
|
||||
-> decltype(calc.GetResult())
|
||||
auto ApplyCalculator(TIterator begin, TIterator end, TCalculator && calc) -> decltype(calc.GetResult())
|
||||
{
|
||||
for (; begin != end; ++begin)
|
||||
calc(*begin);
|
||||
@@ -89,34 +90,30 @@ auto ApplyCalculator(TIterator begin, TIterator end, TCalculator && calc)
|
||||
}
|
||||
|
||||
template <typename TCalculator, typename TIterator>
|
||||
auto SelectImplementation(TIterator begin, TIterator end, TCalculator && calc,
|
||||
std::true_type const &) -> decltype(calc.GetResult())
|
||||
auto SelectImplementation(TIterator begin, TIterator end, TCalculator && calc, std::true_type const &)
|
||||
-> decltype(calc.GetResult())
|
||||
{
|
||||
return impl::ApplyPointOnSurfaceCalculator(begin, end, std::forward<TCalculator>(calc));
|
||||
}
|
||||
|
||||
template <typename TCalculator, typename TIterator>
|
||||
auto SelectImplementation(TIterator begin, TIterator end, TCalculator && calc,
|
||||
std::false_type const &) -> decltype(calc.GetResult())
|
||||
auto SelectImplementation(TIterator begin, TIterator end, TCalculator && calc, std::false_type const &)
|
||||
-> decltype(calc.GetResult())
|
||||
{
|
||||
return impl::ApplyCalculator(begin, end, std::forward<TCalculator>(calc));
|
||||
}
|
||||
} // namespace impl
|
||||
|
||||
template <typename TCalculator, typename TIterator>
|
||||
auto ApplyCalculator(TIterator begin, TIterator end, TCalculator && calc)
|
||||
-> decltype(calc.GetResult())
|
||||
auto ApplyCalculator(TIterator begin, TIterator end, TCalculator && calc) -> decltype(calc.GetResult())
|
||||
{
|
||||
return impl::SelectImplementation(
|
||||
begin, end, std::forward<TCalculator>(calc),
|
||||
std::is_same<CalculatePointOnSurface, std::remove_reference_t<TCalculator>>());
|
||||
return impl::SelectImplementation(begin, end, std::forward<TCalculator>(calc),
|
||||
std::is_same<CalculatePointOnSurface, std::remove_reference_t<TCalculator>>());
|
||||
}
|
||||
|
||||
template <typename TCalculator, typename TCollection>
|
||||
auto ApplyCalculator(TCollection && collection, TCalculator && calc)
|
||||
-> decltype(calc.GetResult())
|
||||
auto ApplyCalculator(TCollection && collection, TCalculator && calc) -> decltype(calc.GetResult())
|
||||
{
|
||||
return ApplyCalculator(std::begin(collection), std::end(collection),
|
||||
std::forward<TCalculator>(calc));
|
||||
return ApplyCalculator(std::begin(collection), std::end(collection), std::forward<TCalculator>(calc));
|
||||
}
|
||||
} // namespace m2
|
||||
|
||||
@@ -37,18 +37,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
AnyRect(Point<T> const & zero, ang::Angle<T> const & angle, Rect<T> const & r)
|
||||
: m_angle(angle), m_rect(r)
|
||||
AnyRect(Point<T> const & zero, ang::Angle<T> const & angle, Rect<T> const & r) : m_angle(angle), m_rect(r)
|
||||
{
|
||||
m_zero = Convert(zero, Point<T>(1, 0), Point<T>(0, 1), i(), j());
|
||||
}
|
||||
|
||||
Point<T> const & LocalZero() const { return m_zero; }
|
||||
|
||||
Point<T> GlobalZero() const
|
||||
{
|
||||
return Convert(m_zero, i(), j(), Point<T>(1, 0), Point<T>(0, 1));
|
||||
}
|
||||
Point<T> GlobalZero() const { return Convert(m_zero, i(), j(), Point<T>(1, 0), Point<T>(0, 1)); }
|
||||
|
||||
Point<T> i() const { return Point<T>(m_angle.cos(), m_angle.sin()); }
|
||||
|
||||
@@ -81,10 +77,8 @@ public:
|
||||
std::sort(arr2.begin(), arr2.end());
|
||||
|
||||
for (size_t i = 0; i < arr1.size(); ++i)
|
||||
{
|
||||
if (!arr1[i].EqualDxDy(arr2[i], eps))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -96,8 +90,8 @@ public:
|
||||
Corners pts;
|
||||
r.GetGlobalPoints(pts);
|
||||
ConvertTo(pts);
|
||||
return m_rect.IsPointInside(pts[0]) && m_rect.IsPointInside(pts[1]) &&
|
||||
m_rect.IsPointInside(pts[2]) && m_rect.IsPointInside(pts[3]);
|
||||
return m_rect.IsPointInside(pts[0]) && m_rect.IsPointInside(pts[1]) && m_rect.IsPointInside(pts[2]) &&
|
||||
m_rect.IsPointInside(pts[3]);
|
||||
}
|
||||
|
||||
bool IsIntersect(AnyRect<T> const & r) const
|
||||
@@ -196,8 +190,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static Point<T> Convert(Point<T> const & p, Point<T> const & fromI, Point<T> const & fromJ,
|
||||
Point<T> const & toI, Point<T> const & toJ)
|
||||
static Point<T> Convert(Point<T> const & p, Point<T> const & fromI, Point<T> const & fromJ, Point<T> const & toI,
|
||||
Point<T> const & toJ)
|
||||
{
|
||||
Point<T> res;
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ double AreaOnEarth(LatLon const & ll1, LatLon const & ll2, LatLon const & ll3)
|
||||
ASSERT(::AlmostEqualAbs(c.Length(), 1.0, 1e-5), ());
|
||||
|
||||
double constexpr lengthMultiplication = 1.0; // a.Length() * b.Length() * c.Length()
|
||||
double const abc = m3::DotProduct(a, b); // * c.Length() == 1
|
||||
double const acb = m3::DotProduct(a, c); // * b.Length() == 1
|
||||
double const bca = m3::DotProduct(b, c); // * a.Length() == 1
|
||||
double const abc = m3::DotProduct(a, b); // * c.Length() == 1
|
||||
double const acb = m3::DotProduct(a, c); // * b.Length() == 1
|
||||
double const bca = m3::DotProduct(b, c); // * a.Length() == 1
|
||||
|
||||
double const tanFromHalfSolidAngle = triple / (lengthMultiplication + abc + acb + bca);
|
||||
double const halfSolidAngle = atan(tanFromHalfSolidAngle);
|
||||
|
||||
@@ -17,10 +17,7 @@ template <class T, size_t Dim>
|
||||
class AvgVector
|
||||
{
|
||||
public:
|
||||
explicit AvgVector(size_t count = 1) : m_count(count)
|
||||
{
|
||||
static_assert(std::is_floating_point<T>::value, "");
|
||||
}
|
||||
explicit AvgVector(size_t count = 1) : m_count(count) { static_assert(std::is_floating_point<T>::value, ""); }
|
||||
|
||||
void SetCount(size_t count) { m_count = count; }
|
||||
|
||||
|
||||
@@ -40,10 +40,7 @@ public:
|
||||
return points;
|
||||
}
|
||||
|
||||
bool operator==(BoundingBox const & rhs) const
|
||||
{
|
||||
return m_min == rhs.m_min && m_max == rhs.m_max;
|
||||
}
|
||||
bool operator==(BoundingBox const & rhs) const { return m_min == rhs.m_min && m_max == rhs.m_max; }
|
||||
|
||||
DECLARE_VISITOR(visitor(m_min, "min"), visitor(m_max, "max"))
|
||||
DECLARE_DEBUG_PRINT(BoundingBox)
|
||||
|
||||
@@ -23,7 +23,10 @@ bool IsCCWNeg(PointD const & p1, PointD const & p2, PointD const & p, double eps
|
||||
return robust::OrientedS(p1, p2, p) > -eps;
|
||||
}
|
||||
|
||||
PointD Ort(PointD const & p) { return PointD(-p.y, p.x); }
|
||||
PointD Ort(PointD const & p)
|
||||
{
|
||||
return PointD(-p.y, p.x);
|
||||
}
|
||||
|
||||
// For each facet of the |hull| calls |fn| with the smallest rectangle
|
||||
// containing the hull and with one side collinear to the facet.
|
||||
@@ -113,11 +116,11 @@ void CalipersBox::Deserialize(std::vector<PointD> && points)
|
||||
ASSERT(TestValid(), ());
|
||||
|
||||
// 2. Stable with input.
|
||||
//#ifdef DEBUG
|
||||
// CalipersBox test(m_points);
|
||||
// ASSERT(test.TestValid(), ());
|
||||
// *this = std::move(test);
|
||||
//#endif
|
||||
// #ifdef DEBUG
|
||||
// CalipersBox test(m_points);
|
||||
// ASSERT(test.TestValid(), ());
|
||||
// *this = std::move(test);
|
||||
// #endif
|
||||
}
|
||||
|
||||
void CalipersBox::Normalize()
|
||||
@@ -136,10 +139,8 @@ bool CalipersBox::TestValid() const
|
||||
{
|
||||
size_t const n = m_points.size();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
if (!IsCCWNeg(m_points[i], m_points[(i + 1) % n], m_points[(i + 2) % n], kEps))
|
||||
return false;
|
||||
}
|
||||
return n > 0;
|
||||
}
|
||||
|
||||
@@ -148,12 +149,9 @@ bool CalipersBox::HasPoint(PointD const & p, double eps) const
|
||||
auto const n = m_points.size();
|
||||
switch (n)
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
return AlmostEqualAbs(m_points[0], p, eps);
|
||||
case 2:
|
||||
return IsPointOnSegmentEps(p, m_points[0], m_points[1], eps);
|
||||
case 0: return false;
|
||||
case 1: return AlmostEqualAbs(m_points[0], p, eps);
|
||||
case 2: return IsPointOnSegmentEps(p, m_points[0], m_points[1], eps);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
|
||||
@@ -108,10 +108,8 @@ public:
|
||||
if (length >= DEPTH_LEVELS)
|
||||
return false;
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if (s[i] < '0' || s[i] > '3')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,13 @@ std::vector<m3::PointD> CreateCircleOnNorth(double radiusMeters, double angleSte
|
||||
std::vector<m3::PointD> result;
|
||||
double const stepRad = math::DegToRad(angleStepDegree);
|
||||
for (double angleRad = 0; angleRad < 2 * math::pi; angleRad += stepRad)
|
||||
{
|
||||
result.emplace_back(circleRadiusMeters * cos(angleRad),
|
||||
circleRadiusMeters * sin(angleRad),
|
||||
z);
|
||||
}
|
||||
result.emplace_back(circleRadiusMeters * cos(angleRad), circleRadiusMeters * sin(angleRad), z);
|
||||
return result;
|
||||
}
|
||||
|
||||
ms::LatLon FromEarth3dToSpherical(m3::PointD const & vec)
|
||||
{
|
||||
ASSERT(AlmostEqualAbs(vec.Length(), ms::kEarthRadiusMeters, 1e-5),
|
||||
(vec.Length(), ms::kEarthRadiusMeters));
|
||||
ASSERT(AlmostEqualAbs(vec.Length(), ms::kEarthRadiusMeters, 1e-5), (vec.Length(), ms::kEarthRadiusMeters));
|
||||
|
||||
double sinLatRad = vec.z / ms::kEarthRadiusMeters;
|
||||
sinLatRad = math::Clamp(sinLatRad, -1.0, 1.0);
|
||||
|
||||
@@ -25,9 +25,8 @@ int GetRectSideIndex(int code)
|
||||
using CornersT = std::array<m2::PointD, 4>;
|
||||
|
||||
template <class AddPointFnT>
|
||||
void InsertCorners(CornersT const & corners, m2::PointD const & p1, m2::PointD const & p2,
|
||||
m2::PointD const & p3, AddPointFnT const & addPolygonPoint, int code1,
|
||||
int code2)
|
||||
void InsertCorners(CornersT const & corners, m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3,
|
||||
AddPointFnT const & addPolygonPoint, int code1, int code2)
|
||||
{
|
||||
int cornerInd = GetRectSideIndex(code1);
|
||||
int endCornerInd = GetRectSideIndex(code2);
|
||||
@@ -47,9 +46,8 @@ void InsertCorners(CornersT const & corners, m2::PointD const & p1, m2::PointD c
|
||||
}
|
||||
|
||||
template <class AddPointFnT>
|
||||
bool IntersectEdge(m2::RectD const & rect, CornersT const & corners,
|
||||
m2::PointD const & pp1, m2::PointD const & pp2, m2::PointD const & pp3,
|
||||
AddPointFnT const & addPolygonPoint, int prevClipCode, int nextClipCode,
|
||||
bool IntersectEdge(m2::RectD const & rect, CornersT const & corners, m2::PointD const & pp1, m2::PointD const & pp2,
|
||||
m2::PointD const & pp3, AddPointFnT const & addPolygonPoint, int prevClipCode, int nextClipCode,
|
||||
int & firstClipCode, int & lastClipCode)
|
||||
{
|
||||
m2::PointD p1 = pp1;
|
||||
@@ -75,10 +73,10 @@ bool IntersectEdge(m2::RectD const & rect, CornersT const & corners,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2,
|
||||
m2::PointD const & p3, ClipTriangleByRectResultIt const & resultIterator)
|
||||
void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3,
|
||||
ClipTriangleByRectResultIt const & resultIterator)
|
||||
{
|
||||
if (rect.IsPointInside(p1) && rect.IsPointInside(p2) && rect.IsPointInside(p3))
|
||||
{
|
||||
@@ -94,22 +92,20 @@ void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::Point
|
||||
polygon.push_back(pt);
|
||||
};
|
||||
|
||||
CornersT const corners = { rect.LeftTop(), rect.RightTop(), rect.RightBottom(), rect.LeftBottom() };
|
||||
CornersT const corners = {rect.LeftTop(), rect.RightTop(), rect.RightBottom(), rect.LeftBottom()};
|
||||
|
||||
int firstClipCode[3];
|
||||
int lastClipCode[3];
|
||||
bool intersected[3];
|
||||
|
||||
intersected[0] = IntersectEdge(rect, corners, p1, p2, p3, addPolygonPoint, 0, 0, firstClipCode[0],
|
||||
lastClipCode[0]);
|
||||
intersected[0] = IntersectEdge(rect, corners, p1, p2, p3, addPolygonPoint, 0, 0, firstClipCode[0], lastClipCode[0]);
|
||||
|
||||
intersected[1] = IntersectEdge(rect, corners, p2, p3, p1, addPolygonPoint, lastClipCode[0], 0,
|
||||
firstClipCode[1], lastClipCode[1]);
|
||||
intersected[1] =
|
||||
IntersectEdge(rect, corners, p2, p3, p1, addPolygonPoint, lastClipCode[0], 0, firstClipCode[1], lastClipCode[1]);
|
||||
|
||||
intersected[2] = IntersectEdge(rect, corners, p3, p1, p2, addPolygonPoint,
|
||||
lastClipCode[1] != 0 ? lastClipCode[1] : lastClipCode[0],
|
||||
firstClipCode[0] != 0 ? firstClipCode[0] : firstClipCode[1],
|
||||
firstClipCode[2], lastClipCode[2]);
|
||||
intersected[2] = IntersectEdge(
|
||||
rect, corners, p3, p1, p2, addPolygonPoint, lastClipCode[1] != 0 ? lastClipCode[1] : lastClipCode[0],
|
||||
firstClipCode[0] != 0 ? firstClipCode[0] : firstClipCode[1], firstClipCode[2], lastClipCode[2]);
|
||||
|
||||
int const intersectCount = intersected[0] + intersected[1] + intersected[2];
|
||||
if (intersectCount == 0)
|
||||
@@ -207,7 +203,7 @@ std::vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect, m2::Share
|
||||
case RectCase::Intersect:
|
||||
{
|
||||
std::vector<m2::SharedSpline> res;
|
||||
res.reserve(2); // keep previous behavior, but not sure that its actually needed
|
||||
res.reserve(2); // keep previous behavior, but not sure that its actually needed
|
||||
ClipPathByRectImpl(rect, spline->GetPath(), base::MakeBackInsertFunctor(res));
|
||||
return res;
|
||||
}
|
||||
@@ -217,7 +213,7 @@ std::vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect, m2::Share
|
||||
}
|
||||
|
||||
void ClipPathByRect(m2::RectD const & rect, std::vector<m2::PointD> && path,
|
||||
std::function<void (m2::SharedSpline &&)> const & fn)
|
||||
std::function<void(m2::SharedSpline &&)> const & fn)
|
||||
{
|
||||
switch (GetRectCase(rect, path))
|
||||
{
|
||||
@@ -228,8 +224,7 @@ void ClipPathByRect(m2::RectD const & rect, std::vector<m2::PointD> && path,
|
||||
}
|
||||
|
||||
void ClipPathByRectBeforeSmooth(m2::RectD const & rect, std::vector<m2::PointD> const & path,
|
||||
GuidePointsForSmooth & guidePoints,
|
||||
std::vector<std::vector<m2::PointD>> & clippedPaths)
|
||||
GuidePointsForSmooth & guidePoints, std::vector<std::vector<m2::PointD>> & clippedPaths)
|
||||
{
|
||||
if (path.size() < 2)
|
||||
return;
|
||||
@@ -313,4 +308,4 @@ void ClipPathByRectBeforeSmooth(m2::RectD const & rect, std::vector<m2::PointD>
|
||||
guidePoints.push_back({currentGuideFront, guideBack});
|
||||
}
|
||||
}
|
||||
} // namespace m2;
|
||||
} // namespace m2
|
||||
|
||||
@@ -9,16 +9,14 @@
|
||||
|
||||
namespace m2
|
||||
{
|
||||
using ClipTriangleByRectResultIt =
|
||||
std::function<void(m2::PointD const &, m2::PointD const &, m2::PointD const &)>;
|
||||
using ClipTriangleByRectResultIt = std::function<void(m2::PointD const &, m2::PointD const &, m2::PointD const &)>;
|
||||
|
||||
void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2,
|
||||
m2::PointD const & p3, ClipTriangleByRectResultIt const & resultIterator);
|
||||
void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3,
|
||||
ClipTriangleByRectResultIt const & resultIterator);
|
||||
|
||||
void ClipPathByRect(m2::RectD const & rect, std::vector<m2::PointD> && path,
|
||||
std::function<void (m2::SharedSpline &&)> const & fn);
|
||||
std::vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect,
|
||||
m2::SharedSpline const & spline);
|
||||
std::function<void(m2::SharedSpline &&)> const & fn);
|
||||
std::vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect, m2::SharedSpline const & spline);
|
||||
|
||||
using GuidePointsForSmooth = std::vector<std::pair<m2::PointD, m2::PointD>>;
|
||||
void ClipPathByRectBeforeSmooth(m2::RectD const & rect, std::vector<m2::PointD> const & path,
|
||||
|
||||
@@ -62,8 +62,5 @@ std::vector<PointD> BuildConvexHull(std::vector<PointD> points, double eps)
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ConvexHull::ConvexHull(std::vector<PointD> const & points, double eps)
|
||||
: m_hull(BuildConvexHull(points, eps))
|
||||
{
|
||||
}
|
||||
ConvexHull::ConvexHull(std::vector<PointD> const & points, double eps) : m_hull(BuildConvexHull(points, eps)) {}
|
||||
} // namespace m2
|
||||
|
||||
@@ -41,8 +41,7 @@ public:
|
||||
}
|
||||
|
||||
// Cover triangle.
|
||||
Covering(m2::PointD const & a, m2::PointD const & b, m2::PointD const & c,
|
||||
int level = CellId::DEPTH_LEVELS - 1)
|
||||
Covering(m2::PointD const & a, m2::PointD const & b, m2::PointD const & c, int level = CellId::DEPTH_LEVELS - 1)
|
||||
{
|
||||
// TODO: ASSERT(a != b), ASSERT(b != c), ASSERT(a != c) ?
|
||||
ASSERT(0 <= level && level <= CellId::DEPTH_LEVELS, (level, CellId::Root()));
|
||||
@@ -117,12 +116,10 @@ private:
|
||||
std::vector<CellId> parentCells;
|
||||
std::vector<CellId> childCells;
|
||||
for (ConstIterator it = m_Covering[level].begin(); it != m_Covering[level].end(); ++it)
|
||||
{
|
||||
if (parentCellCounts[it->Parent()] > 1)
|
||||
parentCells.push_back(it->Parent());
|
||||
else
|
||||
childCells.push_back(*it);
|
||||
}
|
||||
ASSERT(std::is_sorted(parentCells.begin(), parentCells.end(), LessLevelOrder()), (parentCells));
|
||||
ASSERT(std::is_sorted(childCells.begin(), childCells.end(), LessLevelOrder()), (childCells));
|
||||
m_Covering[level].swap(childCells);
|
||||
@@ -135,8 +132,7 @@ private:
|
||||
ASSERT(base::IsSortedAndUnique(a.begin(), a.end(), LessLevelOrder()), (a));
|
||||
ASSERT(base::IsSortedAndUnique(b.begin(), b.end(), LessLevelOrder()), (b));
|
||||
std::vector<CellId> merged;
|
||||
std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(merged),
|
||||
LessLevelOrder());
|
||||
std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(merged), LessLevelOrder());
|
||||
a.swap(merged);
|
||||
}
|
||||
|
||||
@@ -195,16 +191,13 @@ private:
|
||||
{
|
||||
if (m_Covering[parentLevel].empty())
|
||||
continue;
|
||||
for (int childLevel = parentLevel + 1; childLevel < static_cast<int>(m_Covering.size());
|
||||
++childLevel)
|
||||
for (int childLevel = parentLevel + 1; childLevel < static_cast<int>(m_Covering.size()); ++childLevel)
|
||||
{
|
||||
std::vector<CellId> subtracted;
|
||||
CompareCellsAtLevel<LessLevelOrder> comparator(parentLevel);
|
||||
ASSERT(std::is_sorted(m_Covering[childLevel].begin(), m_Covering[childLevel].end(),
|
||||
comparator),
|
||||
ASSERT(std::is_sorted(m_Covering[childLevel].begin(), m_Covering[childLevel].end(), comparator),
|
||||
(m_Covering[childLevel]));
|
||||
ASSERT(std::is_sorted(m_Covering[parentLevel].begin(), m_Covering[parentLevel].end(),
|
||||
comparator),
|
||||
ASSERT(std::is_sorted(m_Covering[parentLevel].begin(), m_Covering[parentLevel].end(), comparator),
|
||||
(m_Covering[parentLevel]));
|
||||
SetDifferenceUnlimited(m_Covering[childLevel].begin(), m_Covering[childLevel].end(),
|
||||
m_Covering[parentLevel].begin(), m_Covering[parentLevel].end(),
|
||||
@@ -229,8 +222,7 @@ private:
|
||||
if (i + 3 < a.size())
|
||||
{
|
||||
CellId const parent = a[i].Parent();
|
||||
if (parent == a[i + 1].Parent() && parent == a[i + 2].Parent() &&
|
||||
parent == a[i + 3].Parent())
|
||||
if (parent == a[i + 1].Parent() && parent == a[i + 2].Parent() && parent == a[i + 3].Parent())
|
||||
{
|
||||
parents.push_back(parent);
|
||||
i += 3;
|
||||
@@ -263,8 +255,7 @@ private:
|
||||
static void CoverTriangleImpl(CoverTriangleInfo const & info, CellId const cell)
|
||||
{
|
||||
ASSERT_LESS_OR_EQUAL(cell.Level(), info.m_Level, (info.m_A, info.m_B, info.m_C));
|
||||
CellObjectIntersection intersection =
|
||||
IntersectCellWithTriangle(cell, info.m_A, info.m_B, info.m_C);
|
||||
CellObjectIntersection intersection = IntersectCellWithTriangle(cell, info.m_A, info.m_B, info.m_C);
|
||||
|
||||
if (intersection == CELL_OBJECT_NO_INTERSECTION)
|
||||
return;
|
||||
|
||||
@@ -28,27 +28,23 @@ enum CellObjectIntersection
|
||||
};
|
||||
|
||||
template <class CellId>
|
||||
CellObjectIntersection IntersectCellWithLine(CellId const cell, m2::PointD const & a,
|
||||
m2::PointD const & b)
|
||||
CellObjectIntersection IntersectCellWithLine(CellId const cell, m2::PointD const & a, m2::PointD const & b)
|
||||
{
|
||||
std::pair<uint32_t, uint32_t> const xy = cell.XY();
|
||||
uint32_t const r = cell.Radius();
|
||||
m2::PointD const cellCorners[4] = {
|
||||
m2::PointD(xy.first - r, xy.second - r), m2::PointD(xy.first - r, xy.second + r),
|
||||
m2::PointD(xy.first + r, xy.second + r), m2::PointD(xy.first + r, xy.second - r)};
|
||||
m2::PointD const cellCorners[4] = {m2::PointD(xy.first - r, xy.second - r), m2::PointD(xy.first - r, xy.second + r),
|
||||
m2::PointD(xy.first + r, xy.second + r), m2::PointD(xy.first + r, xy.second - r)};
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (m2::SegmentsIntersect(a, b, cellCorners[i], cellCorners[i == 0 ? 3 : i - 1]))
|
||||
return CELL_OBJECT_INTERSECT;
|
||||
}
|
||||
if (xy.first - r <= a.x && a.x <= xy.first + r && xy.second - r <= a.y && a.y <= xy.second + r)
|
||||
return OBJECT_INSIDE_CELL;
|
||||
return CELL_OBJECT_NO_INTERSECTION;
|
||||
}
|
||||
|
||||
template <class CellId>
|
||||
CellObjectIntersection IntersectCellWithTriangle(CellId const cell, m2::PointD const & a,
|
||||
m2::PointD const & b, m2::PointD const & c)
|
||||
CellObjectIntersection IntersectCellWithTriangle(CellId const cell, m2::PointD const & a, m2::PointD const & b,
|
||||
m2::PointD const & c)
|
||||
{
|
||||
CellObjectIntersection const i1 = IntersectCellWithLine(cell, a, b);
|
||||
if (i1 == CELL_OBJECT_INTERSECT)
|
||||
@@ -75,8 +71,8 @@ CellObjectIntersection IntersectCellWithTriangle(CellId const cell, m2::PointD c
|
||||
}
|
||||
|
||||
template <class CellId, class CellIdContainerT, typename IntersectF>
|
||||
void CoverObject(IntersectF const & intersect, uint64_t cellPenaltyArea, CellIdContainerT & out,
|
||||
int cellDepth, CellId cell)
|
||||
void CoverObject(IntersectF const & intersect, uint64_t cellPenaltyArea, CellIdContainerT & out, int cellDepth,
|
||||
CellId cell)
|
||||
{
|
||||
if (cell.Level() == cellDepth - 1)
|
||||
{
|
||||
@@ -107,13 +103,9 @@ void CoverObject(IntersectF const & intersect, uint64_t cellPenaltyArea, CellIdC
|
||||
|
||||
// This criteria is more clear for me. Let's divide if we can save more than cellPenaltyArea.
|
||||
if (subdiv.size() > 1 && cellPenaltyArea >= cellArea - subdivArea)
|
||||
{
|
||||
out.push_back(cell);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < subdiv.size(); ++i)
|
||||
out.push_back(subdiv[i]);
|
||||
}
|
||||
}
|
||||
} // namespace covering
|
||||
|
||||
@@ -25,10 +25,7 @@ public:
|
||||
|
||||
bool HasPoint(PointD const & p, double eps) const { return HasPoint(p.x, p.y, eps); }
|
||||
|
||||
bool HasPoint(double x, double y, double eps) const
|
||||
{
|
||||
return m_box.HasPoint(x + y, x - y, 2 * eps);
|
||||
}
|
||||
bool HasPoint(double x, double y, double eps) const { return m_box.HasPoint(x + y, x - y, 2 * eps); }
|
||||
|
||||
std::vector<m2::PointD> Points() const
|
||||
{
|
||||
@@ -44,10 +41,7 @@ public:
|
||||
DECLARE_DEBUG_PRINT(DiamondBox)
|
||||
|
||||
private:
|
||||
static m2::PointD ToOrig(m2::PointD const & p)
|
||||
{
|
||||
return m2::PointD(0.5 * (p.x + p.y), 0.5 * (p.x - p.y));
|
||||
}
|
||||
static m2::PointD ToOrig(m2::PointD const & p) { return m2::PointD(0.5 * (p.x + p.y), 0.5 * (p.x - p.y)); }
|
||||
|
||||
BoundingBox m_box;
|
||||
};
|
||||
|
||||
@@ -11,11 +11,11 @@ namespace algorithm_test
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
using m2::CalculateBoundingBox;
|
||||
using m2::CalculatePointOnSurface;
|
||||
using m2::CalculatePolyLineCenter;
|
||||
using m2::PointD;
|
||||
using m2::RectD;
|
||||
using m2::CalculatePolyLineCenter;
|
||||
using m2::CalculatePointOnSurface;
|
||||
using m2::CalculateBoundingBox;
|
||||
|
||||
PointD GetPolyLineCenter(vector<PointD> const & points)
|
||||
{
|
||||
@@ -42,52 +42,28 @@ bool PointsAlmostEqual(PointD const & p1, PointD const & p2)
|
||||
UNIT_TEST(CalculatePolyLineCenter)
|
||||
{
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}
|
||||
};
|
||||
vector<PointD> const points{{0, 0}, {1, 1}, {2, 2}};
|
||||
TEST_EQUAL(GetPolyLineCenter(points), PointD(1, 1), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 2},
|
||||
{1, 1},
|
||||
{2, 2}
|
||||
};
|
||||
vector<PointD> const points{{0, 2}, {1, 1}, {2, 2}};
|
||||
TEST_EQUAL(GetPolyLineCenter(points), PointD(1, 1), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{4, 4},
|
||||
vector<PointD> const points{
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{4, 4},
|
||||
};
|
||||
TEST_EQUAL(GetPolyLineCenter(points), PointD(2.5, 2.5), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0}
|
||||
};
|
||||
vector<PointD> const points{{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
|
||||
// Also logs a warning message.
|
||||
TEST_EQUAL(GetPolyLineCenter(points), PointD(0, 0), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0.000001},
|
||||
{0, 0.000001},
|
||||
{0, 0.000001},
|
||||
{0, 0.000001}
|
||||
};
|
||||
vector<PointD> const points{{0, 0}, {0, 0}, {0, 0}, {0, 0.000001}, {0, 0.000001}, {0, 0.000001}, {0, 0.000001}};
|
||||
// Also logs a warning message.
|
||||
TEST(GetPolyLineCenter(points).EqualDxDy(PointD(0, .0000005), 1e-7), ());
|
||||
}
|
||||
@@ -96,28 +72,15 @@ UNIT_TEST(CalculatePolyLineCenter)
|
||||
UNIT_TEST(CalculateCenter)
|
||||
{
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{2, 2}
|
||||
};
|
||||
TEST_EQUAL(GetBoundingBox(points), RectD({2, 2}, {2, 2}), ());
|
||||
vector<PointD> const points{{2, 2}};
|
||||
TEST_EQUAL(GetBoundingBox(points), RectD({2, 2}, {2, 2}), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}
|
||||
};
|
||||
vector<PointD> const points{{0, 0}, {1, 1}, {2, 2}};
|
||||
TEST_EQUAL(GetBoundingBox(points), RectD({0, 0}, {2, 2}), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{2, 0}
|
||||
};
|
||||
vector<PointD> const points{{0, 2}, {1, 1}, {2, 2}, {1, 2}, {2, 2}, {2, 0}};
|
||||
TEST_EQUAL(GetBoundingBox(points), RectD({0, 0}, {2, 2}), ());
|
||||
}
|
||||
}
|
||||
@@ -125,45 +88,30 @@ UNIT_TEST(CalculateCenter)
|
||||
UNIT_TEST(CalculatePointOnSurface)
|
||||
{
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2}
|
||||
};
|
||||
vector<PointD> const points{{0, 0}, {1, 1}, {2, 2}};
|
||||
TEST_EQUAL(GetPointOnSurface(points), PointD(1, 1), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 2},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{2, 0}
|
||||
};
|
||||
vector<PointD> const points{{0, 2}, {1, 1}, {2, 2}, {1, 2}, {2, 2}, {2, 0}};
|
||||
TEST_EQUAL(GetPointOnSurface(points), PointD(1, 1), ());
|
||||
}
|
||||
{
|
||||
vector<PointD> const points {
|
||||
{0, 0}, {1, 1}, {2, 0},
|
||||
{1, 1}, {2, 0}, {3, 1}, // Center of this triangle is used as a result.
|
||||
{2, 0}, {3, 1}, {4, 0},
|
||||
vector<PointD> const points{
|
||||
{0, 0}, {1, 1}, {2, 0}, {1, 1}, {2, 0}, {3, 1}, // Center of this triangle is used as a result.
|
||||
{2, 0}, {3, 1}, {4, 0},
|
||||
|
||||
{4, 0}, {3, 1}, {4, 2},
|
||||
{3, 1}, {4, 2}, {3, 3}, // Or this.
|
||||
{4, 2}, {3, 3}, {4, 4},
|
||||
{4, 0}, {3, 1}, {4, 2}, {3, 1}, {4, 2}, {3, 3}, // Or this.
|
||||
{4, 2}, {3, 3}, {4, 4},
|
||||
|
||||
{3, 3}, {4, 4}, {2, 4},
|
||||
{3, 3}, {2, 4}, {1, 3}, // Or this.
|
||||
{1, 3}, {2, 4}, {0, 4},
|
||||
{3, 3}, {4, 4}, {2, 4}, {3, 3}, {2, 4}, {1, 3}, // Or this.
|
||||
{1, 3}, {2, 4}, {0, 4},
|
||||
|
||||
{0, 4}, {1, 3}, {0, 2},
|
||||
{1, 3}, {0, 2}, {1, 1}, // Or this
|
||||
{0, 2}, {1, 1}, {0, 0},
|
||||
{0, 4}, {1, 3}, {0, 2}, {1, 3}, {0, 2}, {1, 1}, // Or this
|
||||
{0, 2}, {1, 1}, {0, 0},
|
||||
};
|
||||
auto const result = GetPointOnSurface(points);
|
||||
TEST(PointsAlmostEqual(result, {10.0 / 3.0, 2}) || PointsAlmostEqual(result, {2, 2.0 / 3.0}) ||
|
||||
PointsAlmostEqual(result, {2, 10.0 / 3.0}) || PointsAlmostEqual(result, {2.0 / 3.0, 2}),
|
||||
PointsAlmostEqual(result, {2, 10.0 / 3.0}) || PointsAlmostEqual(result, {2.0 / 3.0, 2}),
|
||||
("result = ", result));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,20 +6,19 @@
|
||||
|
||||
#include "geometry/angles.hpp"
|
||||
|
||||
|
||||
using namespace test;
|
||||
using math::pi;
|
||||
|
||||
UNIT_TEST(Atan)
|
||||
{
|
||||
double const h4 = math::pi/4.0;
|
||||
double const h4 = math::pi / 4.0;
|
||||
|
||||
TEST(is_equal_atan(1, 1, h4), ());
|
||||
TEST(is_equal_atan(-1, 1, math::pi - h4), ());
|
||||
TEST(is_equal_atan(-1, -1, h4 - math::pi), ());
|
||||
TEST(is_equal_atan(1, -1, -h4), ());
|
||||
|
||||
double const hh = atan(1.0/2.0);
|
||||
double const hh = atan(1.0 / 2.0);
|
||||
|
||||
TEST(is_equal_atan(2, 1, hh), ());
|
||||
TEST(is_equal_atan(-2, 1, math::pi - hh), ());
|
||||
@@ -29,36 +28,36 @@ UNIT_TEST(Atan)
|
||||
|
||||
UNIT_TEST(Atan2)
|
||||
{
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(1, 0), pi/2.0, ());
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(-1, 0), -pi/2.0, ());
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(1, 0), pi / 2.0, ());
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(-1, 0), -pi / 2.0, ());
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(0, 1), 0.0, ());
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(0, -1), pi, ());
|
||||
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(1, 1), pi/4.0, ());
|
||||
TEST_ALMOST_EQUAL_ULPS(atan2(1, 1), pi / 4.0, ());
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void check_avg(double arr[], size_t n, double v)
|
||||
{
|
||||
ang::AverageCalc calc;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
calc.Add(arr[i]);
|
||||
void check_avg(double arr[], size_t n, double v)
|
||||
{
|
||||
ang::AverageCalc calc;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
calc.Add(arr[i]);
|
||||
|
||||
double const avg = calc.GetAverage();
|
||||
TEST(is_equal_angle(avg, v), (avg, v));
|
||||
}
|
||||
double const avg = calc.GetAverage();
|
||||
TEST(is_equal_angle(avg, v), (avg, v));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(Average)
|
||||
{
|
||||
double constexpr eps = 1.0E-3;
|
||||
|
||||
double arr1[] = { math::pi-eps, -math::pi+eps };
|
||||
double arr1[] = {math::pi - eps, -math::pi + eps};
|
||||
TEST(is_equal_angle(ang::GetMiddleAngle(arr1[0], arr1[1]), math::pi), ());
|
||||
check_avg(arr1, ARRAY_SIZE(arr1), math::pi);
|
||||
|
||||
double arr2[] = { eps, -eps };
|
||||
double arr2[] = {eps, -eps};
|
||||
TEST(is_equal_angle(ang::GetMiddleAngle(arr2[0], arr2[1]), 0.0), ());
|
||||
check_avg(arr2, ARRAY_SIZE(arr2), 0.0);
|
||||
}
|
||||
@@ -75,47 +74,36 @@ UNIT_TEST(ShortestDistance)
|
||||
UNIT_TEST(TwoVectorsAngle)
|
||||
{
|
||||
double constexpr eps = 1e-10;
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(0, 0) /* p */,
|
||||
m2::Point<double>(0, 1) /* p1 */,
|
||||
m2::Point<double>(1, 0)) /* p2 */, 3 * math::pi2, eps), ());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(1, 1) /* p */,
|
||||
m2::Point<double>(2, 2) /* p1 */,
|
||||
m2::Point<double>(1, 2)) /* p2 */, math::pi4, eps), ());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(0, 0) /* p */,
|
||||
m2::Point<double>(1, 0) /* p1 */,
|
||||
m2::Point<double>(0, -1)) /* p2 */, 3 * math::pi2, eps), ());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(0, 0) /* p */,
|
||||
m2::Point<double>(1, 0) /* p1 */,
|
||||
m2::Point<double>(-1, 0)) /* p2 */, math::pi, eps), ());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(0, 0) /* p */, m2::Point<double>(0, 1) /* p1 */,
|
||||
m2::Point<double>(1, 0)) /* p2 */,
|
||||
3 * math::pi2, eps),
|
||||
());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(1, 1) /* p */, m2::Point<double>(2, 2) /* p1 */,
|
||||
m2::Point<double>(1, 2)) /* p2 */,
|
||||
math::pi4, eps),
|
||||
());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(0, 0) /* p */, m2::Point<double>(1, 0) /* p1 */,
|
||||
m2::Point<double>(0, -1)) /* p2 */,
|
||||
3 * math::pi2, eps),
|
||||
());
|
||||
TEST(AlmostEqualAbs(ang::TwoVectorsAngle(m2::Point<double>(0, 0) /* p */, m2::Point<double>(1, 0) /* p1 */,
|
||||
m2::Point<double>(-1, 0)) /* p2 */,
|
||||
math::pi, eps),
|
||||
());
|
||||
}
|
||||
|
||||
UNIT_TEST(Azimuth)
|
||||
{
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(-1, 0),
|
||||
m2::Point<double>(0, 1),
|
||||
math::pi2), -math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(-1, 0),
|
||||
m2::Point<double>(0, 1),
|
||||
0.0), math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(-1, 1),
|
||||
m2::Point<double>(1, -1),
|
||||
0.0), 3 * math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(1, 1),
|
||||
m2::Point<double>(0, 1),
|
||||
-math::pi2), 0.0), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(1, -1),
|
||||
m2::Point<double>(-1, -1),
|
||||
math::pi), math::pi2), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0, 0),
|
||||
m2::Point<double>(-1, -1),
|
||||
math::pi4), math::pi), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0.5, -0.5),
|
||||
m2::Point<double>(-0.5, 0.5),
|
||||
math::pi4), -math::pi2), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0.1, 0.1),
|
||||
m2::Point<double>(0.2, 0.2),
|
||||
math::pi4), 0.0), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0.7, 0.7),
|
||||
m2::Point<double>(-0.2, -0.2),
|
||||
math::pi2), 3 * math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(-1, 0), m2::Point<double>(0, 1), math::pi2), -math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(-1, 0), m2::Point<double>(0, 1), 0.0), math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(-1, 1), m2::Point<double>(1, -1), 0.0), 3 * math::pi4), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(1, 1), m2::Point<double>(0, 1), -math::pi2), 0.0), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(1, -1), m2::Point<double>(-1, -1), math::pi), math::pi2), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0, 0), m2::Point<double>(-1, -1), math::pi4), math::pi), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0.5, -0.5), m2::Point<double>(-0.5, 0.5), math::pi4), -math::pi2),
|
||||
());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0.1, 0.1), m2::Point<double>(0.2, 0.2), math::pi4), 0.0), ());
|
||||
TEST(is_equal_angle(ang::Azimuth(m2::Point<double>(0.7, 0.7), m2::Point<double>(-0.2, -0.2), math::pi2),
|
||||
3 * math::pi4),
|
||||
());
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ UNIT_TEST(AnyRect_TestConvertFrom)
|
||||
AnyRectD const r(PointD(100, 100), ang::Angle<double>(math::pi / 6), RectD(0, 0, 10, 10));
|
||||
|
||||
double const sqrt3 = sqrt(3.0);
|
||||
TEST(r.ConvertFrom(PointD(50, 0)).EqualDxDy(PointD(100 + 50 * sqrt3 / 2 , 100 + 50 * 1 / 2.0), 10e-5), ());
|
||||
TEST(r.ConvertFrom(PointD(50, 0)).EqualDxDy(PointD(100 + 50 * sqrt3 / 2, 100 + 50 * 1 / 2.0), 10e-5), ());
|
||||
TEST(r.ConvertTo(PointD(100 + 50 * sqrt3 / 2, 100 + 50 * 1.0 / 2)).EqualDxDy(PointD(50, 0), 10e-5), ());
|
||||
}
|
||||
|
||||
|
||||
@@ -11,28 +11,18 @@
|
||||
UNIT_TEST(AreaOnEarth_Circle)
|
||||
{
|
||||
double const kEarthSurfaceArea = 4.0 * math::pi * ms::kEarthRadiusMeters * ms::kEarthRadiusMeters;
|
||||
TEST_ALMOST_EQUAL_ABS(ms::CircleAreaOnEarth(math::pi * ms::kEarthRadiusMeters),
|
||||
kEarthSurfaceArea,
|
||||
1e-1, ());
|
||||
TEST_ALMOST_EQUAL_ABS(ms::CircleAreaOnEarth(math::pi * ms::kEarthRadiusMeters), kEarthSurfaceArea, 1e-1, ());
|
||||
|
||||
TEST_ALMOST_EQUAL_ABS(ms::CircleAreaOnEarth(2.0 /* radiusMeters */),
|
||||
math::pi * 2.0 * 2.0,
|
||||
1e-2, ());
|
||||
TEST_ALMOST_EQUAL_ABS(ms::CircleAreaOnEarth(2.0 /* radiusMeters */), math::pi * 2.0 * 2.0, 1e-2, ());
|
||||
|
||||
TEST_ALMOST_EQUAL_ABS(ms::CircleAreaOnEarth(2000.0 /* radiusMeters */),
|
||||
math::pi * 2000.0 * 2000.0,
|
||||
1.0, ());
|
||||
TEST_ALMOST_EQUAL_ABS(ms::CircleAreaOnEarth(2000.0 /* radiusMeters */), math::pi * 2000.0 * 2000.0, 1.0, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(AreaOnEarth_ThreePoints)
|
||||
{
|
||||
double const kEarthSurfaceArea = 4.0 * math::pi * ms::kEarthRadiusMeters * ms::kEarthRadiusMeters;
|
||||
|
||||
TEST_ALMOST_EQUAL_ABS(ms::AreaOnEarth({90.0, 0.0}, {0.0, 0.0}, {0.0, 90.0}),
|
||||
kEarthSurfaceArea / 8.0,
|
||||
1e-1, ());
|
||||
TEST_ALMOST_EQUAL_ABS(ms::AreaOnEarth({90.0, 0.0}, {0.0, 0.0}, {0.0, 90.0}), kEarthSurfaceArea / 8.0, 1e-1, ());
|
||||
|
||||
TEST_ALMOST_EQUAL_ABS(ms::AreaOnEarth({90.0, 0.0}, {0.0, 90.0}, {0.0, -90.0}),
|
||||
kEarthSurfaceArea / 4.0,
|
||||
1e-1, ());
|
||||
TEST_ALMOST_EQUAL_ABS(ms::AreaOnEarth({90.0, 0.0}, {0.0, 90.0}, {0.0, -90.0}), kEarthSurfaceArea / 4.0, 1e-1, ());
|
||||
}
|
||||
|
||||
@@ -30,4 +30,4 @@ UNIT_TEST(BoundingBox_Smoke)
|
||||
TEST(bbox.HasPoint(0.5, 0.5), ());
|
||||
}
|
||||
}
|
||||
} // namespace bounding_box_tests
|
||||
} // namespace bounding_box_tests
|
||||
|
||||
@@ -48,18 +48,16 @@ UNIT_TEST(CalipersBox_Smoke)
|
||||
vector<PointD> const points = {
|
||||
{PointD(0, 0), PointD(-2, 3), PointD(1, 5), PointD(3, 2), PointD(1, 2), PointD(0, 3)}};
|
||||
CalipersBox const cbox(points);
|
||||
TEST_EQUAL(cbox.Points(),
|
||||
(vector<PointD>{{PointD(-2, 3), PointD(0, 0), PointD(3, 2), PointD(1, 5)}}), ());
|
||||
TEST_EQUAL(cbox.Points(), (vector<PointD>{{PointD(-2, 3), PointD(0, 0), PointD(3, 2), PointD(1, 5)}}), ());
|
||||
for (auto const & p : points)
|
||||
TEST(cbox.HasPoint(p), (p));
|
||||
TEST(!cbox.HasPoint(1, 0), ());
|
||||
}
|
||||
|
||||
{
|
||||
vector<PointD> const points = {{PointD(0, 0), PointD(1, 0), PointD(0, 5), PointD(1, 5),
|
||||
PointD(-2, 2), PointD(-2, 3), PointD(3, 2), PointD(3, 3)}};
|
||||
vector<PointD> const expected = {
|
||||
{PointD(-2.5, 2.5), PointD(0.5, -0.5), PointD(3.5, 2.5), PointD(0.5, 5.5)}};
|
||||
vector<PointD> const points = {{PointD(0, 0), PointD(1, 0), PointD(0, 5), PointD(1, 5), PointD(-2, 2),
|
||||
PointD(-2, 3), PointD(3, 2), PointD(3, 3)}};
|
||||
vector<PointD> const expected = {{PointD(-2.5, 2.5), PointD(0.5, -0.5), PointD(3.5, 2.5), PointD(0.5, 5.5)}};
|
||||
CalipersBox const cbox(points);
|
||||
TEST_EQUAL(cbox.Points(), expected, ());
|
||||
|
||||
|
||||
@@ -175,7 +175,8 @@ UNIT_TEST(CellId_LessQueueOrder)
|
||||
}
|
||||
sort(tst.begin(), tst.end(), m2::CellId<4>::LessLevelOrder());
|
||||
TEST_EQUAL(tst, exp, ());
|
||||
} while (next_permutation(e.begin(), e.end()));
|
||||
}
|
||||
while (next_permutation(e.begin(), e.end()));
|
||||
}
|
||||
|
||||
UNIT_TEST(CellId_LessStackOrder)
|
||||
@@ -199,7 +200,8 @@ UNIT_TEST(CellId_LessStackOrder)
|
||||
}
|
||||
sort(tst.begin(), tst.end(), m2::CellId<4>::LessPreOrder());
|
||||
TEST_EQUAL(tst, exp, ());
|
||||
} while (next_permutation(e.begin(), e.end()));
|
||||
}
|
||||
while (next_permutation(e.begin(), e.end()));
|
||||
}
|
||||
|
||||
UNIT_TEST(CellId_IsStringValid)
|
||||
@@ -228,27 +230,8 @@ UNIT_TEST(CellId_ToAndFromInt64ZOrder)
|
||||
}
|
||||
|
||||
vector<string> const atDepth3 = {
|
||||
"",
|
||||
"0",
|
||||
"00",
|
||||
"01",
|
||||
"02",
|
||||
"03",
|
||||
"1",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"2",
|
||||
"20",
|
||||
"21",
|
||||
"22",
|
||||
"23",
|
||||
"3",
|
||||
"30",
|
||||
"31",
|
||||
"32",
|
||||
"33",
|
||||
"", "0", "00", "01", "02", "03", "1", "10", "11", "12", "13",
|
||||
"2", "20", "21", "22", "23", "3", "30", "31", "32", "33",
|
||||
};
|
||||
|
||||
for (uint64_t id = 1; id <= atDepth3.size(); ++id)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "geometry/distance_on_sphere.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/circle_on_earth.hpp"
|
||||
#include "geometry/distance_on_sphere.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include "base/math.hpp"
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
void TestGeometryAlmostEqualAbs(std::vector<m2::PointD> const & geometry,
|
||||
std::vector<m2::PointD> const & answer,
|
||||
void TestGeometryAlmostEqualAbs(std::vector<m2::PointD> const & geometry, std::vector<m2::PointD> const & answer,
|
||||
double eps)
|
||||
{
|
||||
TEST_EQUAL(geometry.size(), answer.size(), ());
|
||||
@@ -22,9 +21,8 @@ void TestGeometryAlmostEqualAbs(std::vector<m2::PointD> const & geometry,
|
||||
TEST_ALMOST_EQUAL_ABS(geometry[i], answer[i], eps, ());
|
||||
}
|
||||
|
||||
void TestGeometryAlmostEqualMeters(std::vector<m2::PointD> const & geometry,
|
||||
std::vector<m2::PointD> const & answer,
|
||||
double epsMeters)
|
||||
void TestGeometryAlmostEqualMeters(std::vector<m2::PointD> const & geometry, std::vector<m2::PointD> const & answer,
|
||||
double epsMeters)
|
||||
{
|
||||
TEST_EQUAL(geometry.size(), answer.size(), ());
|
||||
|
||||
@@ -37,15 +35,10 @@ UNIT_TEST(CircleOnEarth)
|
||||
{
|
||||
ms::LatLon const center(90.0 /* lat */, 0.0 /* lon */);
|
||||
double const radiusMeters = 2.0 * math::pi * ms::kEarthRadiusMeters / 4.0;
|
||||
auto const geometry =
|
||||
ms::CreateCircleGeometryOnEarth(center, radiusMeters, 90.0 /* angleStepDegree */);
|
||||
auto const geometry = ms::CreateCircleGeometryOnEarth(center, radiusMeters, 90.0 /* angleStepDegree */);
|
||||
|
||||
std::vector<m2::PointD> const result = {
|
||||
mercator::FromLatLon(0.0, 0.0),
|
||||
mercator::FromLatLon(0.0, 90.0),
|
||||
mercator::FromLatLon(0.0, 180.0),
|
||||
mercator::FromLatLon(0.0, -90.0)
|
||||
};
|
||||
std::vector<m2::PointD> const result = {mercator::FromLatLon(0.0, 0.0), mercator::FromLatLon(0.0, 90.0),
|
||||
mercator::FromLatLon(0.0, 180.0), mercator::FromLatLon(0.0, -90.0)};
|
||||
|
||||
TestGeometryAlmostEqualAbs(geometry, result, 1e-9 /* eps */);
|
||||
}
|
||||
@@ -68,15 +61,13 @@ UNIT_TEST(CircleOnEarthEquator)
|
||||
while (angleSumRad < 2 * math::pi)
|
||||
{
|
||||
angleSumRad += kStepRad;
|
||||
result.emplace_back(point.x + kRadiusMercator * cos(angleRad),
|
||||
point.y + kRadiusMercator * sin(angleRad));
|
||||
result.emplace_back(point.x + kRadiusMercator * cos(angleRad), point.y + kRadiusMercator * sin(angleRad));
|
||||
angleRad += kStepRad;
|
||||
if (angleRad > 2 * math::pi)
|
||||
angleRad -= 2 * math::pi;
|
||||
}
|
||||
|
||||
auto const geometry =
|
||||
ms::CreateCircleGeometryOnEarth(center, kRadiusMeters, kAngleStepDegree);
|
||||
auto const geometry = ms::CreateCircleGeometryOnEarth(center, kRadiusMeters, kAngleStepDegree);
|
||||
|
||||
TestGeometryAlmostEqualMeters(geometry, result, 20.0 /* epsMeters */);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result1.push_back(p2);
|
||||
result1.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult1 = { m2::PointD(0.5, 0.5), m2::PointD(0.5, -0.5), m2::PointD(0.0, 0.0) };
|
||||
vector<m2::PointD> expectedResult1 = {m2::PointD(0.5, 0.5), m2::PointD(0.5, -0.5), m2::PointD(0.0, 0.0)};
|
||||
TEST(CompareTriangleLists(result1, expectedResult1), (result1, expectedResult1));
|
||||
|
||||
// 1 point inside.
|
||||
@@ -84,7 +84,7 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result2.push_back(p2);
|
||||
result2.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult2 = { m2::PointD(0.0, 0.0), m2::PointD(1.0, 1.0), m2::PointD(1.0, -1.0) };
|
||||
vector<m2::PointD> expectedResult2 = {m2::PointD(0.0, 0.0), m2::PointD(1.0, 1.0), m2::PointD(1.0, -1.0)};
|
||||
TEST(CompareTriangleLists(result2, expectedResult2), (result2, expectedResult2));
|
||||
|
||||
// 2 points inside.
|
||||
@@ -96,8 +96,8 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result3.push_back(p2);
|
||||
result3.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult3 = { m2::PointD(0.0, 0.5), m2::PointD(1.0, 0.25), m2::PointD(1.0, -0.25),
|
||||
m2::PointD(0.0, 0.5), m2::PointD(1.0, -0.25), m2::PointD(0.0, -0.5) };
|
||||
vector<m2::PointD> expectedResult3 = {m2::PointD(0.0, 0.5), m2::PointD(1.0, 0.25), m2::PointD(1.0, -0.25),
|
||||
m2::PointD(0.0, 0.5), m2::PointD(1.0, -0.25), m2::PointD(0.0, -0.5)};
|
||||
TEST(CompareTriangleLists(result3, expectedResult3), (result3, expectedResult3));
|
||||
|
||||
// 2 edges clipping.
|
||||
@@ -109,9 +109,9 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result4.push_back(p2);
|
||||
result4.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult4 = { m2::PointD(0.0, 0.0), m2::PointD(0.0, 1.0), m2::PointD(0.5, 1.0),
|
||||
m2::PointD(0.0, 0.0), m2::PointD(0.5, 1.0), m2::PointD(1.0, 0.5),
|
||||
m2::PointD(0.0, 0.0), m2::PointD(1.0, 0.5), m2::PointD(1.0, 0.0) };
|
||||
vector<m2::PointD> expectedResult4 = {m2::PointD(0.0, 0.0), m2::PointD(0.0, 1.0), m2::PointD(0.5, 1.0),
|
||||
m2::PointD(0.0, 0.0), m2::PointD(0.5, 1.0), m2::PointD(1.0, 0.5),
|
||||
m2::PointD(0.0, 0.0), m2::PointD(1.0, 0.5), m2::PointD(1.0, 0.0)};
|
||||
TEST(CompareTriangleLists(result4, expectedResult4), (result4, expectedResult4));
|
||||
|
||||
// 3 edges clipping.
|
||||
@@ -123,10 +123,10 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result5.push_back(p2);
|
||||
result5.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult5 = { m2::PointD(-1.0, 0.5), m2::PointD(-0.5, 1.0), m2::PointD(0.5, 1.0),
|
||||
m2::PointD(-1.0, 0.5), m2::PointD(0.5, 1.0), m2::PointD(1.0, 0.5),
|
||||
m2::PointD(-1.0, 0.5), m2::PointD(1.0, 0.5), m2::PointD(1.0, 0.0),
|
||||
m2::PointD(-1.0, 0.5), m2::PointD(1.0, 0.0), m2::PointD(-1.0, 0.0) };
|
||||
vector<m2::PointD> expectedResult5 = {m2::PointD(-1.0, 0.5), m2::PointD(-0.5, 1.0), m2::PointD(0.5, 1.0),
|
||||
m2::PointD(-1.0, 0.5), m2::PointD(0.5, 1.0), m2::PointD(1.0, 0.5),
|
||||
m2::PointD(-1.0, 0.5), m2::PointD(1.0, 0.5), m2::PointD(1.0, 0.0),
|
||||
m2::PointD(-1.0, 0.5), m2::PointD(1.0, 0.0), m2::PointD(-1.0, 0.0)};
|
||||
TEST(CompareTriangleLists(result5, expectedResult5), (result5, expectedResult5));
|
||||
|
||||
// Completely outside.
|
||||
@@ -150,8 +150,8 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result7.push_back(p2);
|
||||
result7.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult7 = { m2::PointD(0.5, 0.5), m2::PointD(0.5, 1.0), m2::PointD(1.0, 1.0),
|
||||
m2::PointD(0.5, 0.5), m2::PointD(1.0, 1.0), m2::PointD(1.0, 0.5) };
|
||||
vector<m2::PointD> expectedResult7 = {m2::PointD(0.5, 0.5), m2::PointD(0.5, 1.0), m2::PointD(1.0, 1.0),
|
||||
m2::PointD(0.5, 0.5), m2::PointD(1.0, 1.0), m2::PointD(1.0, 0.5)};
|
||||
TEST(CompareTriangleLists(result7, expectedResult7), (result7, expectedResult7));
|
||||
|
||||
// Triangle covers rect.
|
||||
@@ -163,8 +163,8 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result8.push_back(p2);
|
||||
result8.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult8 = { m2::PointD(-1.0, 1.0), m2::PointD(1.0, 1.0), m2::PointD(1.0, -1.0),
|
||||
m2::PointD(1.0, -1.0), m2::PointD(-1.0, -1.0), m2::PointD(-1.0, 1.0) };
|
||||
vector<m2::PointD> expectedResult8 = {m2::PointD(-1.0, 1.0), m2::PointD(1.0, 1.0), m2::PointD(1.0, -1.0),
|
||||
m2::PointD(1.0, -1.0), m2::PointD(-1.0, -1.0), m2::PointD(-1.0, 1.0)};
|
||||
TEST(CompareTriangleLists(result8, expectedResult8), (result8, expectedResult8));
|
||||
|
||||
// Clip with an angle of rect.
|
||||
@@ -176,7 +176,7 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result9.push_back(p2);
|
||||
result9.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult9 = { m2::PointD(0.5, -1.0), m2::PointD(1.0, -0.5), m2::PointD(1.0, -1.0) };
|
||||
vector<m2::PointD> expectedResult9 = {m2::PointD(0.5, -1.0), m2::PointD(1.0, -0.5), m2::PointD(1.0, -1.0)};
|
||||
TEST(CompareTriangleLists(result9, expectedResult9), (result9, expectedResult9));
|
||||
|
||||
// Clip with an angle of rect.
|
||||
@@ -188,8 +188,8 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result10.push_back(p2);
|
||||
result10.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult10 = { m2::PointD(-1.0, -0.5), m2::PointD(-0.5, -0.5), m2::PointD(-0.5, -1.0),
|
||||
m2::PointD(-1.0, -0.5), m2::PointD(-0.5, -1.0), m2::PointD(-1.0, -1.0) };
|
||||
vector<m2::PointD> expectedResult10 = {m2::PointD(-1.0, -0.5), m2::PointD(-0.5, -0.5), m2::PointD(-0.5, -1.0),
|
||||
m2::PointD(-1.0, -0.5), m2::PointD(-0.5, -1.0), m2::PointD(-1.0, -1.0)};
|
||||
TEST(CompareTriangleLists(result10, expectedResult10), (result10, expectedResult10));
|
||||
|
||||
// Clip with 3 angles of rect.
|
||||
@@ -201,9 +201,9 @@ UNIT_TEST(Clipping_ClipTriangleByRect)
|
||||
result11.push_back(p2);
|
||||
result11.push_back(p3);
|
||||
});
|
||||
vector<m2::PointD> expectedResult11 = { m2::PointD(0.0, -1.0), m2::PointD(-1.0, 0.0), m2::PointD(-1.0, 1.0),
|
||||
m2::PointD(0.0, -1.0), m2::PointD(-1.0, 1.0), m2::PointD(1.0, 1.0),
|
||||
m2::PointD(0.0, -1.0), m2::PointD(1.0, 1.0), m2::PointD(1.0, -1.0) };
|
||||
vector<m2::PointD> expectedResult11 = {m2::PointD(0.0, -1.0), m2::PointD(-1.0, 0.0), m2::PointD(-1.0, 1.0),
|
||||
m2::PointD(0.0, -1.0), m2::PointD(-1.0, 1.0), m2::PointD(1.0, 1.0),
|
||||
m2::PointD(0.0, -1.0), m2::PointD(1.0, 1.0), m2::PointD(1.0, -1.0)};
|
||||
TEST(CompareTriangleLists(result11, expectedResult11), (result11, expectedResult11));
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ UNIT_TEST(Clipping_ClipSplineByRect)
|
||||
spline1->AddPoint(m2::PointD(-2.0, 0.0));
|
||||
spline1->AddPoint(m2::PointD(2.0, 1.0));
|
||||
vector<m2::SharedSpline> result1 = m2::ClipSplineByRect(r, spline1);
|
||||
vector<m2::SharedSpline> expectedResult1 = ConstructSplineList({ { m2::PointD(-1.0, 0.25), m2::PointD(1.0, 0.75) } });
|
||||
vector<m2::SharedSpline> expectedResult1 = ConstructSplineList({{m2::PointD(-1.0, 0.25), m2::PointD(1.0, 0.75)}});
|
||||
TEST(CompareSplineLists(result1, expectedResult1), ());
|
||||
|
||||
// Intersection. Several segments.
|
||||
@@ -228,8 +228,8 @@ UNIT_TEST(Clipping_ClipSplineByRect)
|
||||
spline2->AddPoint(m2::PointD(0.5, -2.0));
|
||||
spline2->AddPoint(m2::PointD(-0.5, -0.5));
|
||||
vector<m2::SharedSpline> result2 = m2::ClipSplineByRect(r, spline2);
|
||||
vector<m2::SharedSpline> expectedResult2 = ConstructSplineList({ { m2::PointD(-1.0, 0.25), m2::PointD(1.0, 0.75) },
|
||||
{ m2::PointD(-0.166666666, -1.0), m2::PointD(-0.5, -0.5) } });
|
||||
vector<m2::SharedSpline> expectedResult2 = ConstructSplineList(
|
||||
{{m2::PointD(-1.0, 0.25), m2::PointD(1.0, 0.75)}, {m2::PointD(-0.166666666, -1.0), m2::PointD(-0.5, -0.5)}});
|
||||
TEST(CompareSplineLists(result2, expectedResult2), ());
|
||||
|
||||
// Completely outside.
|
||||
@@ -247,7 +247,7 @@ UNIT_TEST(Clipping_ClipSplineByRect)
|
||||
spline4->AddPoint(m2::PointD(-0.5, 0.0));
|
||||
spline4->AddPoint(m2::PointD(0.5, 0.5));
|
||||
vector<m2::SharedSpline> result4 = m2::ClipSplineByRect(r, spline4);
|
||||
vector<m2::SharedSpline> expectedResult4 = ConstructSplineList({ { m2::PointD(-0.5, 0.0), m2::PointD(0.5, 0.5) } });
|
||||
vector<m2::SharedSpline> expectedResult4 = ConstructSplineList({{m2::PointD(-0.5, 0.0), m2::PointD(0.5, 0.5)}});
|
||||
TEST(CompareSplineLists(result4, expectedResult4), ());
|
||||
|
||||
// Intersection. Long spline.
|
||||
@@ -258,8 +258,8 @@ UNIT_TEST(Clipping_ClipSplineByRect)
|
||||
spline5->AddPoint(m2::PointD(0.5, 0.5));
|
||||
spline5->AddPoint(m2::PointD(2.0, 1.0));
|
||||
vector<m2::SharedSpline> result5 = m2::ClipSplineByRect(r, spline5);
|
||||
vector<m2::SharedSpline> expectedResult5 = ConstructSplineList({ { m2::PointD(-1.0, 0.0), m2::PointD(0.0, 0.0),
|
||||
m2::PointD(0.5, 0.5), m2::PointD(1.0, 0.66666666) } });
|
||||
vector<m2::SharedSpline> expectedResult5 = ConstructSplineList(
|
||||
{{m2::PointD(-1.0, 0.0), m2::PointD(0.0, 0.0), m2::PointD(0.5, 0.5), m2::PointD(1.0, 0.66666666)}});
|
||||
TEST(CompareSplineLists(result5, expectedResult5), ());
|
||||
|
||||
// Intersection. Several segments.
|
||||
@@ -271,8 +271,8 @@ UNIT_TEST(Clipping_ClipSplineByRect)
|
||||
spline6->AddPoint(m2::PointD(0.0, 1.5));
|
||||
spline6->AddPoint(m2::PointD(0.0, 0.0));
|
||||
vector<m2::SharedSpline> result6 = m2::ClipSplineByRect(r, spline6);
|
||||
vector<m2::SharedSpline> expectedResult6 = ConstructSplineList({ { m2::PointD(-1.0, 0.0), m2::PointD(-0.5, 1.0) },
|
||||
{ m2::PointD(0.0, 1.0), m2::PointD(0.0, 0.0) } });
|
||||
vector<m2::SharedSpline> expectedResult6 = ConstructSplineList(
|
||||
{{m2::PointD(-1.0, 0.0), m2::PointD(-0.5, 1.0)}, {m2::PointD(0.0, 1.0), m2::PointD(0.0, 0.0)}});
|
||||
TEST(CompareSplineLists(result6, expectedResult6), ());
|
||||
}
|
||||
} // namespace clipping_test
|
||||
} // namespace clipping_test
|
||||
|
||||
@@ -12,7 +12,7 @@ UNIT_TEST(Rect)
|
||||
{
|
||||
m2::RectD rect(0, 0, 500, 300);
|
||||
|
||||
double factor[] = { 0.2, 0.3, 0.5, 0.7, 1.0, 1.3, 1.5, 2.0 };
|
||||
double factor[] = {0.2, 0.3, 0.5, 0.7, 1.0, 1.3, 1.5, 2.0};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(factor); ++i)
|
||||
{
|
||||
m2::RectD r(rect);
|
||||
@@ -35,5 +35,5 @@ UNIT_TEST(Point)
|
||||
TEST(is_equal(start.Move(l, a), m2::PointD(1, 1)), ());
|
||||
TEST(is_equal(start.Move(l, math::pi - a), m2::PointD(-1, 1)), ());
|
||||
TEST(is_equal(start.Move(l, -math::pi + a), m2::PointD(-1, -1)), ());
|
||||
TEST(is_equal(start.Move(l, - a), m2::PointD(1, -1)), ());
|
||||
TEST(is_equal(start.Move(l, -a), m2::PointD(1, -1)), ());
|
||||
}
|
||||
|
||||
@@ -23,28 +23,24 @@ UNIT_TEST(ConvexHull_Smoke)
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0)}), vector<PointD>{PointD(0, 0)}, ());
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0), PointD(0, 0)}), vector<PointD>{PointD(0, 0)}, ());
|
||||
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0), PointD(1, 1), PointD(0, 0)}),
|
||||
vector<PointD>({PointD(0, 0), PointD(1, 1)}), ());
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0), PointD(1, 1), PointD(0, 0)}), vector<PointD>({PointD(0, 0), PointD(1, 1)}),
|
||||
());
|
||||
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0), PointD(1, 1), PointD(2, 2)}),
|
||||
vector<PointD>({PointD(0, 0), PointD(2, 2)}), ());
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0), PointD(1, 1), PointD(2, 2)}), vector<PointD>({PointD(0, 0), PointD(2, 2)}),
|
||||
());
|
||||
|
||||
{
|
||||
int const kXMax = 100;
|
||||
int const kYMax = 200;
|
||||
vector<PointD> points;
|
||||
for (int x = 0; x <= kXMax; ++x)
|
||||
{
|
||||
for (int y = 0; y <= kYMax; ++y)
|
||||
points.emplace_back(x, y);
|
||||
}
|
||||
TEST_EQUAL(BuildConvexHull(points), vector<PointD>({PointD(0, 0), PointD(kXMax, 0),
|
||||
PointD(kXMax, kYMax), PointD(0, kYMax)}),
|
||||
());
|
||||
TEST_EQUAL(BuildConvexHull(points),
|
||||
vector<PointD>({PointD(0, 0), PointD(kXMax, 0), PointD(kXMax, kYMax), PointD(0, kYMax)}), ());
|
||||
}
|
||||
|
||||
TEST_EQUAL(
|
||||
BuildConvexHull({PointD(0, 0), PointD(0, 5), PointD(10, 5), PointD(3, 3), PointD(10, 0)}),
|
||||
vector<PointD>({PointD(0, 0), PointD(10, 0), PointD(10, 5), PointD(0, 5)}), ());
|
||||
TEST_EQUAL(BuildConvexHull({PointD(0, 0), PointD(0, 5), PointD(10, 5), PointD(3, 3), PointD(10, 0)}),
|
||||
vector<PointD>({PointD(0, 0), PointD(10, 0), PointD(10, 5), PointD(0, 5)}), ());
|
||||
}
|
||||
} // namespace convex_hull_tests
|
||||
|
||||
@@ -20,7 +20,7 @@ using CellId = m2::CellId<5>;
|
||||
UNIT_TEST(CoverTriangle_Simple)
|
||||
{
|
||||
vector<CellId> v;
|
||||
covering::Covering<CellId> c(m2::PointD(3*2, 3*2), m2::PointD(4*2, 12*2), m2::PointD(14*2, 3*2));
|
||||
covering::Covering<CellId> c(m2::PointD(3 * 2, 3 * 2), m2::PointD(4 * 2, 12 * 2), m2::PointD(14 * 2, 3 * 2));
|
||||
c.OutputToVector(v);
|
||||
vector<CellId> e;
|
||||
e.push_back(CellId("03"));
|
||||
@@ -97,14 +97,10 @@ UNIT_TEST(Covering_Append_Simple)
|
||||
UNIT_TEST(IntersectCellWithTriangle_EmptyTriangle)
|
||||
{
|
||||
m2::PointD pt(27.0, 31.0);
|
||||
TEST_EQUAL(covering::CELL_OBJECT_NO_INTERSECTION,
|
||||
covering::IntersectCellWithTriangle(CellId("0"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::CELL_OBJECT_NO_INTERSECTION,
|
||||
covering::IntersectCellWithTriangle(CellId("1"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::CELL_OBJECT_NO_INTERSECTION,
|
||||
covering::IntersectCellWithTriangle(CellId("2"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::OBJECT_INSIDE_CELL,
|
||||
covering::IntersectCellWithTriangle(CellId("3"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::CELL_OBJECT_NO_INTERSECTION, covering::IntersectCellWithTriangle(CellId("0"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::CELL_OBJECT_NO_INTERSECTION, covering::IntersectCellWithTriangle(CellId("1"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::CELL_OBJECT_NO_INTERSECTION, covering::IntersectCellWithTriangle(CellId("2"), pt, pt, pt), ());
|
||||
TEST_EQUAL(covering::OBJECT_INSIDE_CELL, covering::IntersectCellWithTriangle(CellId("3"), pt, pt, pt), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Covering_EmptyTriangle)
|
||||
|
||||
@@ -6,48 +6,44 @@
|
||||
|
||||
namespace test
|
||||
{
|
||||
inline bool is_equal(double a1, double a2)
|
||||
{
|
||||
return (fabs(a1 - a2) < 1.0E-10);
|
||||
}
|
||||
|
||||
inline bool is_equal_atan(double x, double y, double v)
|
||||
{
|
||||
return is_equal(ang::AngleTo(m2::PointD(0, 0), m2::PointD(x, y)), v);
|
||||
}
|
||||
|
||||
inline bool is_equal_angle(double a1, double a2)
|
||||
{
|
||||
double const two_pi = 2.0*math::pi;
|
||||
if (a1 < 0.0) a1 += two_pi;
|
||||
if (a2 < 0.0) a2 += two_pi;
|
||||
|
||||
return is_equal(a1, a2);
|
||||
}
|
||||
|
||||
inline bool is_equal(m2::PointD const & p1, m2::PointD const & p2)
|
||||
{
|
||||
return p1.EqualDxDy(p2, 1.0E-8);
|
||||
}
|
||||
|
||||
inline bool is_equal_center(m2::RectD const & r1, m2::RectD const & r2)
|
||||
{
|
||||
return is_equal(r1.Center(), r2.Center());
|
||||
}
|
||||
|
||||
struct strict_equal
|
||||
{
|
||||
bool operator() (m2::PointD const & p1, m2::PointD const & p2) const
|
||||
{
|
||||
return p1 == p2;
|
||||
}
|
||||
};
|
||||
|
||||
struct epsilon_equal
|
||||
{
|
||||
bool operator() (m2::PointD const & p1, m2::PointD const & p2) const
|
||||
{
|
||||
return is_equal(p1, p2);
|
||||
}
|
||||
};
|
||||
inline bool is_equal(double a1, double a2)
|
||||
{
|
||||
return (fabs(a1 - a2) < 1.0E-10);
|
||||
}
|
||||
|
||||
inline bool is_equal_atan(double x, double y, double v)
|
||||
{
|
||||
return is_equal(ang::AngleTo(m2::PointD(0, 0), m2::PointD(x, y)), v);
|
||||
}
|
||||
|
||||
inline bool is_equal_angle(double a1, double a2)
|
||||
{
|
||||
double const two_pi = 2.0 * math::pi;
|
||||
if (a1 < 0.0)
|
||||
a1 += two_pi;
|
||||
if (a2 < 0.0)
|
||||
a2 += two_pi;
|
||||
|
||||
return is_equal(a1, a2);
|
||||
}
|
||||
|
||||
inline bool is_equal(m2::PointD const & p1, m2::PointD const & p2)
|
||||
{
|
||||
return p1.EqualDxDy(p2, 1.0E-8);
|
||||
}
|
||||
|
||||
inline bool is_equal_center(m2::RectD const & r1, m2::RectD const & r2)
|
||||
{
|
||||
return is_equal(r1.Center(), r2.Center());
|
||||
}
|
||||
|
||||
struct strict_equal
|
||||
{
|
||||
bool operator()(m2::PointD const & p1, m2::PointD const & p2) const { return p1 == p2; }
|
||||
};
|
||||
|
||||
struct epsilon_equal
|
||||
{
|
||||
bool operator()(m2::PointD const & p1, m2::PointD const & p2) const { return is_equal(p1, p2); }
|
||||
};
|
||||
} // namespace test
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "geometry/rect_intersect.hpp"
|
||||
#include "geometry/angles.hpp"
|
||||
|
||||
#include "geometry/rect_intersect.hpp"
|
||||
|
||||
using namespace test;
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef m2::PointD P;
|
||||
typedef m2::PointD P;
|
||||
}
|
||||
|
||||
m2::PointD get_point(m2::RectD const & r, int ind)
|
||||
@@ -21,9 +20,7 @@ m2::PointD get_point(m2::RectD const & r, int ind)
|
||||
case 1: return r.LeftTop();
|
||||
case 2: return r.RightTop();
|
||||
case 3: return r.RightBottom();
|
||||
default:
|
||||
ASSERT ( false, () );
|
||||
return m2::PointD();
|
||||
default: ASSERT(false, ()); return m2::PointD();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +28,16 @@ void make_section_longer(m2::PointD & p1, m2::PointD & p2, double sm)
|
||||
{
|
||||
if (p1.x == p2.x)
|
||||
{
|
||||
if (p1.y > p2.y) sm = -sm;
|
||||
if (p1.y > p2.y)
|
||||
sm = -sm;
|
||||
|
||||
p1.y -= sm;
|
||||
p2.y += sm;
|
||||
}
|
||||
else if (p1.y == p2.y)
|
||||
{
|
||||
if (p1.x > p2.x) sm = -sm;
|
||||
if (p1.x > p2.x)
|
||||
sm = -sm;
|
||||
|
||||
p1.x -= sm;
|
||||
p2.x += sm;
|
||||
@@ -74,8 +73,8 @@ void check_intersect_boundaries(m2::RectD const & r)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
check_full_equal(r, get_point(r, i), get_point(r, i+1), strict_equal());
|
||||
check_inside(r, get_point(r, i), get_point(r, i+1));
|
||||
check_full_equal(r, get_point(r, i), get_point(r, i + 1), strict_equal());
|
||||
check_inside(r, get_point(r, i), get_point(r, i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +82,8 @@ void check_intersect_diagonal(m2::RectD const & r)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
check_full_equal(r, get_point(r, i), get_point(r, i+2), epsilon_equal());
|
||||
check_inside(r, get_point(r, i), get_point(r, i+2));
|
||||
check_full_equal(r, get_point(r, i), get_point(r, i + 2), epsilon_equal());
|
||||
check_inside(r, get_point(r, i), get_point(r, i + 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,8 +91,8 @@ void check_sides(m2::RectD const & r)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
m2::PointD p1 = (get_point(r, i) + get_point(r, i+1)) / 2.0;
|
||||
m2::PointD p2 = (get_point(r, i + 2) + get_point(r, i+3)) / 2.0;
|
||||
m2::PointD p1 = (get_point(r, i) + get_point(r, i + 1)) / 2.0;
|
||||
m2::PointD p2 = (get_point(r, i + 2) + get_point(r, i + 3)) / 2.0;
|
||||
check_full_equal(r, p1, p2, strict_equal());
|
||||
check_inside(r, p1, p2);
|
||||
}
|
||||
@@ -107,7 +106,7 @@ void check_eps_boundaries(m2::RectD const & r, double eps = 1.0E-6)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
m2::PointD p1 = get_point(rr, i);
|
||||
m2::PointD p2 = get_point(rr, i+1);
|
||||
m2::PointD p2 = get_point(rr, i + 1);
|
||||
|
||||
TEST(!m2::Intersect(r, p1, p2), ());
|
||||
}
|
||||
@@ -116,7 +115,7 @@ void check_eps_boundaries(m2::RectD const & r, double eps = 1.0E-6)
|
||||
rr.Inflate(-eps, -eps);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
check_inside(r, get_point(rr, i), get_point(rr, i+1));
|
||||
check_inside(r, get_point(rr, i), get_point(rr, i + 1));
|
||||
}
|
||||
|
||||
UNIT_TEST(IntersectRect_Section)
|
||||
@@ -130,15 +129,15 @@ UNIT_TEST(IntersectRect_Section)
|
||||
|
||||
namespace
|
||||
{
|
||||
void check_point_in_rect(m2::RectD const & r, m2::PointD const & p)
|
||||
{
|
||||
m2::PointD p1 = p;
|
||||
m2::PointD p2 = p;
|
||||
void check_point_in_rect(m2::RectD const & r, m2::PointD const & p)
|
||||
{
|
||||
m2::PointD p1 = p;
|
||||
m2::PointD p2 = p;
|
||||
|
||||
TEST(m2::Intersect(r, p1, p2), ());
|
||||
TEST(p == p1 && p == p2, ());
|
||||
}
|
||||
TEST(m2::Intersect(r, p1, p2), ());
|
||||
TEST(p == p1 && p == p2, ());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(IntersectRect_Point)
|
||||
{
|
||||
@@ -147,14 +146,14 @@ UNIT_TEST(IntersectRect_Point)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
check_point_in_rect(r, get_point(r, i));
|
||||
check_point_in_rect(r, (get_point(r, i) + get_point(r, i+1)) / 2.0);
|
||||
check_point_in_rect(r, (get_point(r, i) + get_point(r, i + 1)) / 2.0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
m2::RectD r(-1000, -1000, 1000, 1000);
|
||||
double const eps = 1.0E-6;
|
||||
P sm[] = { P(-eps, -eps), P(-eps, eps), P(eps, eps), P(eps, -eps) };
|
||||
P sm[] = {P(-eps, -eps), P(-eps, eps), P(eps, eps), P(eps, -eps)};
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
P p1 = get_point(r, i);
|
||||
|
||||
@@ -65,8 +65,7 @@ UNIT_TEST(IntersectionScore_TrianglesToPolygon)
|
||||
std::vector<m2::PointD> triangiulated2 = {{0.0, 0.0}, {0.0, 9.0}, {10.0, 0.0},
|
||||
{10.0, 0.0}, {0.0, 9.0}, {10.0, 9.0}};
|
||||
|
||||
auto const score =
|
||||
geometry::GetIntersectionScoreForTriangulated(triangiulated1, triangiulated2);
|
||||
auto const score = geometry::GetIntersectionScoreForTriangulated(triangiulated1, triangiulated2);
|
||||
|
||||
TEST(AlmostEqualAbs(score, 0.9, 1e-10), ());
|
||||
}
|
||||
@@ -87,8 +86,7 @@ UNIT_TEST(IntersectionScore_TrianglesToPolygon)
|
||||
std::vector<m2::PointD> triangiulated2 = {{10.0, 10.0}, {10.0, 20.0}, {20.0, 10.0},
|
||||
{20.0, 10.0}, {10.0, 20.0}, {20.0, 20.0}};
|
||||
|
||||
auto const score =
|
||||
geometry::GetIntersectionScoreForTriangulated(triangiulated1, triangiulated2);
|
||||
auto const score = geometry::GetIntersectionScoreForTriangulated(triangiulated1, triangiulated2);
|
||||
|
||||
TEST(AlmostEqualAbs(score, 0.0, 1e-10), ());
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
#include "testing/testing.hpp"
|
||||
#include "geometry/latlon.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
UNIT_TEST(LatLonPointConstructorTest)
|
||||
{
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "base/math.hpp"
|
||||
#include "base/macros.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
#include "base/math.hpp"
|
||||
|
||||
UNIT_TEST(Mercator_Grid)
|
||||
{
|
||||
@@ -45,7 +44,7 @@ UNIT_TEST(Mercator_DirectInferseF)
|
||||
|
||||
UNIT_TEST(Mercator_ErrorToRadius)
|
||||
{
|
||||
double const points[] = { -85.0, -45.0, -10.0, -1.0, -0.003, 0.0, 0.003, 1.0, 10.0, 45.0, 85.0 };
|
||||
double const points[] = {-85.0, -45.0, -10.0, -1.0, -0.003, 0.0, 0.003, 1.0, 10.0, 45.0, 85.0};
|
||||
|
||||
double const error1 = 1.0; // 1 metre
|
||||
double const error10 = 10.0; // 10 metres
|
||||
@@ -78,6 +77,5 @@ UNIT_TEST(Mercator_ErrorToRadius)
|
||||
|
||||
UNIT_TEST(Mercator_Sample1)
|
||||
{
|
||||
LOG(LINFO, (mercator::XToLon(27.531491200000001385),
|
||||
mercator::YToLat(64.392864299248202542)));
|
||||
LOG(LINFO, (mercator::XToLon(27.531491200000001385), mercator::YToLat(64.392864299248202542)));
|
||||
}
|
||||
|
||||
@@ -68,8 +68,7 @@ UNIT_TEST(NearbyPointsSweeper_Smoke)
|
||||
|
||||
{
|
||||
uint8_t const priority = 0;
|
||||
vector<PointD> const points = {PointD(0.0, 0.0), PointD(1.0, 1.0),
|
||||
PointD(1.5, 0.0), PointD(1.5 + 1.01, 1.5 + 1.0)};
|
||||
vector<PointD> const points = {PointD(0.0, 0.0), PointD(1.0, 1.0), PointD(1.5, 0.0), PointD(1.5 + 1.01, 1.5 + 1.0)};
|
||||
NearbyPointsSweeper sweeper(1.0);
|
||||
|
||||
for (size_t i = 0; i < points.size(); ++i)
|
||||
@@ -85,9 +84,8 @@ UNIT_TEST(NearbyPointsSweeper_Smoke)
|
||||
|
||||
{
|
||||
uint8_t const priority = 0;
|
||||
vector<PointD> const points = {PointD(0, 0), PointD(0, 0), PointD(1, 0),
|
||||
PointD(0, 1), PointD(1, 1), PointD(1, 0),
|
||||
PointD(0.5, 0.5), PointD(0, 1)};
|
||||
vector<PointD> const points = {PointD(0, 0), PointD(0, 0), PointD(1, 0), PointD(0, 1),
|
||||
PointD(1, 1), PointD(1, 0), PointD(0.5, 0.5), PointD(0, 1)};
|
||||
|
||||
NearbyPointsSweeper sweeper(10.0);
|
||||
for (size_t i = 0; i < points.size(); ++i)
|
||||
@@ -130,8 +128,8 @@ UNIT_TEST(NearbyPointsSweeper_Priority)
|
||||
TEST_EQUAL(expected, actual, ());
|
||||
}
|
||||
{
|
||||
vector<pair<PointD, uint8_t>> const objects = {{PointD(0.0, 0.0), 0}, {PointD(1.0, 1.0), 1},
|
||||
{PointD(1.5, 0.0), 0}, {PointD(1.5 + 1.01, 1.5 + 1.0), 0}};
|
||||
vector<pair<PointD, uint8_t>> const objects = {
|
||||
{PointD(0.0, 0.0), 0}, {PointD(1.0, 1.0), 1}, {PointD(1.5, 0.0), 0}, {PointD(1.5 + 1.01, 1.5 + 1.0), 0}};
|
||||
NearbyPointsSweeper sweeper(1.0);
|
||||
|
||||
for (size_t i = 0; i < objects.size(); ++i)
|
||||
|
||||
@@ -12,7 +12,7 @@ void testDistance(ms::LatLon const & a, ms::LatLon const & b, double planDistanc
|
||||
double const factDistance = oblate_spheroid::GetDistance(a, b);
|
||||
TEST_ALMOST_EQUAL_ABS(factDistance, planDistance, kAccuracyEps, ());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(Distance_EdgeCaseEquatorialLine)
|
||||
{
|
||||
|
||||
@@ -36,15 +36,15 @@ UNIT_TEST(PackerTest_SimplePack)
|
||||
|
||||
m2::Packer::handle_t h2 = p.pack(5, 5);
|
||||
|
||||
// Possibly we should restore this checks
|
||||
// Possibly we should restore this checks
|
||||
|
||||
// TEST_EQUAL(p.isPacked(h0), false, ());
|
||||
// TEST_EQUAL(p.isPacked(h1), false, ());
|
||||
// TEST_EQUAL(p.isPacked(h0), false, ());
|
||||
// TEST_EQUAL(p.isPacked(h1), false, ());
|
||||
|
||||
TEST_EQUAL(p.isPacked(h2), true, ());
|
||||
|
||||
TEST_EQUAL(i, 7, ("Handlers priorities doesn't work"));
|
||||
TEST_NOT_EQUAL( i, 12, ("Handlers priorities doesn't work"));
|
||||
TEST_NOT_EQUAL(i, 12, ("Handlers priorities doesn't work"));
|
||||
|
||||
m2::RectU r2 = p.find(h2).second;
|
||||
|
||||
@@ -55,53 +55,23 @@ UNIT_TEST(PackerTest_HasRoom_Sequence)
|
||||
{
|
||||
m2::Packer p(20, 20);
|
||||
|
||||
m2::PointU pts[] = {
|
||||
m2::PointU(10, 10),
|
||||
m2::PointU(11, 3),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(5, 5)
|
||||
};
|
||||
m2::PointU pts[] = {m2::PointU(10, 10), m2::PointU(11, 3), m2::PointU(5, 5), m2::PointU(5, 5)};
|
||||
|
||||
TEST(p.hasRoom(pts, sizeof(pts) / sizeof(m2::PointU)), ());
|
||||
|
||||
m2::PointU pts1[] = {
|
||||
m2::PointU(10, 10),
|
||||
m2::PointU(11, 3),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(16, 5)
|
||||
};
|
||||
m2::PointU pts1[] = {m2::PointU(10, 10), m2::PointU(11, 3), m2::PointU(5, 5), m2::PointU(5, 5), m2::PointU(16, 5)};
|
||||
|
||||
TEST(!p.hasRoom(pts1, sizeof(pts1) / sizeof(m2::PointU)), ());
|
||||
|
||||
m2::PointU pts2[] = {
|
||||
m2::PointU(10, 10),
|
||||
m2::PointU(11, 3),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(10, 6)
|
||||
};
|
||||
m2::PointU pts2[] = {m2::PointU(10, 10), m2::PointU(11, 3), m2::PointU(5, 5), m2::PointU(5, 5), m2::PointU(10, 6)};
|
||||
|
||||
TEST(!p.hasRoom(pts2, sizeof(pts2) / sizeof(m2::PointU)), ());
|
||||
|
||||
m2::PointU pts3[] = {
|
||||
m2::PointU(10, 10),
|
||||
m2::PointU(11, 3),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(15, 5)
|
||||
};
|
||||
m2::PointU pts3[] = {m2::PointU(10, 10), m2::PointU(11, 3), m2::PointU(5, 5), m2::PointU(5, 5), m2::PointU(15, 5)};
|
||||
|
||||
TEST(p.hasRoom(pts3, sizeof(pts3) / sizeof(m2::PointU)), ());
|
||||
|
||||
m2::PointU pts4[] = {
|
||||
m2::PointU(10, 10),
|
||||
m2::PointU(11, 3),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(5, 5),
|
||||
m2::PointU(16, 5)
|
||||
};
|
||||
m2::PointU pts4[] = {m2::PointU(10, 10), m2::PointU(11, 3), m2::PointU(5, 5), m2::PointU(5, 5), m2::PointU(16, 5)};
|
||||
|
||||
TEST(!p.hasRoom(pts4, sizeof(pts4) / sizeof(m2::PointU)), ());
|
||||
|
||||
}
|
||||
|
||||
@@ -54,19 +54,12 @@ UNIT_TEST(ParametrizedSegment2D_ClosestPoint)
|
||||
{
|
||||
using P = m2::PointD;
|
||||
|
||||
P arr[][4] =
|
||||
{
|
||||
{ P(3, 4), P(0, 0), P(10, 0), P(3, 0) },
|
||||
{ P(3, 4), P(0, 0), P(0, 10), P(0, 4) },
|
||||
P arr[][4] = {{P(3, 4), P(0, 0), P(10, 0), P(3, 0)}, {P(3, 4), P(0, 0), P(0, 10), P(0, 4)},
|
||||
|
||||
{ P(3, 5), P(2, 2), P(5, 5), P(4, 4) },
|
||||
{ P(5, 3), P(2, 2), P(5, 5), P(4, 4) },
|
||||
{ P(2, 4), P(2, 2), P(5, 5), P(3, 3) },
|
||||
{ P(4, 2), P(2, 2), P(5, 5), P(3, 3) },
|
||||
{P(3, 5), P(2, 2), P(5, 5), P(4, 4)}, {P(5, 3), P(2, 2), P(5, 5), P(4, 4)},
|
||||
{P(2, 4), P(2, 2), P(5, 5), P(3, 3)}, {P(4, 2), P(2, 2), P(5, 5), P(3, 3)},
|
||||
|
||||
{ P(5, 6), P(2, 2), P(5, 5), P(5, 5) },
|
||||
{ P(1, 0), P(2, 2), P(5, 5), P(2, 2) }
|
||||
};
|
||||
{P(5, 6), P(2, 2), P(5, 5), P(5, 5)}, {P(1, 0), P(2, 2), P(5, 5), P(2, 2)}};
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
|
||||
{
|
||||
|
||||
@@ -97,4 +97,4 @@ UNIT_TEST(Point3d_RotateXYZ)
|
||||
auto const north = rotatedFirst.RotateAroundY(-angleDegree);
|
||||
TEST_ALMOST_EQUAL_ABS(north, m3::PointD(0.0, 0.0, std::sqrt(3.0)), 1e-10, ());
|
||||
}
|
||||
} // namespace point3d_tests
|
||||
} // namespace point3d_tests
|
||||
|
||||
@@ -79,19 +79,10 @@ UNIT_TEST(GetArrowPoints)
|
||||
|
||||
UNIT_TEST(PointAtSegment)
|
||||
{
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(1, 0), 0.5f),
|
||||
m2::PointF(0.5f, 0.f)),
|
||||
());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(0, 1), 0.3f),
|
||||
m2::PointF(0.f, 0.3f)),
|
||||
());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointD(0., 0.), m2::PointD(30., 40.), 5.),
|
||||
m2::PointD(3., 4.)),
|
||||
());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointF(-3, -4), m2::PointF(-30, -40), 5.f),
|
||||
m2::PointF(-6.f, -8.f)),
|
||||
());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointD(14., -48.), m2::PointD(70., -240.), 25.),
|
||||
m2::PointD(21., -72.)),
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(1, 0), 0.5f), m2::PointF(0.5f, 0.f)), ());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(0, 1), 0.3f), m2::PointF(0.f, 0.3f)), ());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointD(0., 0.), m2::PointD(30., 40.), 5.), m2::PointD(3., 4.)), ());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointF(-3, -4), m2::PointF(-30, -40), 5.f), m2::PointF(-6.f, -8.f)), ());
|
||||
TEST(AlmostEqualULPs(m2::PointAtSegment(m2::PointD(14., -48.), m2::PointD(70., -240.), 25.), m2::PointD(21., -72.)),
|
||||
());
|
||||
}
|
||||
|
||||
@@ -116,8 +116,8 @@ UNIT_TEST(FindSingleStrip)
|
||||
{
|
||||
// Minsk, Bobryiskaya str., 7
|
||||
P const poly[] = {P(53.8926922, 27.5460021), P(53.8926539, 27.5461821), P(53.8926164, 27.5461591),
|
||||
P(53.8925455, 27.5464921), P(53.8925817, 27.5465143), P(53.8925441, 27.5466909),
|
||||
P(53.8923762, 27.5465881), P(53.8925229, 27.5458984)};
|
||||
P(53.8925455, 27.5464921), P(53.8925817, 27.5465143), P(53.8925441, 27.5466909),
|
||||
P(53.8923762, 27.5465881), P(53.8925229, 27.5458984)};
|
||||
TestFindStrip(poly, ARRAY_SIZE(poly));
|
||||
}
|
||||
}
|
||||
@@ -150,15 +150,13 @@ UNIT_TEST(PolygonArea_Smoke)
|
||||
{
|
||||
{
|
||||
P arr[] = {P(-1, 0), P(0, 1), P(1, -1)};
|
||||
TEST_ALMOST_EQUAL_ULPS(m2::GetTriangleArea(arr[0], arr[1], arr[2]),
|
||||
GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
|
||||
TEST_ALMOST_EQUAL_ULPS(m2::GetTriangleArea(arr[0], arr[1], arr[2]), GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
|
||||
}
|
||||
|
||||
{
|
||||
P arr[] = {P(-5, -7), P(-3.5, 10), P(7.2, 5), P(14, -6.4)};
|
||||
TEST_ALMOST_EQUAL_ULPS(
|
||||
m2::GetTriangleArea(arr[0], arr[1], arr[2]) + m2::GetTriangleArea(arr[2], arr[3], arr[0]),
|
||||
GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
|
||||
TEST_ALMOST_EQUAL_ULPS(m2::GetTriangleArea(arr[0], arr[1], arr[2]) + m2::GetTriangleArea(arr[2], arr[3], arr[0]),
|
||||
GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace polyline_tests
|
||||
{
|
||||
double constexpr kEps = 1e-5;
|
||||
|
||||
void TestClosest(std::vector<m2::PointD> const & points, m2::PointD const & point,
|
||||
double expectedSquaredDist, uint32_t expectedIndex)
|
||||
void TestClosest(std::vector<m2::PointD> const & points, m2::PointD const & point, double expectedSquaredDist,
|
||||
uint32_t expectedIndex)
|
||||
{
|
||||
auto const closestByPoints = m2::CalcMinSquaredDistance(points.begin(), points.end(), point);
|
||||
TEST_ALMOST_EQUAL_ABS(closestByPoints.first, expectedSquaredDist, kEps, ());
|
||||
@@ -44,8 +44,7 @@ UNIT_TEST(Rect_PolylineMinDistanceTest)
|
||||
// 1 | |
|
||||
// | |
|
||||
// 0----1----2----3
|
||||
std::vector<m2::PointD> const poly = {{0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0},
|
||||
{2.0, 0.0}, {3.0, 0.0}, {3.0, 1.0}};
|
||||
std::vector<m2::PointD> const poly = {{0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}, {2.0, 0.0}, {3.0, 0.0}, {3.0, 1.0}};
|
||||
|
||||
TestClosest(poly, m2::PointD(0.0, 1.0), 0.0 /* expectedSquaredDist */, 0 /* expectedIndex */);
|
||||
TestClosest(poly, m2::PointD(0.0, 0.0), 0.0 /* expectedSquaredDist */, 0 /* expectedIndex */);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "testing/testing.hpp"
|
||||
#include "geometry/rect2d.hpp"
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
UNIT_TEST(Rect_Intersect)
|
||||
{
|
||||
@@ -19,4 +19,3 @@ UNIT_TEST(Rect_Intersect)
|
||||
TEST(r3.IsIntersect(r), ());
|
||||
TEST(r.IsIntersect(r3), ());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ using R = m2::RegionI;
|
||||
UNIT_TEST(RegionIntersect_Smoke)
|
||||
{
|
||||
{
|
||||
P arr1[] = { P(-2, 1), P(2, 1), P(2, -1), P(-2, -1) };
|
||||
P arr2[] = { P(-1, 2), P(1, 2), P(1, -2), P(-1, -2) };
|
||||
P arr1[] = {P(-2, 1), P(2, 1), P(2, -1), P(-2, -1)};
|
||||
P arr2[] = {P(-1, 2), P(1, 2), P(1, -2), P(-1, -2)};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -31,8 +31,8 @@ UNIT_TEST(RegionIntersect_Smoke)
|
||||
}
|
||||
|
||||
{
|
||||
P arr1[] = { P(0, 0), P(1, 1), P(2, 0) };
|
||||
P arr2[] = { P(0, 0), P(1, -1), P(2, 0) };
|
||||
P arr1[] = {P(0, 0), P(1, 1), P(2, 0)};
|
||||
P arr2[] = {P(0, 0), P(1, -1), P(2, 0)};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -45,8 +45,8 @@ UNIT_TEST(RegionIntersect_Smoke)
|
||||
}
|
||||
|
||||
{
|
||||
P arr1[] = { P(-10, -10), P(10, -10), P(10, 10), P(-10, 10) };
|
||||
P arr2[] = { P(-5, -5), P(5, -5), P(5, 5), P(-5, 5) };
|
||||
P arr1[] = {P(-10, -10), P(10, -10), P(10, 10), P(-10, 10)};
|
||||
P arr2[] = {P(-5, -5), P(5, -5), P(5, 5), P(-5, 5)};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -64,8 +64,8 @@ UNIT_TEST(RegionIntersect_Smoke)
|
||||
UNIT_TEST(RegionDifference_Smoke)
|
||||
{
|
||||
{
|
||||
P arr1[] = { P(-1, 1), P(1, 1), P(1, -1), P(-1, -1) };
|
||||
P arr2[] = { P(-2, 2), P(2, 2), P(2, -2), P(-2, -2) };
|
||||
P arr1[] = {P(-1, 1), P(1, 1), P(1, -1), P(-1, -1)};
|
||||
P arr2[] = {P(-2, 2), P(2, 2), P(2, -2), P(-2, -2)};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -82,8 +82,8 @@ UNIT_TEST(RegionDifference_Smoke)
|
||||
}
|
||||
|
||||
{
|
||||
P arr1[] = { P(0, 1), P(2, 1), P(2, 0), P(0, 0) };
|
||||
P arr2[] = { P(1, 2), P(2, 2), P(2, -1), P(1, -1) };
|
||||
P arr1[] = {P(0, 1), P(2, 1), P(2, 0), P(0, 0)};
|
||||
P arr2[] = {P(1, 2), P(2, 2), P(2, -1), P(1, -1)};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -100,8 +100,8 @@ UNIT_TEST(RegionDifference_Smoke)
|
||||
UNIT_TEST(AddRegion_Smoke)
|
||||
{
|
||||
{
|
||||
P arr1[] = { {0, 0}, {0, 1}, {1, 1}, {1, 0} };
|
||||
P arr2[] = { {2, 2}, {2, 3}, {3, 3}, {3, 2} };
|
||||
P arr1[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
P arr2[] = {{2, 2}, {2, 3}, {3, 3}, {3, 2}};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -120,8 +120,8 @@ UNIT_TEST(AddRegion_Smoke)
|
||||
}
|
||||
|
||||
{
|
||||
P arr1[] = { {0, 0}, {0, 3}, {3, 3}, {3, 0} };
|
||||
P arr2[] = { {1, 1}, {1, 2}, {2, 2}, {2, 1} };
|
||||
P arr1[] = {{0, 0}, {0, 3}, {3, 3}, {3, 0}};
|
||||
P arr2[] = {{1, 1}, {1, 2}, {2, 2}, {2, 1}};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -142,8 +142,8 @@ UNIT_TEST(AddRegion_Smoke)
|
||||
|
||||
UNIT_TEST(RegionIntersect_Floats)
|
||||
{
|
||||
P arr1[] = { {0, 1}, {2, 3}, {3, 2}, {1, 0} };
|
||||
P arr2[] = { {0, 2}, {1, 3}, {3, 1}, {2, 0} };
|
||||
P arr1[] = {{0, 1}, {2, 3}, {3, 2}, {1, 0}};
|
||||
P arr2[] = {{0, 2}, {1, 3}, {3, 1}, {2, 0}};
|
||||
|
||||
R r1, r2;
|
||||
r1.Assign(arr1, arr1 + ARRAY_SIZE(arr1));
|
||||
@@ -158,8 +158,9 @@ UNIT_TEST(RegionIntersect_Floats)
|
||||
|
||||
UNIT_TEST(RegionArea_2Directions)
|
||||
{
|
||||
P arr[] = { {1, 1}, {1, 0}, {2, 0}, {2, 1}, {1, 1}, // CCW direction
|
||||
{1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1} // CW direction
|
||||
P arr[] = {
|
||||
{1, 1}, {1, 0}, {2, 0}, {2, 1}, {1, 1}, // CCW direction
|
||||
{1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1} // CW direction
|
||||
};
|
||||
|
||||
R r;
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace region_tests
|
||||
{
|
||||
@@ -88,13 +88,13 @@ void TestContains()
|
||||
TestContainsRectangular(data);
|
||||
}
|
||||
{
|
||||
P const data[] = {P(-2000000000, -2000000000), P(-1000000000, -2000000000),
|
||||
P(-1000000000, -1000000000), P(-2000000000, -1000000000)};
|
||||
P const data[] = {P(-2000000000, -2000000000), P(-1000000000, -2000000000), P(-1000000000, -1000000000),
|
||||
P(-2000000000, -1000000000)};
|
||||
TestContainsRectangular(data);
|
||||
}
|
||||
{
|
||||
P const data[] = {P(1000000000, 1000000000), P(2000000000, 1000000000),
|
||||
P(2000000000, 2000000000), P(1000000000, 2000000000)};
|
||||
P const data[] = {P(1000000000, 1000000000), P(2000000000, 1000000000), P(2000000000, 2000000000),
|
||||
P(1000000000, 2000000000)};
|
||||
TestContainsRectangular(data);
|
||||
}
|
||||
|
||||
@@ -111,10 +111,9 @@ void TestContains()
|
||||
|
||||
// complex polygon
|
||||
{
|
||||
P const data[] = {P(0, 0), P(2, 0), P(2, 2), P(3, 1), P(4, 2), P(5, 2), P(3, 3),
|
||||
P(3, 2), P(2, 4), P(6, 3), P(7, 4), P(7, 2), P(8, 5), P(8, 7),
|
||||
P(7, 7), P(8, 8), P(5, 9), P(6, 6), P(5, 7), P(4, 6), P(4, 8),
|
||||
P(3, 7), P(2, 7), P(3, 6), P(4, 4), P(0, 7), P(2, 3), P(0, 2)};
|
||||
P const data[] = {P(0, 0), P(2, 0), P(2, 2), P(3, 1), P(4, 2), P(5, 2), P(3, 3), P(3, 2), P(2, 4), P(6, 3),
|
||||
P(7, 4), P(7, 2), P(8, 5), P(8, 7), P(7, 7), P(8, 8), P(5, 9), P(6, 6), P(5, 7), P(4, 6),
|
||||
P(4, 8), P(3, 7), P(2, 7), P(3, 6), P(4, 4), P(0, 7), P(2, 3), P(0, 2)};
|
||||
region.Assign(data, data + ARRAY_SIZE(data));
|
||||
}
|
||||
TEST_EQUAL(region.GetRect(), m2::Rect<typename P::value_type>(0, 0, 8, 9), ());
|
||||
@@ -160,8 +159,7 @@ UNIT_TEST(Region)
|
||||
{
|
||||
// equality case
|
||||
{
|
||||
P const data[] = {P(1, 1), P(0, 4.995), P(1, 4.999996), P(1.000003, 5.000001),
|
||||
P(0.5, 10), P(10, 10), P(10, 1)};
|
||||
P const data[] = {P(1, 1), P(0, 4.995), P(1, 4.999996), P(1.000003, 5.000001), P(0.5, 10), P(10, 10), P(10, 1)};
|
||||
region.Assign(data, data + ARRAY_SIZE(data));
|
||||
}
|
||||
TEST(!region.Contains(P(0.9999987, 0.9999938)), ());
|
||||
@@ -202,7 +200,10 @@ UNIT_TEST(Region_Contains_int32)
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(Region_Contains_uint32) { TestContains<m2::RegionU>(); }
|
||||
UNIT_TEST(Region_Contains_uint32)
|
||||
{
|
||||
TestContains<m2::RegionU>();
|
||||
}
|
||||
|
||||
UNIT_TEST(Region_Contains_double)
|
||||
{
|
||||
@@ -279,8 +280,7 @@ UNIT_TEST(Region_border_intersecion_Test)
|
||||
TEST(region.FindIntersection(P(7.0, 7.0), P(7.0, 10.0), intersection), ());
|
||||
TEST(intersection == P(7.0, 10.0), ());
|
||||
|
||||
TEST(!region.FindIntersection(P(5.0, 5.0), P(2.0, 2.0), intersection),
|
||||
("This case has no intersection"));
|
||||
TEST(!region.FindIntersection(P(5.0, 5.0), P(2.0, 2.0), intersection), ("This case has no intersection"));
|
||||
}
|
||||
|
||||
UNIT_TEST(Region_Area)
|
||||
@@ -319,7 +319,8 @@ UNIT_TEST(Region_GetRandomPoint)
|
||||
size_t const kNumIterations = 1000;
|
||||
bool const kNeedPlot = true;
|
||||
|
||||
auto testConvexRegion = [&](m2::Region<P> const & region) {
|
||||
auto testConvexRegion = [&](m2::Region<P> const & region)
|
||||
{
|
||||
minstd_rand rng(0);
|
||||
vector<P> points;
|
||||
points.reserve(kNumIterations);
|
||||
@@ -363,4 +364,4 @@ UNIT_TEST(Region_GetRandomPoint)
|
||||
testConvexRegion(region);
|
||||
}
|
||||
}
|
||||
} // namespace region_tests
|
||||
} // namespace region_tests
|
||||
|
||||
@@ -159,7 +159,7 @@ UNIT_TEST(Triangle_PointInsidePoint)
|
||||
UNIT_TEST(PolygonSelfIntersections_IntersectSmoke)
|
||||
{
|
||||
{
|
||||
P arr[] = { P(0, 1), P(2, -1), P(2, 1), P(0, -1) };
|
||||
P arr[] = {P(0, 1), P(2, -1), P(2, 1), P(0, -1)};
|
||||
CheckSelfIntersections(&arr[0], arr + ARRAY_SIZE(arr), true);
|
||||
}
|
||||
}
|
||||
@@ -167,13 +167,13 @@ UNIT_TEST(PolygonSelfIntersections_IntersectSmoke)
|
||||
UNIT_TEST(PolygonSelfIntersections_TangentSmoke)
|
||||
{
|
||||
{
|
||||
P arr[] = { P(0, 1), P(1, 0), P(2, 1), P(2, -1), P(1, 0), P(0, -1) };
|
||||
P arr[] = {P(0, 1), P(1, 0), P(2, 1), P(2, -1), P(1, 0), P(0, -1)};
|
||||
CheckSelfIntersections(&arr[0], arr + ARRAY_SIZE(arr), false);
|
||||
}
|
||||
|
||||
{
|
||||
P arr[] = { P(0, 0), P(2, 0), P(2, 1), P(1, 0), P(0, 1) };
|
||||
P arr[] = {P(0, 0), P(2, 0), P(2, 1), P(1, 0), P(0, 1)};
|
||||
CheckSelfIntersections(&arr[0], arr + ARRAY_SIZE(arr), false);
|
||||
}
|
||||
}
|
||||
} // namespace robust_test
|
||||
} // namespace robust_test
|
||||
|
||||
@@ -70,8 +70,11 @@ UNIT_TEST(ScreenBase_3dTransform)
|
||||
|
||||
p3d = m2::PointD(screen.PixelRectIn3d().SizeX() / 2.0, screen.PixelRectIn3d().SizeY() / 2.0);
|
||||
pp = screen.P3dtoP(p3d);
|
||||
TEST(pp.EqualDxDy(m2::PointD(screen.PixelRect().SizeX() / 2.0,
|
||||
screen.PixelRect().SizeY() - screen.PixelRectIn3d().SizeY() / (2.0 * cos(rotationAngle))), kEps), ());
|
||||
TEST(
|
||||
pp.EqualDxDy(m2::PointD(screen.PixelRect().SizeX() / 2.0,
|
||||
screen.PixelRect().SizeY() - screen.PixelRectIn3d().SizeY() / (2.0 * cos(rotationAngle))),
|
||||
kEps),
|
||||
());
|
||||
|
||||
p3d = m2::PointD(0, 0);
|
||||
pp = screen.P3dtoP(p3d);
|
||||
@@ -147,12 +150,10 @@ UNIT_TEST(ScreenBase_CalcTransform)
|
||||
double dx = 1;
|
||||
double dy = 2;
|
||||
double s1, a1, dx1, dy1;
|
||||
math::Matrix<double, 3, 3> m = ScreenBase::CalcTransform(
|
||||
m2::PointD(0, 1), m2::PointD(1, 1),
|
||||
m2::PointD( s * sin(a) + dx, s * cos(a) + dy),
|
||||
m2::PointD(s * cos(a) + s * sin(a) + dx, -s * sin(a) + s * cos(a) + dy),
|
||||
true /* allow rotate */,
|
||||
true /* allow scale*/);
|
||||
math::Matrix<double, 3, 3> m =
|
||||
ScreenBase::CalcTransform(m2::PointD(0, 1), m2::PointD(1, 1), m2::PointD(s * sin(a) + dx, s * cos(a) + dy),
|
||||
m2::PointD(s * cos(a) + s * sin(a) + dx, -s * sin(a) + s * cos(a) + dy),
|
||||
true /* allow rotate */, true /* allow scale*/);
|
||||
|
||||
ScreenBase::ExtractGtoPParams(m, a1, s1, dx1, dy1);
|
||||
|
||||
@@ -194,26 +195,18 @@ UNIT_TEST(ScreenBase_CombineTransforms)
|
||||
|
||||
{
|
||||
// GtoP matrix for scale only.
|
||||
math::Matrix<double, 3, 3> m =
|
||||
math::Shift(
|
||||
math::Scale(math::Identity<double, 3>(),
|
||||
1.0 / fixedScale, -1.0 / fixedScale),
|
||||
sCopy.PixelRect().Center());
|
||||
math::Matrix<double, 3, 3> m = math::Shift(
|
||||
math::Scale(math::Identity<double, 3>(), 1.0 / fixedScale, -1.0 / fixedScale), sCopy.PixelRect().Center());
|
||||
|
||||
TEST(is_equal(sCopy.GtoP(g1), g1 * m), ());
|
||||
TEST(is_equal(sCopy.GtoP(g2), g2 * m), ());
|
||||
}
|
||||
|
||||
// GtoP matrix to make full final transformation.
|
||||
math::Matrix<double, 3, 3> m =
|
||||
math::Shift(
|
||||
math::Scale(
|
||||
math::Rotate(
|
||||
math::Shift(math::Identity<double, 3>(),
|
||||
-sCopy.PixelRect().Center()),
|
||||
angle),
|
||||
fixedScale / scale, fixedScale / scale),
|
||||
org);
|
||||
math::Matrix<double, 3, 3> m = math::Shift(
|
||||
math::Scale(math::Rotate(math::Shift(math::Identity<double, 3>(), -sCopy.PixelRect().Center()), angle),
|
||||
fixedScale / scale, fixedScale / scale),
|
||||
org);
|
||||
|
||||
m2::PointD pp1 = sCopy.GtoP(g1) * m;
|
||||
m2::PointD pp2 = sCopy.GtoP(g2) * m;
|
||||
@@ -221,4 +214,4 @@ UNIT_TEST(ScreenBase_CombineTransforms)
|
||||
TEST(is_equal(p1, pp1), (p1, pp1));
|
||||
TEST(is_equal(p2, pp2), (p2, pp2));
|
||||
}
|
||||
} // namespace screen_test
|
||||
} // namespace screen_test
|
||||
|
||||
@@ -10,7 +10,7 @@ using namespace m2;
|
||||
double const kEps = 1e-10;
|
||||
|
||||
void TestIntersectionResult(IntersectionResult const & result, IntersectionResult::Type expectedType,
|
||||
PointD const & expectedPoint)
|
||||
PointD const & expectedPoint)
|
||||
{
|
||||
TEST_EQUAL(result.m_type, expectedType, ());
|
||||
TEST(AlmostEqualAbs(result.m_point, expectedPoint, kEps), (result.m_point, expectedPoint, kEps));
|
||||
@@ -55,54 +55,45 @@ UNIT_TEST(SegmentIntersection_Intersect)
|
||||
|
||||
UNIT_TEST(SegmentIntersection_NoIntersectionPoint)
|
||||
{
|
||||
TEST_EQUAL(
|
||||
Intersect(Segment2D({0.0, 0.0}, {1.0, 0.0}), Segment2D({2.0, 0.0}, {4.0, 0.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
TEST_EQUAL(Intersect(Segment2D({0.0, 0.0}, {1.0, 0.0}), Segment2D({2.0, 0.0}, {4.0, 0.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
|
||||
TEST_EQUAL(
|
||||
Intersect(Segment2D({0.0, 0.0}, {1.0, 1.0}), Segment2D({2.0, 0.0}, {4.0, 0.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
TEST_EQUAL(Intersect(Segment2D({0.0, 0.0}, {1.0, 1.0}), Segment2D({2.0, 0.0}, {4.0, 0.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
|
||||
TEST_EQUAL(
|
||||
Intersect(Segment2D({0.0, 0.0}, {1.0, 1.0}), Segment2D({4.0, 4.0}, {2.0, 2.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
TEST_EQUAL(Intersect(Segment2D({0.0, 0.0}, {1.0, 1.0}), Segment2D({4.0, 4.0}, {2.0, 2.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
|
||||
TEST_EQUAL(
|
||||
Intersect(Segment2D({0.0, 0.0}, {4.0, 4.0}), Segment2D({10.0, 0.0}, {6.0, 4.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
TEST_EQUAL(Intersect(Segment2D({0.0, 0.0}, {4.0, 4.0}), Segment2D({10.0, 0.0}, {6.0, 4.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Zero, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(SegmentIntersection_OneIntersectionPoint)
|
||||
{
|
||||
// Two intersected segments. The intersection point is in the middle of both of them.
|
||||
{
|
||||
auto const result =
|
||||
Intersect(Segment2D({-1.0, -1.0}, {1.0, 1.0}), Segment2D({-1.0, 0.0}, {1.0, 0.0}), kEps);
|
||||
auto const result = Intersect(Segment2D({-1.0, -1.0}, {1.0, 1.0}), Segment2D({-1.0, 0.0}, {1.0, 0.0}), kEps);
|
||||
TestIntersectionResult(result, IntersectionResult::Type::One, {0.0, 0.0});
|
||||
}
|
||||
|
||||
{
|
||||
auto const result =
|
||||
Intersect(Segment2D({0.0, 0.0}, {10.0, 10.0}), Segment2D({10.0, 0.0}, {0.0, 10.0}), kEps);
|
||||
auto const result = Intersect(Segment2D({0.0, 0.0}, {10.0, 10.0}), Segment2D({10.0, 0.0}, {0.0, 10.0}), kEps);
|
||||
TestIntersectionResult(result, IntersectionResult::Type::One, {5.0, 5.0});
|
||||
}
|
||||
|
||||
// Two intersected segments. The intersection point is in an end of both of them.
|
||||
{
|
||||
auto const result =
|
||||
Intersect(Segment2D({-1.0, -1.0}, {0.0, 0.0}), Segment2D({0.0, 0.0}, {11.0, 0.0}), kEps);
|
||||
auto const result = Intersect(Segment2D({-1.0, -1.0}, {0.0, 0.0}), Segment2D({0.0, 0.0}, {11.0, 0.0}), kEps);
|
||||
TestIntersectionResult(result, IntersectionResult::Type::One, {0.0, 0.0});
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(SegmentIntersection_InfinityIntersectionPoints)
|
||||
{
|
||||
TEST_EQUAL(
|
||||
Intersect(Segment2D({0.0, 0.0}, {2.0, 0.0}), Segment2D({1.0, 0.0}, {4.0, 0.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Infinity, ());
|
||||
TEST_EQUAL(Intersect(Segment2D({0.0, 0.0}, {2.0, 0.0}), Segment2D({1.0, 0.0}, {4.0, 0.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Infinity, ());
|
||||
|
||||
TEST_EQUAL(
|
||||
Intersect(Segment2D({0.0, 0.0}, {2.0, 4.0}), Segment2D({1.0, 2.0}, {2.0, 4.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Infinity, ());
|
||||
TEST_EQUAL(Intersect(Segment2D({0.0, 0.0}, {2.0, 4.0}), Segment2D({1.0, 2.0}, {2.0, 4.0}), kEps).m_type,
|
||||
IntersectionResult::Type::Infinity, ());
|
||||
}
|
||||
} // namespace segment2d_tests
|
||||
|
||||
@@ -20,8 +20,7 @@ using namespace std;
|
||||
using P = m2::PointD;
|
||||
using DistanceFn = m2::SquaredDistanceFromSegmentToPoint;
|
||||
using PointOutput = base::BackInsertFunctor<vector<m2::PointD>>;
|
||||
using SimplifyFn = void (*)(m2::PointD const *, m2::PointD const *, double, DistanceFn,
|
||||
PointOutput);
|
||||
using SimplifyFn = void (*)(m2::PointD const *, m2::PointD const *, double, DistanceFn, PointOutput);
|
||||
|
||||
struct LargePolylineTestData
|
||||
{
|
||||
@@ -67,14 +66,12 @@ void TestSimplificationOfPoly(m2::PointD const * points, size_t count, SimplifyF
|
||||
}
|
||||
}
|
||||
|
||||
void SimplifyNearOptimal10(m2::PointD const * f, m2::PointD const * l, double e, DistanceFn distFn,
|
||||
PointOutput out)
|
||||
void SimplifyNearOptimal10(m2::PointD const * f, m2::PointD const * l, double e, DistanceFn distFn, PointOutput out)
|
||||
{
|
||||
SimplifyNearOptimal(10, f, l, e, distFn, out);
|
||||
}
|
||||
|
||||
void SimplifyNearOptimal20(m2::PointD const * f, m2::PointD const * l, double e, DistanceFn distFn,
|
||||
PointOutput out)
|
||||
void SimplifyNearOptimal20(m2::PointD const * f, m2::PointD const * l, double e, DistanceFn distFn, PointOutput out)
|
||||
{
|
||||
SimplifyNearOptimal(20, f, l, e, distFn, out);
|
||||
}
|
||||
@@ -106,30 +103,39 @@ UNIT_TEST(Simplification_TestDataIsCorrect)
|
||||
TEST_EQUAL(LargePolylineTestData::m_Size, 5539, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_DP_Smoke) { TestSimplificationSmoke(&SimplifyDP<DistanceFn>); }
|
||||
UNIT_TEST(Simplification_DP_Smoke)
|
||||
{
|
||||
TestSimplificationSmoke(&SimplifyDP<DistanceFn>);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_DP_Line) { TestSimplificationOfLine(&SimplifyDP<DistanceFn>); }
|
||||
UNIT_TEST(Simplification_DP_Line)
|
||||
{
|
||||
TestSimplificationOfLine(&SimplifyDP<DistanceFn>);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_DP_Polyline)
|
||||
{
|
||||
TestSimplificationOfPoly(LargePolylineTestData::m_Data, LargePolylineTestData::m_Size,
|
||||
&SimplifyDP<DistanceFn>);
|
||||
TestSimplificationOfPoly(LargePolylineTestData::m_Data, LargePolylineTestData::m_Size, &SimplifyDP<DistanceFn>);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_Opt_Smoke) { TestSimplificationSmoke(&SimplifyNearOptimal10); }
|
||||
UNIT_TEST(Simplification_Opt_Smoke)
|
||||
{
|
||||
TestSimplificationSmoke(&SimplifyNearOptimal10);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_Opt_Line) { TestSimplificationOfLine(&SimplifyNearOptimal10); }
|
||||
UNIT_TEST(Simplification_Opt_Line)
|
||||
{
|
||||
TestSimplificationOfLine(&SimplifyNearOptimal10);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_Opt10_Polyline)
|
||||
{
|
||||
TestSimplificationOfPoly(LargePolylineTestData::m_Data, LargePolylineTestData::m_Size,
|
||||
&SimplifyNearOptimal10);
|
||||
TestSimplificationOfPoly(LargePolylineTestData::m_Data, LargePolylineTestData::m_Size, &SimplifyNearOptimal10);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simplification_Opt20_Polyline)
|
||||
{
|
||||
TestSimplificationOfPoly(LargePolylineTestData::m_Data, LargePolylineTestData::m_Size,
|
||||
&SimplifyNearOptimal20);
|
||||
TestSimplificationOfPoly(LargePolylineTestData::m_Data, LargePolylineTestData::m_Size, &SimplifyNearOptimal20);
|
||||
}
|
||||
|
||||
UNIT_TEST(Simpfication_DP_DegenerateTrg)
|
||||
@@ -137,9 +143,8 @@ UNIT_TEST(Simpfication_DP_DegenerateTrg)
|
||||
P arr1[] = {P(0, 0), P(100, 100), P(100, 500), P(0, 600)};
|
||||
CheckDPStrict(arr1, ARRAY_SIZE(arr1), 1.0, 4);
|
||||
|
||||
P arr2[] = {P(0, 0), P(100, 100), P(100.1, 150), P(100.2, 200),
|
||||
P(100.3, 250), P(100.4, 300), P(100.3, 350), P(100.2, 400),
|
||||
P(100.1, 450), P(100, 500), P(0, 600)};
|
||||
P arr2[] = {P(0, 0), P(100, 100), P(100.1, 150), P(100.2, 200), P(100.3, 250), P(100.4, 300),
|
||||
P(100.3, 350), P(100.2, 400), P(100.1, 450), P(100, 500), P(0, 600)};
|
||||
CheckDPStrict(arr2, ARRAY_SIZE(arr2), 1.0, 4);
|
||||
}
|
||||
} // namespace simplification_test
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace spline_test
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
using m2::Spline;
|
||||
using m2::PointD;
|
||||
using m2::Spline;
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -36,12 +36,12 @@ void TestPointDDir(PointD const & dst, PointD const & src)
|
||||
}
|
||||
else
|
||||
{
|
||||
TestEqual(dst.x/len1, src.x/len2);
|
||||
TestEqual(dst.y/len1, src.y/len2);
|
||||
TestEqual(dst.x / len1, src.x / len2);
|
||||
TestEqual(dst.y / len1, src.y / len2);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(Spline_SmoothedDirections)
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
#include "testing/testing.hpp"
|
||||
#include "geometry/transformations.hpp"
|
||||
#include "base/matrix.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/transformations.hpp"
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
UNIT_TEST(Transformations_Shift)
|
||||
{
|
||||
@@ -28,7 +28,8 @@ UNIT_TEST(Transformations_Rotate)
|
||||
|
||||
UNIT_TEST(Transformations_ShiftScaleRotate)
|
||||
{
|
||||
math::Matrix<double, 3, 3> m = math::Rotate(math::Scale(math::Shift(math::Identity<double, 3>(), 100, 100), 2, 3), -math::pi / 2);
|
||||
math::Matrix<double, 3, 3> m =
|
||||
math::Rotate(math::Scale(math::Shift(math::Identity<double, 3>(), 100, 100), 2, 3), -math::pi / 2);
|
||||
m2::PointD pt = m2::PointD(20, 10) * m;
|
||||
|
||||
TEST(pt.EqualDxDy(m2::PointD(330, -240), 1.0E-10), ());
|
||||
|
||||
@@ -64,8 +64,7 @@ UNIT_TEST(Tree4D_ForAnyInRect)
|
||||
{
|
||||
Tree theTree;
|
||||
|
||||
R arr[] = {R(0, 0, 1, 1), R(0, 0, 5, 5), R(1, 1, 2, 2),
|
||||
R(1, 1, 6.5, 6.5), R(2, 2, 3, 3), R(2, 2, 7, 7)};
|
||||
R arr[] = {R(0, 0, 1, 1), R(0, 0, 5, 5), R(1, 1, 2, 2), R(1, 1, 6.5, 6.5), R(2, 2, 3, 3), R(2, 2, 7, 7)};
|
||||
for (auto const & r : arr)
|
||||
theTree.Add(r);
|
||||
|
||||
@@ -118,7 +117,7 @@ void CheckInRect(R const * arr, size_t count, R const & searchR, size_t expected
|
||||
|
||||
TEST_EQUAL(test.size(), expected, ());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(Tree4D_ForEachInRect)
|
||||
{
|
||||
@@ -141,10 +140,7 @@ struct TestObj : public m2::RectD
|
||||
{
|
||||
int m_id;
|
||||
|
||||
TestObj(double minX, double minY, double maxX, double maxY, int id)
|
||||
: m2::RectD(minX, minY, maxX, maxY), m_id(id)
|
||||
{
|
||||
}
|
||||
TestObj(double minX, double minY, double maxX, double maxY, int id) : m2::RectD(minX, minY, maxX, maxY), m_id(id) {}
|
||||
|
||||
bool operator==(TestObj const & r) const { return m_id == r.m_id; }
|
||||
};
|
||||
|
||||
@@ -8,10 +8,8 @@ template <class T, size_t N>
|
||||
bool EqualArrays(T (&a1)[N], T (&a2)[N])
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
if (!AlmostEqualULPs(a1[i], a2[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
@@ -20,14 +18,14 @@ UNIT_TEST(AvgVector_Smoke)
|
||||
{
|
||||
math::AvgVector<double, 3> holder(3);
|
||||
|
||||
double ethalon1[] = { 5, 5, 5 };
|
||||
double ethalon2[] = { 5.5, 5.5, 5.5 };
|
||||
double ethalon3[] = { 6, 6, 6 };
|
||||
double ethalon1[] = {5, 5, 5};
|
||||
double ethalon2[] = {5.5, 5.5, 5.5};
|
||||
double ethalon3[] = {6, 6, 6};
|
||||
|
||||
double arr1[] = { 5, 5, 5 };
|
||||
double arr2[] = { 6, 6, 6 };
|
||||
double arr3[] = { 5, 5, 5 };
|
||||
double arr4[] = { 6, 6, 6 };
|
||||
double arr1[] = {5, 5, 5};
|
||||
double arr2[] = {6, 6, 6};
|
||||
double arr3[] = {5, 5, 5};
|
||||
double arr4[] = {6, 6, 6};
|
||||
|
||||
holder.Next(arr1);
|
||||
TEST(EqualArrays(arr1, ethalon1), ());
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "std/boost_geometry.hpp"
|
||||
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/geometries/polygon.hpp>
|
||||
#include "std/boost_geometry.hpp"
|
||||
|
||||
namespace geometry
|
||||
{
|
||||
@@ -39,8 +39,8 @@ impl::MultiPolygon TrianglesToPolygon(Container const & points);
|
||||
template <typename LGeometry, typename RGeometry>
|
||||
double GetIntersectionScore(LGeometry const & lhs, RGeometry const & rhs)
|
||||
{
|
||||
if (!boost::geometry::is_valid(lhs) || !boost::geometry::is_valid(rhs) ||
|
||||
boost::geometry::is_empty(lhs) || boost::geometry::is_empty(rhs))
|
||||
if (!boost::geometry::is_valid(lhs) || !boost::geometry::is_valid(rhs) || boost::geometry::is_empty(lhs) ||
|
||||
boost::geometry::is_empty(rhs))
|
||||
{
|
||||
return kPenaltyScore;
|
||||
}
|
||||
@@ -63,8 +63,7 @@ double GetIntersectionScore(LGeometry const & lhs, RGeometry const & rhs)
|
||||
/// |lhs| and |rhs| are any standard container of m2::Point with random access iterator.
|
||||
/// |toPolygonConverter| is a method which converts |lhs| and |rhs| to boost::geometry areal type.
|
||||
template <typename Container, typename Converter>
|
||||
double GetIntersectionScore(Container const & lhs, Container const & rhs,
|
||||
Converter const & toPolygonConverter)
|
||||
double GetIntersectionScore(Container const & lhs, Container const & rhs, Converter const & toPolygonConverter)
|
||||
{
|
||||
auto const lhsPolygon = toPolygonConverter(lhs);
|
||||
if (boost::geometry::is_empty(lhsPolygon))
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
namespace ms
|
||||
{
|
||||
bool LatLon::operator==(ms::LatLon const & rhs) const { return m_lat == rhs.m_lat && m_lon == rhs.m_lon; }
|
||||
bool LatLon::operator==(ms::LatLon const & rhs) const
|
||||
{
|
||||
return m_lat == rhs.m_lat && m_lon == rhs.m_lon;
|
||||
}
|
||||
|
||||
bool LatLon::operator<(ms::LatLon const & rhs) const
|
||||
{
|
||||
@@ -22,14 +25,13 @@ bool LatLon::EqualDxDy(LatLon const & p, double eps) const
|
||||
std::string DebugPrint(LatLon const & t)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out.precision(9); // <3>.<6> digits is enough here
|
||||
out.precision(9); // <3>.<6> digits is enough here
|
||||
out << "ms::LatLon(" << t.m_lat << ", " << t.m_lon << ")";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
bool AlmostEqualAbs(LatLon const & ll1, LatLon const & ll2, double eps)
|
||||
{
|
||||
return ::AlmostEqualAbs(ll1.m_lat, ll2.m_lat, eps) &&
|
||||
::AlmostEqualAbs(ll1.m_lon, ll2.m_lon, eps);
|
||||
return ::AlmostEqualAbs(ll1.m_lat, ll2.m_lat, eps) && ::AlmostEqualAbs(ll1.m_lon, ll2.m_lon, eps);
|
||||
}
|
||||
} // namespace ms
|
||||
|
||||
@@ -101,8 +101,7 @@ m2::RectD RectByCenterXYAndSizeInMeters(m2::PointD const & center, double size)
|
||||
|
||||
m2::RectD RectByCenterXYAndOffset(m2::PointD const & center, double offset)
|
||||
{
|
||||
return {ClampX(center.x - offset), ClampY(center.y - offset),
|
||||
ClampX(center.x + offset), ClampY(center.y + offset)};
|
||||
return {ClampX(center.x - offset), ClampY(center.y - offset), ClampX(center.x + offset), ClampY(center.y + offset)};
|
||||
}
|
||||
|
||||
m2::RectD RectByCenterLatLonAndSizeInMeters(double lat, double lon, double size)
|
||||
@@ -112,11 +111,11 @@ m2::RectD RectByCenterLatLonAndSizeInMeters(double lat, double lon, double size)
|
||||
|
||||
m2::RectD FromLatLon(m2::RectD const & rect)
|
||||
{
|
||||
return { FromLatLon(rect.minY(), rect.minX()), FromLatLon(rect.maxY(), rect.maxX()) };
|
||||
return {FromLatLon(rect.minY(), rect.minX()), FromLatLon(rect.maxY(), rect.maxX())};
|
||||
}
|
||||
|
||||
m2::RectD ToLatLon(m2::RectD const & rect)
|
||||
{
|
||||
return { YToLat(rect.minY()), XToLon(rect.minX()), YToLat(rect.maxY()), XToLon(rect.maxX()) };
|
||||
return {YToLat(rect.minY()), XToLon(rect.minX()), YToLat(rect.maxY()), XToLon(rect.maxX())};
|
||||
}
|
||||
} // namespace mercator
|
||||
|
||||
@@ -24,31 +24,58 @@ struct Bounds
|
||||
static double constexpr kDegreesInMeter = 360.0 / 40008245.0;
|
||||
static double constexpr kMetersInDegree = 40008245.0 / 360.0;
|
||||
|
||||
static m2::RectD FullRect()
|
||||
{
|
||||
return m2::RectD(kMinX, kMinY, kMaxX, kMaxY);
|
||||
}
|
||||
static m2::RectD FullRect() { return m2::RectD(kMinX, kMinY, kMaxX, kMaxY); }
|
||||
};
|
||||
|
||||
inline bool ValidLon(double d) { return math::Between(-180.0, 180.0, d); }
|
||||
inline bool ValidLat(double d) { return math::Between(-90.0, 90.0, d); }
|
||||
inline bool ValidLon(double d)
|
||||
{
|
||||
return math::Between(-180.0, 180.0, d);
|
||||
}
|
||||
inline bool ValidLat(double d)
|
||||
{
|
||||
return math::Between(-90.0, 90.0, d);
|
||||
}
|
||||
|
||||
inline bool ValidX(double d) { return math::Between(Bounds::kMinX, Bounds::kMaxX, d); }
|
||||
inline bool ValidY(double d) { return math::Between(Bounds::kMinY, Bounds::kMaxY, d); }
|
||||
inline bool ValidX(double d)
|
||||
{
|
||||
return math::Between(Bounds::kMinX, Bounds::kMaxX, d);
|
||||
}
|
||||
inline bool ValidY(double d)
|
||||
{
|
||||
return math::Between(Bounds::kMinY, Bounds::kMaxY, d);
|
||||
}
|
||||
|
||||
inline double ClampX(double d) { return math::Clamp(d, Bounds::kMinX, Bounds::kMaxX); }
|
||||
inline double ClampY(double d) { return math::Clamp(d, Bounds::kMinY, Bounds::kMaxY); }
|
||||
inline double ClampX(double d)
|
||||
{
|
||||
return math::Clamp(d, Bounds::kMinX, Bounds::kMaxX);
|
||||
}
|
||||
inline double ClampY(double d)
|
||||
{
|
||||
return math::Clamp(d, Bounds::kMinY, Bounds::kMaxY);
|
||||
}
|
||||
|
||||
void ClampPoint(m2::PointD & pt);
|
||||
|
||||
double YToLat(double y);
|
||||
double LatToY(double lat);
|
||||
|
||||
inline double XToLon(double x) { return x; }
|
||||
inline double LonToX(double lon) { return lon; }
|
||||
inline double XToLon(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
inline double LonToX(double lon)
|
||||
{
|
||||
return lon;
|
||||
}
|
||||
|
||||
inline double MetersToMercator(double meters) { return meters * Bounds::kDegreesInMeter; }
|
||||
inline double MercatorToMeters(double mercator) { return mercator * Bounds::kMetersInDegree; }
|
||||
inline double MetersToMercator(double meters)
|
||||
{
|
||||
return meters * Bounds::kDegreesInMeter;
|
||||
}
|
||||
inline double MercatorToMeters(double mercator)
|
||||
{
|
||||
return mercator * Bounds::kMetersInDegree;
|
||||
}
|
||||
|
||||
/// @name Get rect for center point (lon, lat) and dimensions in meters.
|
||||
/// @return mercator rect.
|
||||
@@ -63,12 +90,21 @@ m2::RectD RectByCenterXYAndOffset(m2::PointD const & center, double offset);
|
||||
|
||||
m2::PointD GetSmPoint(m2::PointD const & pt, double lonMetersR, double latMetersR);
|
||||
|
||||
inline m2::PointD FromLatLon(double lat, double lon) { return m2::PointD(LonToX(lon), LatToY(lat)); }
|
||||
inline m2::PointD FromLatLon(ms::LatLon const & point) { return FromLatLon(point.m_lat, point.m_lon); }
|
||||
inline m2::PointD FromLatLon(double lat, double lon)
|
||||
{
|
||||
return m2::PointD(LonToX(lon), LatToY(lat));
|
||||
}
|
||||
inline m2::PointD FromLatLon(ms::LatLon const & point)
|
||||
{
|
||||
return FromLatLon(point.m_lat, point.m_lon);
|
||||
}
|
||||
|
||||
m2::RectD RectByCenterLatLonAndSizeInMeters(double lat, double lon, double size);
|
||||
|
||||
inline ms::LatLon ToLatLon(m2::PointD const & point) { return {YToLat(point.y), XToLon(point.x)}; }
|
||||
inline ms::LatLon ToLatLon(m2::PointD const & point)
|
||||
{
|
||||
return {YToLat(point.y), XToLon(point.x)};
|
||||
}
|
||||
|
||||
m2::RectD FromLatLon(m2::RectD const & rect);
|
||||
m2::RectD ToLatLon(m2::RectD const & rect);
|
||||
|
||||
@@ -4,9 +4,12 @@ namespace m2
|
||||
{
|
||||
// NearbyPointsSweeper::Event ----------------------------------------------------------------------
|
||||
NearbyPointsSweeper::Event::Event(Type type, double y, double x, size_t index, uint8_t priority)
|
||||
: m_type(type), m_y(y), m_x(x), m_index(index), m_priority(priority)
|
||||
{
|
||||
}
|
||||
: m_type(type)
|
||||
, m_y(y)
|
||||
, m_x(x)
|
||||
, m_index(index)
|
||||
, m_priority(priority)
|
||||
{}
|
||||
|
||||
bool NearbyPointsSweeper::Event::operator<(Event const & rhs) const
|
||||
{
|
||||
|
||||
@@ -55,8 +55,8 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
auto it = line.upper_bound(
|
||||
{event.m_x, std::numeric_limits<size_t>::max(), std::numeric_limits<uint8_t>::max()});
|
||||
auto it =
|
||||
line.upper_bound({event.m_x, std::numeric_limits<size_t>::max(), std::numeric_limits<uint8_t>::max()});
|
||||
|
||||
bool add = true;
|
||||
while (true)
|
||||
|
||||
@@ -26,7 +26,10 @@ static double constexpr kEps = 1e-10;
|
||||
static int constexpr kIterations = 10;
|
||||
|
||||
/// \brief Calculates latitude on the auxiliary sphere for |angleRad| latitude on a spheroid.
|
||||
static double ReducedLatitude(double angleRad) { return std::atan((1.0 - kF) * std::tan(angleRad)); }
|
||||
static double ReducedLatitude(double angleRad)
|
||||
{
|
||||
return std::atan((1.0 - kF) * std::tan(angleRad));
|
||||
}
|
||||
|
||||
double GetDistance(ms::LatLon const & point1, ms::LatLon const & point2)
|
||||
{
|
||||
@@ -75,9 +78,7 @@ double GetDistance(ms::LatLon const & point1, ms::LatLon const & point2)
|
||||
|
||||
lambdaPrev = lambda;
|
||||
lambda = L + (1 - C) * kF * sinAlpha *
|
||||
(sigma +
|
||||
C * sinSigma *
|
||||
(cosDoubleSigmaMid + C * cosSigma * (-1 + 2 * cosDoubleSigmaMidSquare)));
|
||||
(sigma + C * sinSigma * (cosDoubleSigmaMid + C * cosSigma * (-1 + 2 * cosDoubleSigmaMidSquare)));
|
||||
}
|
||||
|
||||
// Fallback solution.
|
||||
@@ -89,18 +90,16 @@ double GetDistance(ms::LatLon const & point1, ms::LatLon const & point2)
|
||||
|
||||
double const uSquare = cosAlphaSquare * (aSquare - bSquare) / bSquare;
|
||||
|
||||
double const A = 1.0 + (uSquare / 16384.0) *
|
||||
(4096.0 + uSquare * (-768.0 + uSquare * (320.0 - 175.0 * uSquare)));
|
||||
double const A = 1.0 + (uSquare / 16384.0) * (4096.0 + uSquare * (-768.0 + uSquare * (320.0 - 175.0 * uSquare)));
|
||||
|
||||
double const B = (uSquare / 1024.0) * (256.0 + uSquare * (-128.0 + uSquare * (74.0 - 47 * uSquare)));
|
||||
|
||||
double const deltaSigma =
|
||||
B * sinSigma *
|
||||
(cosDoubleSigmaMid + 0.25 * B *
|
||||
(cosSigma * (-1.0 + 2.0 * cosDoubleSigmaMidSquare) -
|
||||
(B / 6.0) * cosDoubleSigmaMid * (-3.0 + 4.0 * Pow2(sinSigma)) *
|
||||
(-3.0 + 4 * cosDoubleSigmaMidSquare)));
|
||||
double const deltaSigma = B * sinSigma *
|
||||
(cosDoubleSigmaMid + 0.25 * B *
|
||||
(cosSigma * (-1.0 + 2.0 * cosDoubleSigmaMidSquare) -
|
||||
(B / 6.0) * cosDoubleSigmaMid * (-3.0 + 4.0 * Pow2(sinSigma)) *
|
||||
(-3.0 + 4 * cosDoubleSigmaMidSquare)));
|
||||
|
||||
return kB * A * (sigma - deltaSigma);
|
||||
}
|
||||
} // namespace oblate_spheroid
|
||||
} // namespace oblate_spheroid
|
||||
|
||||
@@ -9,4 +9,4 @@ namespace oblate_spheroid
|
||||
/// Vincenty's solution is much slower but more accurate than ms::DistanceOnEarth from [geometry].
|
||||
/// https://en.wikipedia.org/wiki/Vincenty%27s_formulae
|
||||
double GetDistance(ms::LatLon const & point1, ms::LatLon const & point2);
|
||||
} // namespace
|
||||
} // namespace oblate_spheroid
|
||||
|
||||
@@ -14,8 +14,7 @@ Packer::Packer()
|
||||
, m_currentHandle(0)
|
||||
, m_maxHandle(0)
|
||||
, m_invalidHandle(0x00FFFFFF)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Packer::Packer(unsigned width, unsigned height, uint32_t maxHandle)
|
||||
: m_currentX(0)
|
||||
@@ -26,10 +25,12 @@ Packer::Packer(unsigned width, unsigned height, uint32_t maxHandle)
|
||||
, m_currentHandle(0)
|
||||
, m_maxHandle(maxHandle)
|
||||
, m_invalidHandle(0x00FFFFFF)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
uint32_t Packer::invalidHandle() const { return m_invalidHandle; }
|
||||
uint32_t Packer::invalidHandle() const
|
||||
{
|
||||
return m_invalidHandle;
|
||||
}
|
||||
|
||||
Packer::handle_t Packer::pack(unsigned width, unsigned height)
|
||||
{
|
||||
@@ -134,7 +135,10 @@ bool Packer::hasRoom(m2::PointU const * sizes, size_t cnt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Packer::isPacked(handle_t handle) { return m_rects.find(handle) != m_rects.end(); }
|
||||
bool Packer::isPacked(handle_t handle)
|
||||
{
|
||||
return m_rects.find(handle) != m_rects.end();
|
||||
}
|
||||
|
||||
Packer::find_result_t Packer::find(handle_t handle) const
|
||||
{
|
||||
@@ -146,7 +150,10 @@ Packer::find_result_t Packer::find(handle_t handle) const
|
||||
return res;
|
||||
}
|
||||
|
||||
void Packer::remove(handle_t handle) { m_rects.erase(handle); }
|
||||
void Packer::remove(handle_t handle)
|
||||
{
|
||||
m_rects.erase(handle);
|
||||
}
|
||||
|
||||
void Packer::reset()
|
||||
{
|
||||
|
||||
@@ -15,10 +15,7 @@ namespace m2
|
||||
template <typename pair_t>
|
||||
struct first_less
|
||||
{
|
||||
bool operator()(pair_t const & first, pair_t const & second)
|
||||
{
|
||||
return first.first < second.first;
|
||||
}
|
||||
bool operator()(pair_t const & first, pair_t const & second) { return first.first < second.first; }
|
||||
};
|
||||
|
||||
/// The simplest row-by-row packer.
|
||||
@@ -29,9 +26,8 @@ class Packer
|
||||
public:
|
||||
using overflowFn = std::function<void()>;
|
||||
|
||||
using overflowFns =
|
||||
std::priority_queue<std::pair<size_t, overflowFn>, std::vector<std::pair<size_t, overflowFn>>,
|
||||
first_less<std::pair<size_t, overflowFn>>>;
|
||||
using overflowFns = std::priority_queue<std::pair<size_t, overflowFn>, std::vector<std::pair<size_t, overflowFn>>,
|
||||
first_less<std::pair<size_t, overflowFn>>>;
|
||||
|
||||
using handle_t = uint32_t;
|
||||
using find_result_t = std::pair<bool, m2::RectU>;
|
||||
|
||||
@@ -24,8 +24,7 @@ template <typename Point>
|
||||
class ParametrizedSegment
|
||||
{
|
||||
public:
|
||||
static_assert(std::numeric_limits<typename Point::value_type>::is_signed,
|
||||
"Unsigned points are not supported");
|
||||
static_assert(std::numeric_limits<typename Point::value_type>::is_signed, "Unsigned points are not supported");
|
||||
|
||||
ParametrizedSegment(Point const & p0, Point const & p1) : m_p0(p0), m_p1(p1)
|
||||
{
|
||||
|
||||
@@ -24,17 +24,14 @@ public:
|
||||
constexpr Point(T x_, T y_) : x(x_), y(y_) {}
|
||||
|
||||
template <typename U>
|
||||
explicit constexpr Point(Point<U> const & u) : x(u.x), y(u.y)
|
||||
{
|
||||
}
|
||||
explicit constexpr Point(Point<U> const & u) : x(u.x)
|
||||
, y(u.y)
|
||||
{}
|
||||
|
||||
static Point<T> Zero() { return Point<T>(0, 0); }
|
||||
static Point<T> Max() { return Point<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::max());}
|
||||
static Point<T> Max() { return Point<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::max()); }
|
||||
|
||||
bool EqualDxDy(Point<T> const & p, T eps) const
|
||||
{
|
||||
return ((fabs(x - p.x) < eps) && (fabs(y - p.y) < eps));
|
||||
}
|
||||
bool EqualDxDy(Point<T> const & p, T eps) const { return ((fabs(x - p.x) < eps) && (fabs(y - p.y) < eps)); }
|
||||
|
||||
T SquaredLength(Point<T> const & p) const { return math::Pow2(x - p.x) + math::Pow2(y - p.y); }
|
||||
double Length(Point<T> const & p) const { return std::sqrt(SquaredLength(p)); }
|
||||
@@ -43,10 +40,7 @@ public:
|
||||
|
||||
Point<T> Move(T len, T ang) const { return Point<T>(x + len * cos(ang), y + len * sin(ang)); }
|
||||
|
||||
Point<T> Move(T len, T angSin, T angCos) const
|
||||
{
|
||||
return m2::Point<T>(x + len * angCos, y + len * angSin);
|
||||
}
|
||||
Point<T> Move(T len, T angSin, T angCos) const { return m2::Point<T>(x + len * angCos, y + len * angSin); }
|
||||
|
||||
Point<T> const & operator-=(Point<T> const & a)
|
||||
{
|
||||
@@ -100,10 +94,7 @@ public:
|
||||
|
||||
m2::Point<T> operator/(T scale) const { return m2::Point<T>(x / scale, y / scale); }
|
||||
|
||||
m2::Point<T> Mid(m2::Point<T> const & p) const
|
||||
{
|
||||
return m2::Point<T>((x + p.x) * 0.5, (y + p.y) * 0.5);
|
||||
}
|
||||
m2::Point<T> Mid(m2::Point<T> const & p) const { return m2::Point<T>((x + p.x) * 0.5, (y + p.y) * 0.5); }
|
||||
|
||||
/// @name VectorOperationsOnPoint
|
||||
/// @{
|
||||
@@ -123,9 +114,8 @@ public:
|
||||
{
|
||||
T const prolongatedX = prolongationFactor * x;
|
||||
T const prolongatedY = prolongationFactor * y;
|
||||
return std::pair<Point<T>, Point<T>>(
|
||||
Point<T>(static_cast<T>(-prolongatedY), static_cast<T>(prolongatedX)),
|
||||
Point<T>(static_cast<T>(prolongatedY), static_cast<T>(-prolongatedX)));
|
||||
return std::pair<Point<T>, Point<T>>(Point<T>(static_cast<T>(-prolongatedY), static_cast<T>(prolongatedX)),
|
||||
Point<T>(static_cast<T>(prolongatedY), static_cast<T>(-prolongatedX)));
|
||||
}
|
||||
|
||||
m2::Point<T> const & operator*=(math::Matrix<T, 3, 3> const & m)
|
||||
|
||||
@@ -97,7 +97,6 @@ std::string DebugPrint(Point<T> const & p)
|
||||
template <typename T>
|
||||
bool AlmostEqualAbs(Point<T> const & p1, Point<T> const & p2, double const & eps)
|
||||
{
|
||||
return ::AlmostEqualAbs(p1.x, p2.x, eps) && ::AlmostEqualAbs(p1.y, p2.y, eps) &&
|
||||
::AlmostEqualAbs(p1.z, p2.z, eps);
|
||||
return ::AlmostEqualAbs(p1.x, p2.x, eps) && ::AlmostEqualAbs(p1.y, p2.y, eps) && ::AlmostEqualAbs(p1.z, p2.z, eps);
|
||||
}
|
||||
} // namespace m3
|
||||
|
||||
@@ -6,15 +6,12 @@
|
||||
|
||||
namespace geometry
|
||||
{
|
||||
PointWithAltitude::PointWithAltitude()
|
||||
: m_point(m2::PointD::Zero()), m_altitude(kDefaultAltitudeMeters)
|
||||
{
|
||||
}
|
||||
PointWithAltitude::PointWithAltitude() : m_point(m2::PointD::Zero()), m_altitude(kDefaultAltitudeMeters) {}
|
||||
|
||||
PointWithAltitude::PointWithAltitude(m2::PointD const & point, Altitude altitude/* = kDefaultAltitudeMeters */)
|
||||
: m_point(point), m_altitude(altitude)
|
||||
{
|
||||
}
|
||||
PointWithAltitude::PointWithAltitude(m2::PointD const & point, Altitude altitude /* = kDefaultAltitudeMeters */)
|
||||
: m_point(point)
|
||||
, m_altitude(altitude)
|
||||
{}
|
||||
|
||||
bool PointWithAltitude::operator==(PointWithAltitude const & r) const
|
||||
{
|
||||
@@ -32,8 +29,7 @@ bool PointWithAltitude::operator<(PointWithAltitude const & r) const
|
||||
std::string DebugPrint(PointWithAltitude const & r)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "PointWithAltitude{point:" << DebugPrint(r.m_point) << ", altitude:" << r.GetAltitude()
|
||||
<< "}";
|
||||
ss << "PointWithAltitude{point:" << DebugPrint(r.m_point) << ", altitude:" << r.GetAltitude() << "}";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,14 @@ private:
|
||||
std::string DebugPrint(PointWithAltitude const & r);
|
||||
|
||||
template <typename T>
|
||||
m2::Point<T> GetPoint(m2::Point<T> const & point) { return point; }
|
||||
inline m2::PointD GetPoint(PointWithAltitude const & pwa) { return pwa.GetPoint(); }
|
||||
m2::Point<T> GetPoint(m2::Point<T> const & point)
|
||||
{
|
||||
return point;
|
||||
}
|
||||
inline m2::PointD GetPoint(PointWithAltitude const & pwa)
|
||||
{
|
||||
return pwa.GetPoint();
|
||||
}
|
||||
|
||||
PointWithAltitude MakePointWithAltitudeForTesting(m2::PointD const & point);
|
||||
|
||||
|
||||
@@ -38,16 +38,15 @@ template <typename IsVisibleF>
|
||||
size_t FindSingleStrip(size_t n, IsVisibleF isVisible)
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
if (FindSingleStripForIndex(i, n, isVisible))
|
||||
return i;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
template <typename IterT> bool TestPolygonPreconditions(IterT beg, IterT end)
|
||||
template <typename IterT>
|
||||
bool TestPolygonPreconditions(IterT beg, IterT end)
|
||||
{
|
||||
ASSERT_GREATER(std::distance(beg, end), 2, ());
|
||||
ASSERT(!AlmostEqualULPs(*beg, *(--end)), ());
|
||||
@@ -56,7 +55,8 @@ template <typename IterT> bool TestPolygonPreconditions(IterT beg, IterT end)
|
||||
#endif
|
||||
|
||||
/// Is polygon [beg, end) has CCW orientation.
|
||||
template <typename IterT> bool IsPolygonCCW(IterT beg, IterT end)
|
||||
template <typename IterT>
|
||||
bool IsPolygonCCW(IterT beg, IterT end)
|
||||
{
|
||||
ASSERT(TestPolygonPreconditions(beg, end), ());
|
||||
|
||||
@@ -72,8 +72,8 @@ template <typename IterT> bool IsPolygonCCW(IterT beg, IterT end)
|
||||
}
|
||||
}
|
||||
|
||||
double cp = m2::robust::OrientedS(*base::PrevIterInCycle(iRes, beg, end), *iRes,
|
||||
*base::NextIterInCycle(iRes, beg, end));
|
||||
double cp =
|
||||
m2::robust::OrientedS(*base::PrevIterInCycle(iRes, beg, end), *iRes, *base::NextIterInCycle(iRes, beg, end));
|
||||
if (cp != 0.0)
|
||||
return (cp > 0.0);
|
||||
|
||||
@@ -90,7 +90,7 @@ template <typename IterT> bool IsPolygonCCW(IterT beg, IterT end)
|
||||
|
||||
IterT iPrev = base::PrevIterInCycle(iRes, beg, end);
|
||||
IterT iNext = base::NextIterInCycle(iRes, beg, end);
|
||||
cp = m2::robust::OrientedS(*iPrev, *iRes, *iNext);
|
||||
cp = m2::robust::OrientedS(*iPrev, *iRes, *iNext);
|
||||
|
||||
// Feel free to comment this assert when debugging generator tool.
|
||||
// It fires on degenerated polygons which a lot in OSM.
|
||||
@@ -122,45 +122,45 @@ bool IsDiagonalVisible(IterT beg, IterT end, IterT i0, IterT i1)
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename IterT> class IsDiagonalVisibleFunctor
|
||||
template <typename IterT>
|
||||
class IsDiagonalVisibleFunctor
|
||||
{
|
||||
IterT m_Beg, m_End;
|
||||
|
||||
public:
|
||||
IsDiagonalVisibleFunctor(IterT beg, IterT end) : m_Beg(beg), m_End(end) {}
|
||||
|
||||
bool operator () (size_t a, size_t b) const
|
||||
{
|
||||
return IsDiagonalVisible(m_Beg, m_End, m_Beg + a, m_Beg + b);
|
||||
}
|
||||
bool operator()(size_t a, size_t b) const { return IsDiagonalVisible(m_Beg, m_End, m_Beg + a, m_Beg + b); }
|
||||
};
|
||||
|
||||
namespace polygon_detail
|
||||
{
|
||||
template <typename F> class StripEmitter
|
||||
template <typename F>
|
||||
class StripEmitter
|
||||
{
|
||||
F & m_f;
|
||||
int m_order;
|
||||
|
||||
public:
|
||||
StripEmitter(F & f) : m_f(f), m_order(0) {}
|
||||
|
||||
bool operator()(size_t a, size_t b)
|
||||
{
|
||||
F & m_f;
|
||||
int m_order;
|
||||
|
||||
public:
|
||||
StripEmitter(F & f) : m_f(f), m_order(0) {}
|
||||
|
||||
bool operator () (size_t a, size_t b)
|
||||
if (m_order == 0)
|
||||
{
|
||||
if (m_order == 0)
|
||||
{
|
||||
m_f(b);
|
||||
m_f(a);
|
||||
m_order = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_f(m_order == 1 ? b : a);
|
||||
m_order = -m_order;
|
||||
}
|
||||
return true;
|
||||
m_f(b);
|
||||
m_f(a);
|
||||
m_order = 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
m_f(m_order == 1 ? b : a);
|
||||
m_order = -m_order;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace polygon_detail
|
||||
|
||||
/// Make single strip for the range of points [beg, end), started with index = i.
|
||||
template <typename F>
|
||||
@@ -171,7 +171,8 @@ void MakeSingleStripFromIndex(size_t i, size_t n, F && f)
|
||||
FindSingleStripForIndex(i, n, polygon_detail::StripEmitter<F>(f));
|
||||
}
|
||||
|
||||
template <class TIter> double GetPolygonArea(TIter beg, TIter end)
|
||||
template <class TIter>
|
||||
double GetPolygonArea(TIter beg, TIter end)
|
||||
{
|
||||
double area = 0.0;
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@ namespace m2
|
||||
/// \returns a pair of minimum squared distance from |point| to the closest segment and
|
||||
/// a zero-based closest segment index in points in range [|beginIt|, |endIt|).
|
||||
template <typename It, typename T>
|
||||
std::pair<double, uint32_t> CalcMinSquaredDistance(It beginIt, It endIt,
|
||||
m2::Point<T> const & point)
|
||||
std::pair<double, uint32_t> CalcMinSquaredDistance(It beginIt, It endIt, m2::Point<T> const & point)
|
||||
{
|
||||
CHECK_GREATER(std::distance(beginIt, endIt), 1, ());
|
||||
auto squaredClosestSegDist = std::numeric_limits<double>::max();
|
||||
@@ -40,8 +39,7 @@ std::pair<double, uint32_t> CalcMinSquaredDistance(It beginIt, It endIt,
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(squaredClosestSegDist,
|
||||
static_cast<uint32_t>(std::distance(beginIt, closestSeg)));
|
||||
return std::make_pair(squaredClosestSegDist, static_cast<uint32_t>(std::distance(beginIt, closestSeg)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -59,10 +57,7 @@ public:
|
||||
ASSERT_GREATER(m_points.size(), 1, ());
|
||||
}
|
||||
|
||||
explicit Polyline(std::vector<Point<T>> const & points) : m_points(points)
|
||||
{
|
||||
ASSERT_GREATER(m_points.size(), 1, ());
|
||||
}
|
||||
explicit Polyline(std::vector<Point<T>> const & points) : m_points(points) { ASSERT_GREATER(m_points.size(), 1, ()); }
|
||||
|
||||
explicit Polyline(std::vector<Point<T>> && points) : m_points(std::move(points))
|
||||
{
|
||||
@@ -108,10 +103,7 @@ public:
|
||||
|
||||
void Clear() { m_points.clear(); }
|
||||
void Add(Point<T> const & pt) { m_points.push_back(pt); }
|
||||
void Append(Polyline const & poly)
|
||||
{
|
||||
m_points.insert(m_points.end(), poly.m_points.cbegin(), poly.m_points.cend());
|
||||
}
|
||||
void Append(Polyline const & poly) { m_points.insert(m_points.end(), poly.m_points.cbegin(), poly.m_points.cend()); }
|
||||
|
||||
template <class Iter>
|
||||
void Append(Iter beg, Iter end)
|
||||
@@ -170,11 +162,8 @@ public:
|
||||
|
||||
std::vector<Point<T>> ExtractSegment(size_t startPointIndex, size_t endPointIndex) const
|
||||
{
|
||||
if (startPointIndex > endPointIndex || startPointIndex >= m_points.size() ||
|
||||
endPointIndex >= m_points.size())
|
||||
{
|
||||
if (startPointIndex > endPointIndex || startPointIndex >= m_points.size() || endPointIndex >= m_points.size())
|
||||
return std::vector<Point<T>>();
|
||||
}
|
||||
|
||||
std::vector<Point<T>> result(endPointIndex - startPointIndex + 1);
|
||||
for (size_t i = startPointIndex, j = 0; i <= endPointIndex; ++i, ++j)
|
||||
|
||||
@@ -50,14 +50,14 @@ public:
|
||||
, m_minY(std::min(p1.y, p2.y))
|
||||
, m_maxX(std::max(p1.x, p2.x))
|
||||
, m_maxY(std::max(p1.y, p2.y))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <typename U>
|
||||
explicit Rect(Rect<U> const & src)
|
||||
: m_minX(src.minX()), m_minY(src.minY()), m_maxX(src.maxX()), m_maxY(src.maxY())
|
||||
{
|
||||
}
|
||||
explicit Rect(Rect<U> const & src) : m_minX(src.minX())
|
||||
, m_minY(src.minY())
|
||||
, m_maxX(src.maxX())
|
||||
, m_maxY(src.maxY())
|
||||
{}
|
||||
|
||||
static Rect GetEmptyRect() { return Rect(); }
|
||||
|
||||
@@ -141,8 +141,7 @@ public:
|
||||
|
||||
bool IsIntersect(Rect const & r) const
|
||||
{
|
||||
return !((m_maxX < r.m_minX) || (m_minX > r.m_maxX) || (m_maxY < r.m_minY) ||
|
||||
(m_minY > r.m_maxY));
|
||||
return !((m_maxX < r.m_minX) || (m_minX > r.m_maxX) || (m_maxY < r.m_minY) || (m_minY > r.m_maxY));
|
||||
}
|
||||
|
||||
bool IsPointInside(Point<T> const & pt) const
|
||||
@@ -152,8 +151,7 @@ public:
|
||||
|
||||
bool IsRectInside(Rect<T> const & rect) const
|
||||
{
|
||||
return (IsPointInside(Point<T>(rect.minX(), rect.minY())) &&
|
||||
IsPointInside(Point<T>(rect.maxX(), rect.maxY())));
|
||||
return (IsPointInside(Point<T>(rect.minX(), rect.minY())) && IsPointInside(Point<T>(rect.maxX(), rect.maxY())));
|
||||
}
|
||||
|
||||
Point<T> Center() const { return Point<T>((m_minX + m_maxX) / 2.0, (m_minY + m_maxY) / 2.0); }
|
||||
@@ -326,8 +324,8 @@ m2::Rect<T> const Add(m2::Rect<T> const & r, m2::Point<T> const & p)
|
||||
template <typename T>
|
||||
m2::Rect<T> const Add(m2::Rect<T> const & r1, m2::Rect<T> const & r2)
|
||||
{
|
||||
return m2::Rect<T>(std::min(r2.minX(), r1.minX()), std::min(r2.minY(), r1.minY()),
|
||||
std::max(r2.maxX(), r1.maxX()), std::max(r2.maxY(), r1.maxY()));
|
||||
return m2::Rect<T>(std::min(r2.minX(), r1.minX()), std::min(r2.minY(), r1.minY()), std::max(r2.maxX(), r1.maxX()),
|
||||
std::max(r2.maxY(), r1.maxY()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -358,10 +356,8 @@ template <typename T, typename TCollection>
|
||||
bool HasIntersection(m2::Rect<T> const & rect, TCollection const & geometry)
|
||||
{
|
||||
for (auto const & g : geometry)
|
||||
{
|
||||
if (rect.IsIntersect(g))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,104 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include "geometry/rect2d.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/rect2d.hpp"
|
||||
|
||||
namespace m2
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// bit masks for code kinds
|
||||
static const int LEFT = 1;
|
||||
static const int RIGHT = 2;
|
||||
static const int BOT = 4;
|
||||
static const int TOP = 8;
|
||||
namespace detail
|
||||
{
|
||||
// bit masks for code kinds
|
||||
static int const LEFT = 1;
|
||||
static int const RIGHT = 2;
|
||||
static int const BOT = 4;
|
||||
static int const TOP = 8;
|
||||
|
||||
// return accumulated bit mask for point-rect interaction
|
||||
template <class T>
|
||||
int vcode(m2::Rect<T> const & r, m2::Point<T> const & p)
|
||||
{
|
||||
return ((p.x < r.minX() ? LEFT : 0) +
|
||||
(p.x > r.maxX() ? RIGHT : 0) +
|
||||
(p.y < r.minY() ? BOT : 0) +
|
||||
(p.y > r.maxY() ? TOP : 0));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Intersect(m2::Rect<T> const & r, m2::Point<T> & p1, m2::Point<T> & p2, int & code1, int & code2)
|
||||
{
|
||||
code1 = code2 = 0;
|
||||
int codeClip[2] = { 0, 0 };
|
||||
int code[2] = { detail::vcode(r, p1), detail::vcode(r, p2) };
|
||||
|
||||
// do while one of the point is out of rect
|
||||
while (code[0] || code[1])
|
||||
{
|
||||
if (code[0] & code[1])
|
||||
{
|
||||
// both point area on the one side of rect
|
||||
return false;
|
||||
}
|
||||
|
||||
// choose point with non-zero code
|
||||
m2::Point<T> * pp;
|
||||
int i;
|
||||
if (code[0])
|
||||
{
|
||||
i = 0;
|
||||
pp = &p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 1;
|
||||
pp = &p2;
|
||||
}
|
||||
|
||||
// added points compare to avoid NAN numbers
|
||||
if (code[i] & detail::LEFT)
|
||||
{
|
||||
if (p1 == p2) return false;
|
||||
pp->y += (p1.y - p2.y) * (r.minX() - pp->x) / (p1.x - p2.x);
|
||||
pp->x = r.minX();
|
||||
codeClip[i] = detail::LEFT;
|
||||
}
|
||||
else if (code[i] & detail::RIGHT)
|
||||
{
|
||||
if (p1 == p2) return false;
|
||||
pp->y += (p1.y - p2.y) * (r.maxX() - pp->x) / (p1.x - p2.x);
|
||||
pp->x = r.maxX();
|
||||
codeClip[i] = detail::RIGHT;
|
||||
}
|
||||
|
||||
if (code[i] & detail::BOT)
|
||||
{
|
||||
if (p1 == p2) return false;
|
||||
pp->x += (p1.x - p2.x) * (r.minY() - pp->y) / (p1.y - p2.y);
|
||||
pp->y = r.minY();
|
||||
codeClip[i] = detail::BOT;
|
||||
}
|
||||
else if (code[i] & detail::TOP)
|
||||
{
|
||||
if (p1 == p2) return false;
|
||||
pp->x += (p1.x - p2.x) * (r.maxY() - pp->y) / (p1.y - p2.y);
|
||||
pp->y = r.maxY();
|
||||
codeClip[i] = detail::TOP;
|
||||
}
|
||||
|
||||
// update code with new point
|
||||
code[i] = detail::vcode(r, *pp);
|
||||
}
|
||||
|
||||
code1 = codeClip[0];
|
||||
code2 = codeClip[1];
|
||||
// both codes are equal to zero => points area inside rect
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Intersect(m2::Rect<T> const & r, m2::Point<T> & p1, m2::Point<T> & p2)
|
||||
{
|
||||
int code1, code2;
|
||||
return Intersect(r, p1, p2, code1, code2);
|
||||
}
|
||||
// return accumulated bit mask for point-rect interaction
|
||||
template <class T>
|
||||
int vcode(m2::Rect<T> const & r, m2::Point<T> const & p)
|
||||
{
|
||||
return ((p.x < r.minX() ? LEFT : 0) + (p.x > r.maxX() ? RIGHT : 0) + (p.y < r.minY() ? BOT : 0) +
|
||||
(p.y > r.maxY() ? TOP : 0));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <class T>
|
||||
bool Intersect(m2::Rect<T> const & r, m2::Point<T> & p1, m2::Point<T> & p2, int & code1, int & code2)
|
||||
{
|
||||
code1 = code2 = 0;
|
||||
int codeClip[2] = {0, 0};
|
||||
int code[2] = {detail::vcode(r, p1), detail::vcode(r, p2)};
|
||||
|
||||
// do while one of the point is out of rect
|
||||
while (code[0] || code[1])
|
||||
{
|
||||
if (code[0] & code[1])
|
||||
{
|
||||
// both point area on the one side of rect
|
||||
return false;
|
||||
}
|
||||
|
||||
// choose point with non-zero code
|
||||
m2::Point<T> * pp;
|
||||
int i;
|
||||
if (code[0])
|
||||
{
|
||||
i = 0;
|
||||
pp = &p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 1;
|
||||
pp = &p2;
|
||||
}
|
||||
|
||||
// added points compare to avoid NAN numbers
|
||||
if (code[i] & detail::LEFT)
|
||||
{
|
||||
if (p1 == p2)
|
||||
return false;
|
||||
pp->y += (p1.y - p2.y) * (r.minX() - pp->x) / (p1.x - p2.x);
|
||||
pp->x = r.minX();
|
||||
codeClip[i] = detail::LEFT;
|
||||
}
|
||||
else if (code[i] & detail::RIGHT)
|
||||
{
|
||||
if (p1 == p2)
|
||||
return false;
|
||||
pp->y += (p1.y - p2.y) * (r.maxX() - pp->x) / (p1.x - p2.x);
|
||||
pp->x = r.maxX();
|
||||
codeClip[i] = detail::RIGHT;
|
||||
}
|
||||
|
||||
if (code[i] & detail::BOT)
|
||||
{
|
||||
if (p1 == p2)
|
||||
return false;
|
||||
pp->x += (p1.x - p2.x) * (r.minY() - pp->y) / (p1.y - p2.y);
|
||||
pp->y = r.minY();
|
||||
codeClip[i] = detail::BOT;
|
||||
}
|
||||
else if (code[i] & detail::TOP)
|
||||
{
|
||||
if (p1 == p2)
|
||||
return false;
|
||||
pp->x += (p1.x - p2.x) * (r.maxY() - pp->y) / (p1.y - p2.y);
|
||||
pp->y = r.maxY();
|
||||
codeClip[i] = detail::TOP;
|
||||
}
|
||||
|
||||
// update code with new point
|
||||
code[i] = detail::vcode(r, *pp);
|
||||
}
|
||||
|
||||
code1 = codeClip[0];
|
||||
code2 = codeClip[1];
|
||||
// both codes are equal to zero => points area inside rect
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Intersect(m2::Rect<T> const & r, m2::Point<T> & p1, m2::Point<T> & p2)
|
||||
{
|
||||
int code1, code2;
|
||||
return Intersect(r, p1, p2, code1, code2);
|
||||
}
|
||||
} // namespace m2
|
||||
|
||||
@@ -39,8 +39,7 @@ struct DefEqualFloat
|
||||
// Determines if value of a val lays between a p1 and a p2 values with some precision.
|
||||
bool IsAlmostBetween(double val, double p1, double p2) const
|
||||
{
|
||||
return (val >= p1 - kPrecision && val <= p2 + kPrecision) ||
|
||||
(val <= p1 + kPrecision && val >= p2 - kPrecision);
|
||||
return (val >= p1 - kPrecision && val <= p2 + kPrecision) || (val <= p1 + kPrecision && val >= p2 - kPrecision);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,8 +100,7 @@ public:
|
||||
|
||||
Region() = default;
|
||||
|
||||
template <typename Points,
|
||||
typename = std::enable_if_t<std::is_constructible<Container, Points>::value>>
|
||||
template <typename Points, typename = std::enable_if_t<std::is_constructible<Container, Points>::value>>
|
||||
explicit Region(Points && points) : m_points(std::forward<Points>(points))
|
||||
{
|
||||
CalcLimitRect();
|
||||
@@ -158,9 +156,8 @@ public:
|
||||
Container & MutableData() { return m_points; }
|
||||
|
||||
template <typename EqualFn>
|
||||
static bool IsIntersect(Coord const & x11, Coord const & y11, Coord const & x12,
|
||||
Coord const & y12, Coord const & x21, Coord const & y21,
|
||||
Coord const & x22, Coord const & y22, EqualFn && equalF, Point & pt)
|
||||
static bool IsIntersect(Coord const & x11, Coord const & y11, Coord const & x12, Coord const & y12, Coord const & x21,
|
||||
Coord const & y21, Coord const & x22, Coord const & y22, EqualFn && equalF, Point & pt)
|
||||
{
|
||||
double const divider = ((y12 - y11) * (x22 - x21) - (x12 - x11) * (y22 - y21));
|
||||
if (equalF.EqualZeroSquarePrecision(divider))
|
||||
@@ -181,11 +178,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsIntersect(Point const & p1, Point const & p2, Point const & p3, Point const & p4,
|
||||
Point & pt)
|
||||
static bool IsIntersect(Point const & p1, Point const & p2, Point const & p3, Point const & p4, Point & pt)
|
||||
{
|
||||
return IsIntersect(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, typename Traits::EqualType(),
|
||||
pt);
|
||||
return IsIntersect(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, typename Traits::EqualType(), pt);
|
||||
}
|
||||
|
||||
/// Taken from Computational Geometry in C and modified
|
||||
@@ -275,7 +270,7 @@ public:
|
||||
if (!Inflate(m_rect, rectDelta, rectDelta).IsPointInside(pt))
|
||||
return false;
|
||||
|
||||
const double squaredDelta = delta * delta;
|
||||
double const squaredDelta = delta * delta;
|
||||
size_t const numPoints = m_points.size();
|
||||
|
||||
Point prev = m_points[numPoints - 1];
|
||||
@@ -402,10 +397,8 @@ template <typename Point>
|
||||
bool RegionsContain(std::vector<Region<Point>> const & regions, Point const & point)
|
||||
{
|
||||
for (auto const & region : regions)
|
||||
{
|
||||
if (region.Contains(point))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -20,163 +20,136 @@ namespace boost
|
||||
{
|
||||
namespace polygon
|
||||
{
|
||||
typedef int32_t my_coord_t;
|
||||
typedef int32_t my_coord_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Point concept.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef m2::PointI my_point_t;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Point concept.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef m2::PointI my_point_t;
|
||||
|
||||
template <>
|
||||
struct geometry_concept<my_point_t>
|
||||
template <>
|
||||
struct geometry_concept<my_point_t>
|
||||
{
|
||||
typedef point_concept type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct point_traits<my_point_t>
|
||||
{
|
||||
typedef my_point_t::value_type coordinate_type;
|
||||
|
||||
static inline coordinate_type get(my_point_t const & p, orientation_2d o) { return ((o == HORIZONTAL) ? p.x : p.y); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct point_mutable_traits<my_point_t>
|
||||
{
|
||||
typedef my_point_t::value_type Coord;
|
||||
|
||||
static inline void set(my_point_t & p, orientation_2d o, Coord v)
|
||||
{
|
||||
typedef point_concept type;
|
||||
};
|
||||
if (o == HORIZONTAL)
|
||||
p.x = v;
|
||||
else
|
||||
p.y = v;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct point_traits<my_point_t>
|
||||
static inline my_point_t construct(Coord x, Coord y) { return my_point_t(x, y); }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Polygon concept.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef m2::RegionI my_region_t;
|
||||
|
||||
template <>
|
||||
struct geometry_concept<my_region_t>
|
||||
{
|
||||
typedef polygon_concept type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct polygon_traits<my_region_t>
|
||||
{
|
||||
typedef my_region_t::Coord coordinate_type;
|
||||
typedef my_region_t::IteratorT iterator_type;
|
||||
typedef my_region_t::Value point_type;
|
||||
|
||||
// Get the begin iterator
|
||||
static inline iterator_type begin_points(my_region_t const & t) { return t.Begin(); }
|
||||
|
||||
// Get the end iterator
|
||||
static inline iterator_type end_points(my_region_t const & t) { return t.End(); }
|
||||
|
||||
// Get the number of sides of the polygon
|
||||
static inline size_t size(my_region_t const & t) { return t.Size(); }
|
||||
|
||||
// Get the winding direction of the polygon
|
||||
static inline winding_direction winding(my_region_t const & /*t*/) { return unknown_winding; }
|
||||
};
|
||||
|
||||
struct my_point_getter
|
||||
{
|
||||
my_point_t operator()(point_data<my_coord_t> const & t) { return my_point_t(t.x(), t.y()); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct polygon_mutable_traits<my_region_t>
|
||||
{
|
||||
// expects stl style iterators
|
||||
template <typename IterT>
|
||||
static inline my_region_t & set_points(my_region_t & t, IterT b, IterT e)
|
||||
{
|
||||
typedef my_point_t::value_type coordinate_type;
|
||||
t.AssignEx(b, e, my_point_getter());
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
static inline coordinate_type get(my_point_t const & p, orientation_2d o)
|
||||
{
|
||||
return ((o == HORIZONTAL) ? p.x : p.y);
|
||||
}
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Polygon set concept.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef std::vector<my_region_t> my_region_set_t;
|
||||
|
||||
template <>
|
||||
struct point_mutable_traits<my_point_t>
|
||||
template <>
|
||||
struct geometry_concept<my_region_set_t>
|
||||
{
|
||||
typedef polygon_set_concept type;
|
||||
};
|
||||
|
||||
// next we map to the concept through traits
|
||||
template <>
|
||||
struct polygon_set_traits<my_region_set_t>
|
||||
{
|
||||
typedef my_coord_t coordinate_type;
|
||||
typedef my_region_set_t::const_iterator iterator_type;
|
||||
typedef my_region_set_t operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(my_region_set_t const & t) { return t.begin(); }
|
||||
|
||||
static inline iterator_type end(my_region_set_t const & t) { return t.end(); }
|
||||
|
||||
// don't worry about these, just return false from them
|
||||
static inline bool clean(my_region_set_t const & /*t*/) { return false; }
|
||||
static inline bool sorted(my_region_set_t const & /*t*/) { return false; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct polygon_set_mutable_traits<my_region_set_t>
|
||||
{
|
||||
template <typename IterT>
|
||||
static inline void set(my_region_set_t & poly_set, IterT b, IterT e)
|
||||
{
|
||||
typedef my_point_t::value_type Coord;
|
||||
poly_set.clear();
|
||||
|
||||
static inline void set(my_point_t & p, orientation_2d o, Coord v)
|
||||
{
|
||||
if (o == HORIZONTAL)
|
||||
p.x = v;
|
||||
else
|
||||
p.y = v;
|
||||
}
|
||||
// this is kind of cheesy. I am copying the unknown input geometry
|
||||
// into my own polygon set and then calling get to populate the std::vector
|
||||
polygon_set_data<my_coord_t> ps;
|
||||
ps.insert(b, e);
|
||||
ps.get(poly_set);
|
||||
|
||||
static inline my_point_t construct(Coord x, Coord y)
|
||||
{
|
||||
return my_point_t(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Polygon concept.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef m2::RegionI my_region_t;
|
||||
|
||||
template <>
|
||||
struct geometry_concept<my_region_t>
|
||||
{
|
||||
typedef polygon_concept type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct polygon_traits<my_region_t>
|
||||
{
|
||||
typedef my_region_t::Coord coordinate_type;
|
||||
typedef my_region_t::IteratorT iterator_type;
|
||||
typedef my_region_t::Value point_type;
|
||||
|
||||
// Get the begin iterator
|
||||
static inline iterator_type begin_points(my_region_t const & t)
|
||||
{
|
||||
return t.Begin();
|
||||
}
|
||||
|
||||
// Get the end iterator
|
||||
static inline iterator_type end_points(my_region_t const & t)
|
||||
{
|
||||
return t.End();
|
||||
}
|
||||
|
||||
// Get the number of sides of the polygon
|
||||
static inline size_t size(my_region_t const & t)
|
||||
{
|
||||
return t.Size();
|
||||
}
|
||||
|
||||
// Get the winding direction of the polygon
|
||||
static inline winding_direction winding(my_region_t const & /*t*/)
|
||||
{
|
||||
return unknown_winding;
|
||||
}
|
||||
};
|
||||
|
||||
struct my_point_getter
|
||||
{
|
||||
my_point_t operator() (point_data<my_coord_t> const & t)
|
||||
{
|
||||
return my_point_t(t.x(), t.y());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct polygon_mutable_traits<my_region_t>
|
||||
{
|
||||
// expects stl style iterators
|
||||
template <typename IterT>
|
||||
static inline my_region_t & set_points(my_region_t & t, IterT b, IterT e)
|
||||
{
|
||||
t.AssignEx(b, e, my_point_getter());
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Polygon set concept.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef std::vector<my_region_t> my_region_set_t;
|
||||
|
||||
template <>
|
||||
struct geometry_concept<my_region_set_t>
|
||||
{
|
||||
typedef polygon_set_concept type;
|
||||
};
|
||||
|
||||
// next we map to the concept through traits
|
||||
template <>
|
||||
struct polygon_set_traits<my_region_set_t>
|
||||
{
|
||||
typedef my_coord_t coordinate_type;
|
||||
typedef my_region_set_t::const_iterator iterator_type;
|
||||
typedef my_region_set_t operator_arg_type;
|
||||
|
||||
static inline iterator_type begin(my_region_set_t const & t)
|
||||
{
|
||||
return t.begin();
|
||||
}
|
||||
|
||||
static inline iterator_type end(my_region_set_t const & t)
|
||||
{
|
||||
return t.end();
|
||||
}
|
||||
|
||||
// don't worry about these, just return false from them
|
||||
static inline bool clean(my_region_set_t const & /*t*/) { return false; }
|
||||
static inline bool sorted(my_region_set_t const & /*t*/) { return false; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct polygon_set_mutable_traits<my_region_set_t>
|
||||
{
|
||||
template <typename IterT>
|
||||
static inline void set(my_region_set_t & poly_set, IterT b, IterT e)
|
||||
{
|
||||
poly_set.clear();
|
||||
|
||||
// this is kind of cheesy. I am copying the unknown input geometry
|
||||
// into my own polygon set and then calling get to populate the std::vector
|
||||
polygon_set_data<my_coord_t> ps;
|
||||
ps.insert(b, e);
|
||||
ps.get(poly_set);
|
||||
|
||||
// if you had your own odd-ball polygon set you would probably have
|
||||
// to iterate through each polygon at this point and do something extra
|
||||
}
|
||||
};
|
||||
// if you had your own odd-ball polygon set you would probably have
|
||||
// to iterate through each polygon at this point and do something extra
|
||||
}
|
||||
};
|
||||
} // namespace polygon
|
||||
} // namespace boost
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconditional-uninitialized"
|
||||
@@ -36,8 +37,7 @@ double OrientedS(PointD const & p1, PointD const & p2, PointD const & p)
|
||||
return orient2d(a, b, c);
|
||||
}
|
||||
|
||||
bool IsSegmentInCone(PointD const & v, PointD const & v1, PointD const & vPrev,
|
||||
PointD const & vNext)
|
||||
bool IsSegmentInCone(PointD const & v, PointD const & v1, PointD const & vPrev, PointD const & vNext)
|
||||
{
|
||||
double const cpLR = OrientedS(vPrev, vNext, v);
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@ double OrientedS(PointD const & p1, PointD const & p2, PointD const & p);
|
||||
|
||||
/// Is segment (v, v1) in cone (vPrev, v, vNext)?
|
||||
/// @precondition (vPrev, v, vNext) is CCW.
|
||||
bool IsSegmentInCone(PointD const & v, PointD const & v1, PointD const & vPrev,
|
||||
PointD const & vNext);
|
||||
bool IsSegmentInCone(PointD const & v, PointD const & v1, PointD const & vPrev, PointD const & vNext);
|
||||
|
||||
template <typename T>
|
||||
bool Between(T a, T b, T c)
|
||||
|
||||
@@ -42,7 +42,10 @@ ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect)
|
||||
}
|
||||
|
||||
ScreenBase::ScreenBase(ScreenBase const & s, m2::PointD const & org, double scale, double angle)
|
||||
: m_Org(org), m_ViewportRect(s.m_ViewportRect), m_Scale(scale), m_Angle(angle)
|
||||
: m_Org(org)
|
||||
, m_ViewportRect(s.m_ViewportRect)
|
||||
, m_Scale(scale)
|
||||
, m_Angle(angle)
|
||||
{
|
||||
ASSERT_GREATER(m_Scale, 0.0, ());
|
||||
UpdateDependentParameters();
|
||||
@@ -52,11 +55,11 @@ void ScreenBase::UpdateDependentParameters()
|
||||
{
|
||||
m_PixelRect = CalculatePixelRect(m_Scale);
|
||||
|
||||
m_PtoG = math::Shift( /// 5. shifting on (E0, N0)
|
||||
math::Rotate( /// 4. rotating on the screen angle
|
||||
math::Scale( /// 3. scaling to translate pixel sizes to global
|
||||
math::Scale( /// 2. swapping the Y axis??? why??? supposed to be a rotation on -pi /
|
||||
/// 2 here.
|
||||
m_PtoG = math::Shift( /// 5. shifting on (E0, N0)
|
||||
math::Rotate( /// 4. rotating on the screen angle
|
||||
math::Scale( /// 3. scaling to translate pixel sizes to global
|
||||
math::Scale( /// 2. swapping the Y axis??? why??? supposed to be a rotation on -pi /
|
||||
/// 2 here.
|
||||
math::Shift( /// 1. shifting for the pixel center to become (0, 0)
|
||||
math::Identity<double, 3>(), -m_PixelRect.Center()),
|
||||
1, -1),
|
||||
@@ -93,15 +96,13 @@ double ScreenBase::CalculateAutoPerspectiveAngle(double scale)
|
||||
|
||||
if (scale > kEndPerspectiveScale1)
|
||||
{
|
||||
double const k =
|
||||
(kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1);
|
||||
double const k = (kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1);
|
||||
return kMaxPerspectiveAngle1 * k;
|
||||
}
|
||||
|
||||
if (scale > kEndPerspectiveScale2)
|
||||
{
|
||||
double const k =
|
||||
(kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2);
|
||||
double const k = (kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2);
|
||||
return kMaxPerspectiveAngle1 + (kMaxPerspectiveAngle2 - kMaxPerspectiveAngle1) * k;
|
||||
}
|
||||
|
||||
@@ -109,7 +110,10 @@ double ScreenBase::CalculateAutoPerspectiveAngle(double scale)
|
||||
}
|
||||
|
||||
// static
|
||||
double ScreenBase::GetStartPerspectiveScale() { return kStartPerspectiveScale1; }
|
||||
double ScreenBase::GetStartPerspectiveScale()
|
||||
{
|
||||
return kStartPerspectiveScale1;
|
||||
}
|
||||
|
||||
double ScreenBase::CalculatePerspectiveAngle(double scale) const
|
||||
{
|
||||
@@ -142,7 +146,10 @@ void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & px
|
||||
UpdateDependentParameters();
|
||||
}
|
||||
|
||||
void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect) { SetFromRects(glbRect, m_PixelRect); }
|
||||
void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect)
|
||||
{
|
||||
SetFromRects(glbRect, m_PixelRect);
|
||||
}
|
||||
|
||||
void ScreenBase::SetFromParams(m2::PointD const & org, double angle, double scale)
|
||||
{
|
||||
@@ -203,7 +210,10 @@ void ScreenBase::OnSize(m2::RectI const & r)
|
||||
UpdateDependentParameters();
|
||||
}
|
||||
|
||||
void ScreenBase::OnSize(int x0, int y0, int w, int h) { OnSize(m2::RectI(x0, y0, x0 + w, y0 + h)); }
|
||||
void ScreenBase::OnSize(int x0, int y0, int w, int h)
|
||||
{
|
||||
OnSize(m2::RectI(x0, y0, x0 + w, y0 + h));
|
||||
}
|
||||
|
||||
void ScreenBase::SetScale(double scale)
|
||||
{
|
||||
@@ -218,25 +228,26 @@ void ScreenBase::SetAngle(double angle)
|
||||
UpdateDependentParameters();
|
||||
}
|
||||
|
||||
int ScreenBase::GetWidth() const { return std::lround(m_PixelRect.SizeX()); }
|
||||
|
||||
int ScreenBase::GetHeight() const { return std::lround(m_PixelRect.SizeY()); }
|
||||
|
||||
ScreenBase::MatrixT ScreenBase::CalcTransform(m2::PointD const & oldPt1,
|
||||
m2::PointD const & oldPt2,
|
||||
m2::PointD const & newPt1,
|
||||
m2::PointD const & newPt2,
|
||||
bool allowRotate,
|
||||
bool allowScale)
|
||||
int ScreenBase::GetWidth() const
|
||||
{
|
||||
return std::lround(m_PixelRect.SizeX());
|
||||
}
|
||||
|
||||
int ScreenBase::GetHeight() const
|
||||
{
|
||||
return std::lround(m_PixelRect.SizeY());
|
||||
}
|
||||
|
||||
ScreenBase::MatrixT ScreenBase::CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
|
||||
m2::PointD const & newPt1, m2::PointD const & newPt2, bool allowRotate,
|
||||
bool allowScale)
|
||||
{
|
||||
double const s = allowScale ? newPt1.Length(newPt2) / oldPt1.Length(oldPt2) : 1.0;
|
||||
double const a = allowRotate ? ang::AngleTo(newPt1, newPt2) - ang::AngleTo(oldPt1, oldPt2) : 0.0;
|
||||
|
||||
MatrixT m = math::Shift(
|
||||
math::Scale(math::Rotate(math::Shift(math::Identity<double, 3>(), -oldPt1.x, -oldPt1.y), a),
|
||||
s, s),
|
||||
newPt1.x, newPt1.y);
|
||||
MatrixT m =
|
||||
math::Shift(math::Scale(math::Rotate(math::Shift(math::Identity<double, 3>(), -oldPt1.x, -oldPt1.y), a), s, s),
|
||||
newPt1.x, newPt1.y);
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -268,15 +279,14 @@ void ScreenBase::PtoG(m2::RectD const & pxRect, m2::RectD & glbRect) const
|
||||
glbRect = m2::RectD(PtoG(pxRect.LeftTop()), PtoG(pxRect.RightBottom()));
|
||||
}
|
||||
|
||||
void ScreenBase::GetTouchRect(m2::PointD const & pixPoint, double pixRadius,
|
||||
m2::AnyRectD & glbRect) const
|
||||
void ScreenBase::GetTouchRect(m2::PointD const & pixPoint, double pixRadius, m2::AnyRectD & glbRect) const
|
||||
{
|
||||
double const r = pixRadius * m_Scale;
|
||||
glbRect = m2::AnyRectD(PtoG(pixPoint), m_Angle, m2::RectD(-r, -r, r, r));
|
||||
}
|
||||
|
||||
void ScreenBase::GetTouchRect(m2::PointD const & pixPoint, double const pxWidth,
|
||||
double const pxHeight, m2::AnyRectD & glbRect) const
|
||||
void ScreenBase::GetTouchRect(m2::PointD const & pixPoint, double const pxWidth, double const pxHeight,
|
||||
m2::AnyRectD & glbRect) const
|
||||
{
|
||||
double const width = pxWidth * m_Scale;
|
||||
double const height = pxHeight * m_Scale;
|
||||
@@ -293,16 +303,13 @@ bool IsPanningAndRotate(ScreenBase const & s1, ScreenBase const & s2)
|
||||
|
||||
m2::PointD globPt(c1.x - r1.minX(), c1.y - r1.minY());
|
||||
|
||||
m2::PointD p1 =
|
||||
s1.GtoP(s1.GlobalRect().ConvertFrom(c1)) - s1.GtoP(s1.GlobalRect().ConvertFrom(c1 + globPt));
|
||||
m2::PointD p2 =
|
||||
s2.GtoP(s2.GlobalRect().ConvertFrom(c2)) - s2.GtoP(s2.GlobalRect().ConvertFrom(c2 + globPt));
|
||||
m2::PointD p1 = s1.GtoP(s1.GlobalRect().ConvertFrom(c1)) - s1.GtoP(s1.GlobalRect().ConvertFrom(c1 + globPt));
|
||||
m2::PointD p2 = s2.GtoP(s2.GlobalRect().ConvertFrom(c2)) - s2.GtoP(s2.GlobalRect().ConvertFrom(c2 + globPt));
|
||||
|
||||
return p1.EqualDxDy(p2, 0.00001);
|
||||
}
|
||||
|
||||
void ScreenBase::ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx,
|
||||
double & dy)
|
||||
void ScreenBase::ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx, double & dy)
|
||||
{
|
||||
s = sqrt(m(0, 0) * m(0, 0) + m(0, 1) * m(0, 1));
|
||||
|
||||
@@ -319,8 +326,7 @@ double ScreenBase::CalculateScale3d(double rotationAngle) const
|
||||
|
||||
// Ratio of the expanded plane's size to the original size.
|
||||
double const y3dScale = cos(rotationAngle) + sin(rotationAngle) * tan(halfFOV + rotationAngle);
|
||||
double const x3dScale =
|
||||
1.0 + 2 * sin(rotationAngle) * cos(halfFOV) / (cameraZ * cos(halfFOV + rotationAngle));
|
||||
double const x3dScale = 1.0 + 2 * sin(rotationAngle) * cos(halfFOV) / (cameraZ * cos(halfFOV + rotationAngle));
|
||||
|
||||
return std::max(x3dScale, y3dScale);
|
||||
}
|
||||
@@ -332,8 +338,7 @@ m2::RectD ScreenBase::CalculatePixelRect(double scale) const
|
||||
{
|
||||
double const scale3d = CalculateScale3d(angle);
|
||||
|
||||
return m2::RectD(m2::PointD(0.0, 0.0),
|
||||
m2::PointD(m_ViewportRect.maxX(), m_ViewportRect.maxY()) * scale3d);
|
||||
return m2::RectD(m2::PointD(0.0, 0.0), m2::PointD(m_ViewportRect.maxX(), m_ViewportRect.maxY()) * scale3d);
|
||||
}
|
||||
|
||||
return m_ViewportRect;
|
||||
@@ -342,8 +347,7 @@ m2::RectD ScreenBase::CalculatePixelRect(double scale) const
|
||||
// Place the camera at the distance, where it gives the same view of plane as the
|
||||
// orthogonal projection does. Calculate what part of the map would be visible,
|
||||
// when it is rotated through maxRotationAngle around its near horizontal side.
|
||||
void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotationAngle,
|
||||
double angleFOV)
|
||||
void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV)
|
||||
{
|
||||
ASSERT_GREATER(angleFOV, 0.0, ());
|
||||
ASSERT_LESS(angleFOV, math::pi2, ());
|
||||
@@ -405,8 +409,7 @@ void ScreenBase::SetRotationAngle(double rotationAngle)
|
||||
projectionM(0, 0) = projectionM(1, 1) = cameraZ;
|
||||
projectionM(2, 2) = m_3dAngleX != 0.0 ? (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ) : 0.0;
|
||||
projectionM(2, 3) = 1.0;
|
||||
projectionM(3, 2) =
|
||||
m_3dAngleX != 0.0 ? -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ) : 0.0;
|
||||
projectionM(3, 2) = m_3dAngleX != 0.0 ? -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ) : 0.0;
|
||||
|
||||
m_Pto3d = scaleM * rotateM * translateM * projectionM;
|
||||
m_3dtoP = math::Inverse(m_Pto3d);
|
||||
@@ -426,7 +429,10 @@ void ScreenBase::ResetPerspective()
|
||||
Move(0.0, -old_dy / 2.0);
|
||||
}
|
||||
|
||||
m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const { return PtoP3d(pt, 0.0); }
|
||||
m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const
|
||||
{
|
||||
return PtoP3d(pt, 0.0);
|
||||
}
|
||||
|
||||
double ScreenBase::GetZScale() const
|
||||
{
|
||||
@@ -439,8 +445,7 @@ m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt, double ptZ) const
|
||||
if (!m_isPerspective)
|
||||
return pt;
|
||||
Vector3dT const normalizedPoint{float(2.0 * pt.x / m_PixelRect.SizeX() - 1.0),
|
||||
-float(2.0 * pt.y / m_PixelRect.SizeY() - 1.0),
|
||||
float(ptZ * GetZScale()), 1.0};
|
||||
-float(2.0 * pt.y / m_PixelRect.SizeY() - 1.0), float(ptZ * GetZScale()), 1.0};
|
||||
|
||||
Vector3dT const perspectivePoint = normalizedPoint * m_Pto3d;
|
||||
|
||||
@@ -515,24 +520,16 @@ bool ScreenBase::IsReverseProjection3d(m2::PointD const & pt) const
|
||||
|
||||
ScreenBase::Matrix3dT ScreenBase::GetModelView() const
|
||||
{
|
||||
return ScreenBase::Matrix3dT
|
||||
{
|
||||
m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0),
|
||||
m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1),
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
return ScreenBase::Matrix3dT{
|
||||
m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0), m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1), 0, 0, 1, 0, 0, 0, 0, 1};
|
||||
}
|
||||
|
||||
ScreenBase::Matrix3dT ScreenBase::GetModelView(m2::PointD const & pivot, double scalar) const
|
||||
{
|
||||
MatrixT const & m = m_GtoP;
|
||||
double const s = 1.0 / scalar;
|
||||
return ScreenBase::Matrix3dT
|
||||
{
|
||||
s * m(0, 0), s * m(1, 0), 0, m(2, 0) + pivot.x * m(0, 0) + pivot.y * m(1, 0),
|
||||
s * m(0, 1), s * m(1, 1), 0, m(2, 1) + pivot.x * m(0, 1) + pivot.y * m(1, 1),
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
return ScreenBase::Matrix3dT{s * m(0, 0), s * m(1, 0), 0, m(2, 0) + pivot.x * m(0, 0) + pivot.y * m(1, 0),
|
||||
s * m(0, 1), s * m(1, 1), 0, m(2, 1) + pivot.x * m(0, 1) + pivot.y * m(1, 1),
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1};
|
||||
}
|
||||
|
||||
@@ -122,23 +122,18 @@ public:
|
||||
|
||||
/// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1,
|
||||
/// newPt2)
|
||||
static MatrixT CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
|
||||
m2::PointD const & newPt1, m2::PointD const & newPt2,
|
||||
bool allowRotate, bool allowScale);
|
||||
static MatrixT CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2, m2::PointD const & newPt1,
|
||||
m2::PointD const & newPt2, bool allowRotate, bool allowScale);
|
||||
|
||||
/// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact
|
||||
void SetGtoPMatrix(MatrixT const & m);
|
||||
|
||||
/// Extracting parameters from matrix, that is supposed to represent GtoP transformation
|
||||
static void ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx,
|
||||
double & dy);
|
||||
static void ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx, double & dy);
|
||||
|
||||
bool operator!=(ScreenBase const & src) const { return !(*this == src); }
|
||||
|
||||
bool operator==(ScreenBase const & src) const
|
||||
{
|
||||
return (m_GtoP == src.m_GtoP) && (m_PtoG == src.m_PtoG);
|
||||
}
|
||||
bool operator==(ScreenBase const & src) const { return (m_GtoP == src.m_GtoP) && (m_PtoG == src.m_PtoG); }
|
||||
|
||||
private:
|
||||
// Used when initializing m_GlobalRect.
|
||||
|
||||
@@ -43,10 +43,9 @@ bool IsPointOnSegment(PointD const & pt, PointD const & p1, PointD const & p2)
|
||||
bool SegmentsIntersect(PointD const & a, PointD const & b, PointD const & c, PointD const & d)
|
||||
{
|
||||
using std::max, std::min;
|
||||
return max(a.x, b.x) >= min(c.x, d.x) && min(a.x, b.x) <= max(c.x, d.x) &&
|
||||
max(a.y, b.y) >= min(c.y, d.y) && min(a.y, b.y) <= max(c.y, d.y) &&
|
||||
robust::OrientedS(a, b, c) * robust::OrientedS(a, b, d) <= 0.0 &&
|
||||
robust::OrientedS(c, d, a) * robust::OrientedS(c, d, b) <= 0.0;
|
||||
return max(a.x, b.x) >= min(c.x, d.x) && min(a.x, b.x) <= max(c.x, d.x) && max(a.y, b.y) >= min(c.y, d.y) &&
|
||||
min(a.y, b.y) <= max(c.y, d.y) && robust::OrientedS(a, b, c) * robust::OrientedS(a, b, d) <= 0.0 &&
|
||||
robust::OrientedS(c, d, a) * robust::OrientedS(c, d, b) <= 0.0;
|
||||
}
|
||||
|
||||
IntersectionResult Intersect(Segment2D const & seg1, Segment2D const & seg2, double eps)
|
||||
|
||||
@@ -37,8 +37,7 @@ bool IsPointOnSegmentEps(PointD const & pt, PointD const & p1, PointD const & p2
|
||||
bool IsPointOnSegment(PointD const & pt, PointD const & p1, PointD const & p2);
|
||||
|
||||
/// \returns true if segments (p1, p2) and (p3, p4) are intersected and false otherwise.
|
||||
bool SegmentsIntersect(PointD const & p1, PointD const & p2, PointD const & p3,
|
||||
PointD const & p4);
|
||||
bool SegmentsIntersect(PointD const & p1, PointD const & p2, PointD const & p3, PointD const & p4);
|
||||
|
||||
/// \breif Intersects two segments and finds an intersection point if any.
|
||||
/// \note |eps| applies for collinearity and for PointD errors.
|
||||
|
||||
@@ -52,8 +52,7 @@ void SimplifyDP(Iter first, Iter last, double epsilon, DistanceFn & distFn, Out
|
||||
struct SimplifyOptimalRes
|
||||
{
|
||||
SimplifyOptimalRes() = default;
|
||||
SimplifyOptimalRes(int32_t nextPoint, uint32_t pointCount)
|
||||
: m_NextPoint(nextPoint), m_PointCount(pointCount) {}
|
||||
SimplifyOptimalRes(int32_t nextPoint, uint32_t pointCount) : m_NextPoint(nextPoint), m_PointCount(pointCount) {}
|
||||
|
||||
int32_t m_NextPoint = -1;
|
||||
uint32_t m_PointCount = -1U;
|
||||
@@ -80,8 +79,7 @@ void SimplifyDP(Iter beg, Iter end, double epsilon, DistanceFn distFn, Out out)
|
||||
// Essentially, it's a trade-off between optimality and performance.
|
||||
// Values around 20 - 200 are reasonable.
|
||||
template <typename DistanceFn, typename Iter, typename Out>
|
||||
void SimplifyNearOptimal(int maxFalseLookAhead, Iter beg, Iter end, double epsilon,
|
||||
DistanceFn distFn, Out out)
|
||||
void SimplifyNearOptimal(int maxFalseLookAhead, Iter beg, Iter end, double epsilon, DistanceFn distFn, Out out)
|
||||
{
|
||||
int32_t const n = static_cast<int32_t>(end - beg);
|
||||
if (n <= 2)
|
||||
@@ -124,21 +122,20 @@ class AccumulateSkipSmallTrg
|
||||
{
|
||||
public:
|
||||
AccumulateSkipSmallTrg(DistanceFn & distFn, std::vector<Point> & vec, double eps)
|
||||
: m_distFn(distFn), m_vec(vec), m_eps(eps)
|
||||
{
|
||||
}
|
||||
: m_distFn(distFn)
|
||||
, m_vec(vec)
|
||||
, m_eps(eps)
|
||||
{}
|
||||
|
||||
void operator()(Point const & p) const
|
||||
{
|
||||
// remove points while they make linear triangle with p
|
||||
size_t count;
|
||||
while ((count = m_vec.size()) >= 2)
|
||||
{
|
||||
if (m_distFn(m_vec[count - 2], p, m_vec[count - 1]) < m_eps)
|
||||
m_vec.pop_back();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
m_vec.push_back(p);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ namespace
|
||||
{
|
||||
double constexpr kEps = 1e-5;
|
||||
|
||||
void SmoothGeneric(m2::PointD const & pt0, m2::PointD const & pt1,
|
||||
m2::PointD const & pt2, m2::PointD const & pt3,
|
||||
void SmoothGeneric(m2::PointD const & pt0, m2::PointD const & pt1, m2::PointD const & pt2, m2::PointD const & pt3,
|
||||
double alpha, size_t pointsCount, std::vector<m2::PointD> & path)
|
||||
{
|
||||
if (pt0.EqualDxDy(pt1, kEps) || pt1.EqualDxDy(pt2, kEps) || pt2.EqualDxDy(pt3, kEps))
|
||||
@@ -46,8 +45,7 @@ void SmoothGeneric(m2::PointD const & pt0, m2::PointD const & pt1,
|
||||
}
|
||||
|
||||
// The same as SmoothGeneric but optimized for alpha == 0.0.
|
||||
void SmoothUniform(m2::PointD const & pt0, m2::PointD const & pt1,
|
||||
m2::PointD const & pt2, m2::PointD const & pt3,
|
||||
void SmoothUniform(m2::PointD const & pt0, m2::PointD const & pt1, m2::PointD const & pt2, m2::PointD const & pt3,
|
||||
size_t pointsCount, std::vector<m2::PointD> & path)
|
||||
{
|
||||
if (pt0.EqualDxDy(pt1, kEps) || pt1.EqualDxDy(pt2, kEps) || pt2.EqualDxDy(pt3, kEps))
|
||||
@@ -71,8 +69,7 @@ void SmoothUniform(m2::PointD const & pt0, m2::PointD const & pt1,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void SmoothPaths(GuidePointsForSmooth const & guidePoints,
|
||||
size_t newPointsPerSegmentCount, double smoothAlpha,
|
||||
void SmoothPaths(GuidePointsForSmooth const & guidePoints, size_t newPointsPerSegmentCount, double smoothAlpha,
|
||||
std::vector<std::vector<m2::PointD>> & paths)
|
||||
{
|
||||
ASSERT_EQUAL(guidePoints.size(), paths.size(), ());
|
||||
|
||||
@@ -13,8 +13,6 @@ double constexpr kUniformAplha = 0.0;
|
||||
double constexpr kCentripetalAlpha = 0.5;
|
||||
double constexpr kChordalAlpha = 1.0;
|
||||
|
||||
void SmoothPaths(GuidePointsForSmooth const & guidePoints,
|
||||
size_t newPointsPerSegmentCount, double smoothAlpha,
|
||||
void SmoothPaths(GuidePointsForSmooth const & guidePoints, size_t newPointsPerSegmentCount, double smoothAlpha,
|
||||
std::vector<std::vector<m2::PointD>> & paths);
|
||||
} // namespace m2
|
||||
|
||||
|
||||
@@ -4,14 +4,12 @@
|
||||
|
||||
namespace m2
|
||||
{
|
||||
Spline::Spline(std::vector<PointD> const & path)
|
||||
: m_position(path)
|
||||
Spline::Spline(std::vector<PointD> const & path) : m_position(path)
|
||||
{
|
||||
InitDirections();
|
||||
}
|
||||
|
||||
Spline::Spline(std::vector<PointD> && path)
|
||||
: m_position(std::move(path))
|
||||
Spline::Spline(std::vector<PointD> && path) : m_position(std::move(path))
|
||||
{
|
||||
InitDirections();
|
||||
}
|
||||
@@ -24,10 +22,7 @@ Spline::Spline(size_t reservedSize)
|
||||
m_length.reserve(reservedSize - 1);
|
||||
}
|
||||
|
||||
SplineEx::SplineEx(size_t reservedSize)
|
||||
: Spline(reservedSize)
|
||||
{
|
||||
}
|
||||
SplineEx::SplineEx(size_t reservedSize) : Spline(reservedSize) {}
|
||||
|
||||
void Spline::AddPoint(PointD const & pt)
|
||||
{
|
||||
@@ -120,7 +115,7 @@ double Spline::GetLastLength() const
|
||||
std::pair<PointD, double> Spline::GetTangentAndLength(size_t i) const
|
||||
{
|
||||
ASSERT_LESS(i, m_length.size(), ());
|
||||
return { m_direction[i], m_length[i] };
|
||||
return {m_direction[i], m_length[i]};
|
||||
}
|
||||
|
||||
void Spline::InitDirections()
|
||||
@@ -142,13 +137,7 @@ void Spline::InitDirections()
|
||||
}
|
||||
}
|
||||
|
||||
Spline::iterator::iterator()
|
||||
: m_checker(false)
|
||||
, m_spl(NULL)
|
||||
, m_index(0)
|
||||
, m_dist(0)
|
||||
{
|
||||
}
|
||||
Spline::iterator::iterator() : m_checker(false), m_spl(NULL), m_index(0), m_dist(0) {}
|
||||
|
||||
void Spline::iterator::Attach(Spline const & spl)
|
||||
{
|
||||
@@ -247,15 +236,9 @@ void Spline::iterator::AdvanceForward(double step)
|
||||
m_avrDir += m_pos;
|
||||
}
|
||||
|
||||
SharedSpline::SharedSpline(std::vector<PointD> const & path)
|
||||
: m_spline(std::make_shared<Spline>(path))
|
||||
{
|
||||
}
|
||||
SharedSpline::SharedSpline(std::vector<PointD> const & path) : m_spline(std::make_shared<Spline>(path)) {}
|
||||
|
||||
SharedSpline::SharedSpline(std::vector<PointD> && path)
|
||||
: m_spline(std::make_shared<Spline>(std::move(path)))
|
||||
{
|
||||
}
|
||||
SharedSpline::SharedSpline(std::vector<PointD> && path) : m_spline(std::make_shared<Spline>(std::move(path))) {}
|
||||
|
||||
bool SharedSpline::IsNull() const
|
||||
{
|
||||
@@ -267,10 +250,10 @@ void SharedSpline::Reset(Spline * spline)
|
||||
m_spline.reset(spline);
|
||||
}
|
||||
|
||||
//void SharedSpline::Reset(std::vector<PointD> const & path)
|
||||
// void SharedSpline::Reset(std::vector<PointD> const & path)
|
||||
//{
|
||||
// m_spline.reset(new Spline(path));
|
||||
//}
|
||||
// m_spline.reset(new Spline(path));
|
||||
// }
|
||||
|
||||
Spline::iterator SharedSpline::CreateIterator() const
|
||||
{
|
||||
@@ -295,4 +278,4 @@ Spline const * SharedSpline::Get() const
|
||||
ASSERT(!IsNull(), ());
|
||||
return m_spline.get();
|
||||
}
|
||||
} // namespace m2
|
||||
} // namespace m2
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
|
||||
bool IsNull() const;
|
||||
void Reset(Spline * spline);
|
||||
//void Reset(std::vector<PointD> const & path);
|
||||
// void Reset(std::vector<PointD> const & path);
|
||||
|
||||
Spline::iterator CreateIterator() const;
|
||||
|
||||
|
||||
@@ -4,53 +4,54 @@
|
||||
|
||||
#include "base/matrix.hpp"
|
||||
|
||||
|
||||
/// v` = v * M, v = [x, y, 1]
|
||||
|
||||
namespace math
|
||||
{
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Rotate(Matrix<T, 3, 3> const & m, U const & cos, U const & sin)
|
||||
{
|
||||
Matrix<T, 3, 3> m1 = Identity<T, 3>();
|
||||
m1(0, 0) = cos; m1(0, 1) = sin;
|
||||
m1(1, 0) = -sin; m1(1, 1) = cos;
|
||||
return m * m1;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Rotate(Matrix<T, 3, 3> const & m, U const & angle)
|
||||
{
|
||||
return Rotate(m, cos(angle), sin(angle));
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Shift(Matrix<T, 3, 3> const & m, U const & dx, U const & dy)
|
||||
{
|
||||
Matrix<T, 3, 3> m1 = Identity<T, 3>();
|
||||
m1(2, 0) = dx;
|
||||
m1(2, 1) = dy;
|
||||
return m * m1;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Shift(Matrix<T, 3, 3> const & m, m2::Point<U> const & pt)
|
||||
{
|
||||
return Shift(m, pt.x, pt.y);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Scale(Matrix<T, 3, 3> const & m, U const & kx, U const & ky)
|
||||
{
|
||||
Matrix<T, 3, 3> m1 = Identity<T, 3>();
|
||||
m1(0, 0) = kx;
|
||||
m1(1, 1) = ky;
|
||||
return m * m1;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Scale(Matrix<T, 3, 3> const & m, m2::Point<U> const & pt)
|
||||
{
|
||||
return Scale(m, pt.x, pt.y);
|
||||
}
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Rotate(Matrix<T, 3, 3> const & m, U const & cos, U const & sin)
|
||||
{
|
||||
Matrix<T, 3, 3> m1 = Identity<T, 3>();
|
||||
m1(0, 0) = cos;
|
||||
m1(0, 1) = sin;
|
||||
m1(1, 0) = -sin;
|
||||
m1(1, 1) = cos;
|
||||
return m * m1;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Rotate(Matrix<T, 3, 3> const & m, U const & angle)
|
||||
{
|
||||
return Rotate(m, cos(angle), sin(angle));
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Shift(Matrix<T, 3, 3> const & m, U const & dx, U const & dy)
|
||||
{
|
||||
Matrix<T, 3, 3> m1 = Identity<T, 3>();
|
||||
m1(2, 0) = dx;
|
||||
m1(2, 1) = dy;
|
||||
return m * m1;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Shift(Matrix<T, 3, 3> const & m, m2::Point<U> const & pt)
|
||||
{
|
||||
return Shift(m, pt.x, pt.y);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Scale(Matrix<T, 3, 3> const & m, U const & kx, U const & ky)
|
||||
{
|
||||
Matrix<T, 3, 3> m1 = Identity<T, 3>();
|
||||
m1(0, 0) = kx;
|
||||
m1(1, 1) = ky;
|
||||
return m * m1;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
Matrix<T, 3, 3> const Scale(Matrix<T, 3, 3> const & m, m2::Point<U> const & pt)
|
||||
{
|
||||
return Scale(m, pt.x, pt.y);
|
||||
}
|
||||
} // namespace math
|
||||
|
||||
@@ -37,8 +37,7 @@ class Tree
|
||||
|
||||
bool IsIntersect(m2::RectD const & r) const
|
||||
{
|
||||
return !((m_pts[2] <= r.minX()) || (m_pts[0] >= r.maxX()) || (m_pts[3] <= r.minY()) ||
|
||||
(m_pts[1] >= r.maxY()));
|
||||
return !((m_pts[2] <= r.minX()) || (m_pts[0] >= r.maxX()) || (m_pts[3] <= r.minY()) || (m_pts[1] >= r.maxY()));
|
||||
}
|
||||
|
||||
bool operator==(Value const & r) const { return (m_val == r.m_val); }
|
||||
@@ -47,8 +46,7 @@ class Tree
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
||||
out << DebugPrint(m_val) << ", (" << m_pts[0] << ", " << m_pts[1] << ", " << m_pts[2] << ", "
|
||||
<< m_pts[3] << ")";
|
||||
out << DebugPrint(m_val) << ", (" << m_pts[0] << ", " << m_pts[1] << ", " << m_pts[2] << ", " << m_pts[3] << ")";
|
||||
|
||||
return out.str();
|
||||
}
|
||||
@@ -77,9 +75,7 @@ class Tree
|
||||
class for_each_helper
|
||||
{
|
||||
public:
|
||||
for_each_helper(m2::RectD const & r, ToDo && toDo) : m_rect(r), m_toDo(std::forward<ToDo>(toDo))
|
||||
{
|
||||
}
|
||||
for_each_helper(m2::RectD const & r, ToDo && toDo) : m_rect(r), m_toDo(std::forward<ToDo>(toDo)) {}
|
||||
|
||||
bool ScanLeft(size_t plane, Value const & v) const
|
||||
{
|
||||
@@ -153,7 +149,8 @@ private:
|
||||
bool skip = false;
|
||||
std::vector<Value const *> isect;
|
||||
|
||||
m_tree.for_each(GetFunctor(rect, [&](Value const & v) {
|
||||
m_tree.for_each(GetFunctor(rect, [&](Value const & v)
|
||||
{
|
||||
if (skip)
|
||||
return;
|
||||
|
||||
@@ -177,14 +174,14 @@ public:
|
||||
template <typename Compare>
|
||||
void ReplaceAllInRect(T const & obj, Compare comp)
|
||||
{
|
||||
ReplaceImpl(obj, GetLimitRect(obj),
|
||||
[&comp](T const & t1, T const & t2) { return comp(t1, t2) ? 1 : -1; });
|
||||
ReplaceImpl(obj, GetLimitRect(obj), [&comp](T const & t1, T const & t2) { return comp(t1, t2) ? 1 : -1; });
|
||||
}
|
||||
|
||||
template <typename Equal, typename Compare>
|
||||
void ReplaceEqualInRect(T const & obj, Equal eq, Compare comp)
|
||||
{
|
||||
ReplaceImpl(obj, GetLimitRect(obj), [&](T const & t1, T const & t2) {
|
||||
ReplaceImpl(obj, GetLimitRect(obj), [&](T const & t1, T const & t2)
|
||||
{
|
||||
if (eq(t1, t2))
|
||||
return comp(t1, t2) ? 1 : -1;
|
||||
else
|
||||
@@ -215,10 +212,8 @@ public:
|
||||
bool ForAny(ToDo && toDo) const
|
||||
{
|
||||
for (Value const & v : m_tree)
|
||||
{
|
||||
if (toDo(v.m_val))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -234,10 +229,8 @@ public:
|
||||
bool FindNode(ToDo && toDo) const
|
||||
{
|
||||
for (Value const & v : m_tree)
|
||||
{
|
||||
if (toDo(v.m_val))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
namespace m2
|
||||
{
|
||||
bool IsPointInsideTriangle(PointD const & pt, PointD const & p1,
|
||||
PointD const & p2, PointD const & p3)
|
||||
bool IsPointInsideTriangle(PointD const & pt, PointD const & p1, PointD const & p2, PointD const & p3)
|
||||
{
|
||||
double const s1 = robust::OrientedS(p1, p2, pt);
|
||||
double const s2 = robust::OrientedS(p2, p3, pt);
|
||||
@@ -21,32 +20,24 @@ bool IsPointInsideTriangle(PointD const & pt, PointD const & p1,
|
||||
// In the case of degenerate triangles we need to check that pt lies
|
||||
// on (p1, p2), (p2, p3) or (p3, p1).
|
||||
if (s1 == 0.0 && s2 == 0.0 && s3 == 0.0)
|
||||
{
|
||||
return IsPointOnSegment(pt, p1, p2) || IsPointOnSegment(pt, p2, p3) ||
|
||||
IsPointOnSegment(pt, p3, p1);
|
||||
}
|
||||
return IsPointOnSegment(pt, p1, p2) || IsPointOnSegment(pt, p2, p3) || IsPointOnSegment(pt, p3, p1);
|
||||
|
||||
return ((s1 >= 0.0 && s2 >= 0.0 && s3 >= 0.0) ||
|
||||
(s1 <= 0.0 && s2 <= 0.0 && s3 <= 0.0));
|
||||
return ((s1 >= 0.0 && s2 >= 0.0 && s3 >= 0.0) || (s1 <= 0.0 && s2 <= 0.0 && s3 <= 0.0));
|
||||
}
|
||||
|
||||
bool IsPointStrictlyInsideTriangle(PointD const & pt, PointD const & p1,
|
||||
PointD const & p2, PointD const & p3)
|
||||
bool IsPointStrictlyInsideTriangle(PointD const & pt, PointD const & p1, PointD const & p2, PointD const & p3)
|
||||
{
|
||||
double const s1 = robust::OrientedS(p1, p2, pt);
|
||||
double const s2 = robust::OrientedS(p2, p3, pt);
|
||||
double const s3 = robust::OrientedS(p3, p1, pt);
|
||||
|
||||
return ((s1 > 0.0 && s2 > 0.0 && s3 > 0.0) ||
|
||||
(s1 < 0.0 && s2 < 0.0 && s3 < 0.0));
|
||||
return ((s1 > 0.0 && s2 > 0.0 && s3 > 0.0) || (s1 < 0.0 && s2 < 0.0 && s3 < 0.0));
|
||||
}
|
||||
|
||||
bool IsPointInsideTriangles(PointD const & pt, std::vector<TriangleD> const & v)
|
||||
{
|
||||
return std::any_of(v.begin(), v.end(), [&pt](TriangleD const & t)
|
||||
{
|
||||
return IsPointInsideTriangle(pt, t.p1(), t.p2(), t.p3());
|
||||
});
|
||||
return std::any_of(v.begin(), v.end(),
|
||||
[&pt](TriangleD const & t) { return IsPointInsideTriangle(pt, t.p1(), t.p2(), t.p3()); });
|
||||
}
|
||||
|
||||
PointD GetRandomPointInsideTriangle(TriangleD const & t)
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
namespace m2
|
||||
{
|
||||
|
||||
template <typename T> struct Triangle
|
||||
template <typename T>
|
||||
struct Triangle
|
||||
{
|
||||
Point<T> m_points[3];
|
||||
|
||||
@@ -31,17 +32,14 @@ template <typename T>
|
||||
std::string DebugPrint(m2::Triangle<T> const & trg)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Triangle ["
|
||||
<< DebugPrint(trg.p1()) << ", "
|
||||
<< DebugPrint(trg.p2()) << ", "
|
||||
<< DebugPrint(trg.p3()) << "]";
|
||||
s << "Triangle [" << DebugPrint(trg.p1()) << ", " << DebugPrint(trg.p2()) << ", " << DebugPrint(trg.p3()) << "]";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
double GetTriangleArea(Point<T> const & p1, Point<T> const & p2, Point<T> const & p3)
|
||||
{
|
||||
return 0.5 * fabs((p2.x - p1.x)*(p3.y - p1.y) - (p3.x - p1.x)*(p2.y - p1.y));
|
||||
return 0.5 * fabs((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
|
||||
}
|
||||
|
||||
m2::PointD GetRandomPointInsideTriangle(m2::TriangleD const & t);
|
||||
@@ -54,13 +52,12 @@ m2::PointD ProjectPointToTriangles(m2::PointD const & pt, std::vector<m2::Triang
|
||||
/// @param[in] pt - Point to check
|
||||
/// @param[in] p1, p2, p3 - Triangle
|
||||
//@{
|
||||
bool IsPointInsideTriangle(m2::PointD const & pt, m2::PointD const & p1,
|
||||
m2::PointD const & p2, m2::PointD const & p3);
|
||||
bool IsPointInsideTriangle(m2::PointD const & pt, m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3);
|
||||
|
||||
bool IsPointStrictlyInsideTriangle(m2::PointD const & pt, m2::PointD const & p1,
|
||||
m2::PointD const & p2, m2::PointD const & p3);
|
||||
bool IsPointStrictlyInsideTriangle(m2::PointD const & pt, m2::PointD const & p1, m2::PointD const & p2,
|
||||
m2::PointD const & p3);
|
||||
|
||||
bool IsPointInsideTriangles(m2::PointD const & pt, std::vector<m2::TriangleD> const & v);
|
||||
//@}
|
||||
|
||||
} // namespace m2
|
||||
} // namespace m2
|
||||
|
||||
Reference in New Issue
Block a user