Я пытаюсь вычислить многоугольник, который окружает линию, соединяющую несколько точек (например, дорожку GPX).
На рисунке ниже показан пример с дорожкой в виде красной линии и желаемого многоугольника в синем.
В качестве упрощения красные точки обозначены x и y, а не широтой / долготой.
Как мне вычислить такую среду (голубой многоугольник), если у меня есть только список из трех точек, указывающих путь?
Частичные решения (например, только для двух точек) или подсказки о математических библиотеках (в Java), которые предоставляют алгоритмы для таких вычислений, также позволили бы мне сделать один шаг вперед.
Дополнительные предположения:
- Трек свободен от пересечений.
Обновление:
Используя подход, представленный Рогачем и Ксаном, я столкнулся с некоторыми проблемами, если угол между линиями меньше 90 градусов или больше 270 градусов:
Как видите, многоугольник сам пересекается, что приводит к серьезной проблеме.
С моей точки зрения, лучше использовать java.awt.geom.Area
:
Мое решение (на основе кода Рогача):
Для каждой линии, соединяющей две точки дорожки, я вычисляю окружающий многоугольник. После этого я добавляю (объединение областей) вычисляемый многоугольник к области, которая выполняет все необходимые вычисления для меня. Поскольку в области строго используется алгоритм «или» при добавлении новых многоугольников, мне не нужно заботиться о «самопересечениях» многоугольника, как представлено в обновлении выше.
Area area = new Area();
for (int i = 1; i < points.size(); i++) {
Point2D point1 = points.get(i - 1);
Point2D point2 = points.get(i);
Line2D.Double ln = new Line2D.Double(point1.getX(), point1.getY(), point2.getX(), point2.getY());
double indent = 15.0; // distance from central line
double length = ln.getP1().distance(ln.getP2());
double dx_li = (ln.getX2() - ln.getX1()) / length * indent;
double dy_li = (ln.getY2() - ln.getY1()) / length * indent;
// moved p1 point
double p1X = ln.getX1() - dx_li;
double p1Y = ln.getY1() - dy_li;
// line moved to the left
double lX1 = ln.getX1() - dy_li;
double lY1 = ln.getY1() + dx_li;
double lX2 = ln.getX2() - dy_li;
double lY2 = ln.getY2() + dx_li;
// moved p2 point
double p2X = ln.getX2() + dx_li;
double p2Y = ln.getY2() + dy_li;
// line moved to the right
double rX1_ = ln.getX1() + dy_li;
double rY1 = ln.getY1() - dx_li;
double rX2 = ln.getX2() + dy_li;
double rY2 = ln.getY2() - dx_li;
Path2D p = new Path2D.Double();
p.moveTo(lX1, lY1);
p.lineTo(lX2, lY2);
p.lineTo(p2X, p2Y);
p.lineTo(rX2, rY2);
p.lineTo(rX1_, rY1);
p.lineTo(p1X, p1Y);
p.lineTo(lX1, lY1);
area.add(new Area(p));
}