/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.awt.geom.Point2D;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
int id;
double theta;
CPoint prev, next;
public CPoint(int id, double x, double y)
{
super(x, y);
this.id = id;
theta
= Math.
atan2(y, x
); if(theta
< 0) theta
= 2*Math.
PI + theta
; }
{
return String.
format("%d : (%f,%f) : %f [(%f,%f) : (%f,%f)]", id, getX
(), getY
(), theta, prev.
getX(), prev.
getY(), next.
getX(), next.
getY()); }
}
public static void main
(String[] args
) {
double[][] coords = {{-0.708, 0.707, 0.309, -0.951, 0.587, -0.809},
{1, 0, 0, 1, -1, 0, 0, -1, 0.708, -0.708}};
double areaSum = 0;
List<CPoint> pts = new ArrayList<>();
for(int i=0; i<coords.length; i++)
{
List<CPoint> poly = new ArrayList<>();
for(int j=0; j<coords[i].length; j+=2)
{
poly.add(new CPoint(i, coords[i][j], coords[i][j+1]));
}
poly.
sort((a, b
) -> Double.
compare(a.
theta, b.
theta)); pts.addAll(poly);
int n = poly.size();
for(int j=0; j<n; j++)
{
poly.get(j).prev = poly.get((j + n - 1) % n);
poly.get(j).next = poly.get((j + 1) % n);
}
areaSum += area(poly);
}
pts.
sort((a, b
) -> Double.
compare(a.
theta, b.
theta));
List<Point2D> intersections = new ArrayList<>();
int n = pts.size();
for(int i=0, j=n-1; i<n; j=i++)
{
if(pts.get(j).id != pts.get(i).id)
{
intersections.add(intersect(pts.get(j), pts.get(j).next, pts.get(i).prev, pts.get(i)));
}
}
double areaInt = area(intersections);
double iou = areaInt/(areaSum - areaInt);
}
static double area(List<? extends Point2D> poly)
{
double area = 0;
for(int i=0, j=poly.size()-1; i<poly.size(); j=i++)
area += (poly.get(j).getX() * poly.get(i).getY()) - (poly.get(i).getX() * poly.get(j).getY());
}
// https://r...content-available-to-author-only...e.org/wiki/Find_the_intersection_of_two_lines#Java
{
double a1 = p2.getY() - p1.getY();
double b1 = p1.getX() - p2.getX();
double c1 = a1 * p1.getX() + b1 * p1.getY();
double a2 = p4.getY() - p3.getY();
double b2 = p3.getX() - p4.getX();
double c2 = a2 * p3.getX() + b2 * p3.getY();
double delta = a1 * b2 - a2 * b1;
return new Point2D.
Double((b2
* c1
- b1
* c2
) / delta,
(a1
* c2
- a2
* c1
) / delta
); }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLmF3dC5nZW9tLlBvaW50MkQ7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgSWRlb25lCnsKCXN0YXRpYyBjbGFzcyBDUG9pbnQgZXh0ZW5kcyBQb2ludDJELkRvdWJsZQoJewoJCWludCBpZDsKCQlkb3VibGUgdGhldGE7CgkJQ1BvaW50IHByZXYsIG5leHQ7CgkJCgkJcHVibGljIENQb2ludChpbnQgaWQsIGRvdWJsZSB4LCBkb3VibGUgeSkKCQl7CgkJCXN1cGVyKHgsIHkpOwoJCQl0aGlzLmlkID0gaWQ7CgkJCXRoZXRhID0gTWF0aC5hdGFuMih5LCB4KTsKCQkJaWYodGhldGEgPCAwKSB0aGV0YSA9IDIqTWF0aC5QSSArIHRoZXRhOwoJCX0KCQoJCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQoJCXsKCQkJcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVkIDogKCVmLCVmKSA6ICVmIFsoJWYsJWYpIDogKCVmLCVmKV0iLCBpZCwgZ2V0WCgpLCBnZXRZKCksIHRoZXRhLCBwcmV2LmdldFgoKSwgcHJldi5nZXRZKCksIG5leHQuZ2V0WCgpLCBuZXh0LmdldFkoKSk7CgkJfQoJfQoJCglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQoJewoJCWRvdWJsZVtdW10gY29vcmRzID0ge3stMC43MDgsIDAuNzA3LCAwLjMwOSwgLTAuOTUxLCAwLjU4NywgLTAuODA5fSwKCQkJCSAgICAgICAgICAgICAgIHsxLCAwLCAwLCAxLCAtMSwgMCwgMCwgLTEsIDAuNzA4LCAtMC43MDh9fTsKCQkKCQlkb3VibGUgYXJlYVN1bSA9IDA7CgoJCUxpc3Q8Q1BvaW50PiBwdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKCQlmb3IoaW50IGk9MDsgaTxjb29yZHMubGVuZ3RoOyBpKyspCgkJewoJCQlMaXN0PENQb2ludD4gcG9seSA9IG5ldyBBcnJheUxpc3Q8PigpOwoJCQlmb3IoaW50IGo9MDsgajxjb29yZHNbaV0ubGVuZ3RoOyBqKz0yKQoJCQl7CgkJCQlwb2x5LmFkZChuZXcgQ1BvaW50KGksIGNvb3Jkc1tpXVtqXSwgY29vcmRzW2ldW2orMV0pKTsKCQkJfQoJCQkKCQkJcG9seS5zb3J0KChhLCBiKSAtPiBEb3VibGUuY29tcGFyZShhLnRoZXRhLCBiLnRoZXRhKSk7CgkJCXB0cy5hZGRBbGwocG9seSk7CgkJCQoJCQlpbnQgbiA9IHBvbHkuc2l6ZSgpOwoJCQlmb3IoaW50IGo9MDsgajxuOyBqKyspCgkJCXsKCQkJCXBvbHkuZ2V0KGopLnByZXYgPSBwb2x5LmdldCgoaiArIG4gLSAxKSAlIG4pOwoJCQkJcG9seS5nZXQoaikubmV4dCA9IHBvbHkuZ2V0KChqICsgMSkgJSBuKTsJCQkJCgkJCX0KCQkJCgkJCWFyZWFTdW0gKz0gYXJlYShwb2x5KTsKCQl9CQkKCQkJCQoJCXB0cy5zb3J0KChhLCBiKSAtPiBEb3VibGUuY29tcGFyZShhLnRoZXRhLCBiLnRoZXRhKSk7CgkJCQkKCQlMaXN0PFBvaW50MkQ+IGludGVyc2VjdGlvbnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKCQlpbnQgbiA9IHB0cy5zaXplKCk7CgkJZm9yKGludCBpPTAsIGo9bi0xOyBpPG47IGo9aSsrKQoJCXsKCQkJaWYocHRzLmdldChqKS5pZCAhPSBwdHMuZ2V0KGkpLmlkKQoJCQl7CgkJCQlpbnRlcnNlY3Rpb25zLmFkZChpbnRlcnNlY3QocHRzLmdldChqKSwgcHRzLmdldChqKS5uZXh0LCBwdHMuZ2V0KGkpLnByZXYsIHB0cy5nZXQoaSkpKTsKCQkJfQoJCX0KCgkJZG91YmxlIGFyZWFJbnQgPSBhcmVhKGludGVyc2VjdGlvbnMpOwoJCWRvdWJsZSBpb3UgPSBhcmVhSW50LyhhcmVhU3VtIC0gYXJlYUludCk7CgkJU3lzdGVtLm91dC5wcmludGxuKGlvdSk7Cgl9CgoJc3RhdGljIGRvdWJsZSBhcmVhKExpc3Q8PyBleHRlbmRzIFBvaW50MkQ+IHBvbHkpCgl7CgkJZG91YmxlIGFyZWEgPSAwOwoJCWZvcihpbnQgaT0wLCBqPXBvbHkuc2l6ZSgpLTE7IGk8cG9seS5zaXplKCk7IGo9aSsrKQoJCQlhcmVhICs9IChwb2x5LmdldChqKS5nZXRYKCkgKiBwb2x5LmdldChpKS5nZXRZKCkpIC0gKHBvbHkuZ2V0KGkpLmdldFgoKSAqIHBvbHkuZ2V0KGopLmdldFkoKSk7CgkJcmV0dXJuIE1hdGguYWJzKGFyZWEpLzI7Cgl9CgoJLy8gaHR0cHM6Ly9yLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5lLm9yZy93aWtpL0ZpbmRfdGhlX2ludGVyc2VjdGlvbl9vZl90d29fbGluZXMjSmF2YQoJc3RhdGljIFBvaW50MkQgaW50ZXJzZWN0KFBvaW50MkQgcDEsIFBvaW50MkQgcDIsIFBvaW50MkQgcDMsIFBvaW50MkQgcDQpCgl7CgkgIGRvdWJsZSBhMSA9IHAyLmdldFkoKSAtIHAxLmdldFkoKTsKCSAgZG91YmxlIGIxID0gcDEuZ2V0WCgpIC0gcDIuZ2V0WCgpOwoJICBkb3VibGUgYzEgPSBhMSAqIHAxLmdldFgoKSArIGIxICogcDEuZ2V0WSgpOwoJCgkgIGRvdWJsZSBhMiA9IHA0LmdldFkoKSAtIHAzLmdldFkoKTsKCSAgZG91YmxlIGIyID0gcDMuZ2V0WCgpIC0gcDQuZ2V0WCgpOwoJICBkb3VibGUgYzIgPSBhMiAqIHAzLmdldFgoKSArIGIyICogcDMuZ2V0WSgpOwoJCgkgIGRvdWJsZSBkZWx0YSA9IGExICogYjIgLSBhMiAqIGIxOwoJICByZXR1cm4gbmV3IFBvaW50MkQuRG91YmxlKChiMiAqIGMxIC0gYjEgKiBjMikgLyBkZWx0YSwgKGExICogYzIgLSBhMiAqIGMxKSAvIGRlbHRhKTsgICAgCgl9Cn0=