package org.dynmap.utils; import java.util.ArrayList; public class Polygon { public static class Point2D { public double x, y; public Point2D(double x, double y) { this.x = x; this.y = y; } } private ArrayList<Point2D> v = new ArrayList<Point2D>(); public void addVertex(Point2D p) { v.add(p); } public void addVertex(double x, double y) { v.add(new Point2D(x, y)); } public int size() { return v.size(); } public Point2D getVertex(int i) { return v.get(i); } // Sutherland-Hodgman polygon clipping: public Polygon clip(double xmin, double ymin, double xmax, double ymax) { ArrayList<Point2D> newpoly = new ArrayList<Point2D>(v); // Make copy ArrayList<Point2D> poly = new ArrayList<Point2D>(); ArrayList<Point2D> wrkpoly; int n; Point2D a, b; boolean aIns, bIns; // whether A or B is on the same side as the rectangle // Clip against x == xmax: n = newpoly.size(); if (n > 0) { // Local through line segments - clip b = newpoly.get(n-1); for (int i=0; i<n; i++) { a = b; b = newpoly.get(i); aIns = a.x <= xmax; bIns = b.x <= xmax; if (aIns != bIns) { poly.add(new Point2D(xmax, a.y + (b.y - a.y) * (xmax - a.x)/(b.x - a.x))); } if (bIns) { poly.add(b); } } wrkpoly = newpoly; newpoly = poly; poly = wrkpoly; poly.clear(); // Clip against x == xmin: n = newpoly.size(); if (n > 0) { // Local through line segments - clip b = newpoly.get(n-1); for (int i=0; i<n; i++) { a = b; b = newpoly.get(i); aIns = a.x >= xmin; bIns = b.x >= xmin; if (aIns != bIns) { poly.add(new Point2D(xmin, a.y + (b.y - a.y) * (xmin - a.x)/(b.x - a.x))); } if (bIns) { poly.add(b); } } wrkpoly = newpoly; newpoly = poly; poly = wrkpoly; poly.clear(); // Clip against y == ymax: n = newpoly.size(); if (n > 0) { // Local through line segments - clip b = newpoly.get(n-1); for (int i=0; i<n; i++) { a = b; b = newpoly.get(i); aIns = a.y <= ymax; bIns = b.y <= ymax; if (aIns != bIns) { poly.add(new Point2D(a.x + (b.x - a.x) * (ymax - a.y)/(b.y - a.y), ymax)); } if (bIns) { poly.add(b); } } wrkpoly = newpoly; newpoly = poly; poly = wrkpoly; poly.clear(); // Clip against y == ymin: n = newpoly.size(); if (n > 0) { b = newpoly.get(n-1); for (int i=0; i<n; i++) { a = b; b = newpoly.get(i); aIns = a.y >= ymin; bIns = b.y >= ymin; if (aIns != bIns) { poly.add(new Point2D(a.x + (b.x - a.x) * (ymin - a.y)/(b.y - a.y), ymin)); } if (bIns) { poly.add(b); } } wrkpoly = newpoly; newpoly = poly; } } } } Polygon rslt = null; if (newpoly.size() > 0) { rslt = new Polygon(); rslt.v = newpoly; } return rslt; } }