两点间距离
// 两点间距离
const double Geo::distance(const double x0, const double y0, const double x1, const double y1)
{
return std::sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
}
// 两点间距离
const double Geo::distance(const Point &point0, const Point &point1)
{
return std::sqrt((point0.x - point1.x) * (point0.x - point1.x)
+ (point0.y - point1.y) * (point0.y - point1.y));
}
点到有限长线段或无线长直线距离
点到直线距离:如果为有限长线段且垂足不在线段上,则计算点到线段端点距离。
// 点到直线距离,如果为有限长线段且垂足不在线段上,则计算点到线段端点距离
const double Geo::distance(const Point &point, const Line &line, const bool infinite)
{
if (line.front().x == line.back().x)
{
if (infinite)
{
return std::abs(point.x - line.front().x);
}
else
{
if ((point.y >= line.front().y && point.y <= line.back().y) ||
(point.y <= line.front().y && point.y >= line.back().y))
{
return std::abs(point.x - line.front().x);
}
else
{
return std::min(Geo::distance(point, line.front()), Geo::distance(point, line.back()));
}
}
}
else if (line.front().y == line.back().y)
{
if (infinite)
{
return std::abs(point.y - line.front().y);
}
else
{
if ((point.x >= line.front().x && point.x <= line.back().x) ||
(point.x <= line.front().x && point.x >= line.back().x))
{
return std::abs(point.y - line.front().y);
}
else
{
return std::min(Geo::distance(point, line.front()), Geo::distance(point, line.back()));
}
}
}
const double a = line.back().y - line.front().y,
b = line.front().x - line.back().x,
c = line.back().x * line.front().y - line.front().x * line.back().y;
if (infinite)
{
return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
}
else
{
const double k = ((point.x - line.front().x) * (line.back().x - line.front().x) +
(point.y - line.front().y) * (line.back().y - line.front().y)) /
(std::pow(line.back().x - line.front().x, 2) + std::pow(line.back().y - line.front().y, 2));
const double x = line.front().x + k * (line.back().x - line.front().x);
if ((x >= line.front().x && x <= line.back().x) || (x <= line.front().x && x >= line.back().x))
{
return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
}
else
{
return std::min(Geo::distance(point, line.front()), Geo::distance(point, line.back()));
}
}
}
// 点到直线距离,如果为有限长线段且垂足不在线段上,则计算点到线段端点距离
const double Geo::distance(const Point &point, const Point &start, const Point &end, const bool infinite)
{
if (start.x == end.x)
{
if (infinite)
{
return std::abs(point.x - start.x);
}
else
{
if ((point.y >= start.y && point.y <= end.y) ||
(point.y <= start.y && point.y >= end.y))
{
return std::abs(point.x - start.x);
}
else
{
return std::min(Geo::distance(point, start), Geo::distance(point, end));
}
}
}
else if (start.y == end.y)
{
if (infinite)
{
return std::abs(point.y - start.y);
}
else
{
if ((point.x >= start.x && point.x <= end.x) ||
(point.x <= start.x && point.x >= end.x))
{
return std::abs(point.y - start.y);
}
else
{
return std::min(Geo::distance(point, start), Geo::distance(point, end));
}
}
}
const double a = end.y - start.y,
b = start.x - end.x,
c = end.x * start.y - start.x * end.y;
if (infinite)
{
return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
}
else
{
const double k = ((point.x - start.x) * (end.x - start.x) +
(point.y - start.y) * (end.y - start.y)) /
(std::pow(end.x - start.x, 2) + std::pow(end.y - start.y, 2));
const double x = start.x + k * (end.x - start.x);
if ((x >= start.x && x <= end.x) || (x <= start.x && x >= end.x))
{
return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
}
else
{
return std::min(Geo::distance(point, start), Geo::distance(point, end));
}
}
}
点到多段线距离
点到多段线距离:计算点到每一段有限长线段的距离,取最近距离。
// 点到多段线距离,计算点到每一段有限长线段的距离,取最近距离
const double Geo::distance(const Point &point, const Polyline &polyline)
{
double dis = DBL_MAX;
for (size_t i = 1, count = polyline.size(); i < count; ++i)
{
dis = std::min(dis, Geo::distance(point, polyline[i - 1], polyline[i]));
}
return dis;
}
点到多边形距离
点到多边形距离:计算点到每一段有限长线段的距离,取最近距离。
// 点到多边形距离,计算点到每一段有限长线段的距离,取最近距离
const double Geo::distance(const Point &point, const Polygon &polygon)
{
double dis = DBL_MAX;
for (size_t i = 1, count = polygon.size(); i < count; ++i)
{
dis = std::min(dis, Geo::distance(point, polygon[i - 1], polygon[i]));
}
return dis;
}