
shz.model.Polygon Maven / Gradle / Ivy
package shz.model;
import shz.msg.ServerFailureMsg;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
/**
* 多边形
*/
public class Polygon {
private final double[] xs, ys;
private final int n;
public Polygon(double[] xs, double[] ys) {
n = xs.length;
ServerFailureMsg.requireNon(n != ys.length, "多边形点位数不等x:%d,y:%d", xs.length, ys.length);
ServerFailureMsg.requireNon(n < 3, "多边形点位数小于3");
this.xs = xs;
this.ys = ys;
}
/**
* 度数和
*/
public final double degreeSum() {
double degreeSum1 = 0D, degreeSum2 = 0D;
int count1 = 0, count2 = 0;
double x1, y1, x2, y2, x3, y3;
double a1, b1, c1, a2, b2, c2, a3, b3, c3;
int i = 0, max = n - 1;
x1 = xs[max] * Sphere.RADIAN;
y1 = ys[max] * Sphere.RADIAN;
x2 = xs[i] * Sphere.RADIAN;
y2 = ys[i] * Sphere.RADIAN;
x3 = xs[i + 1] * Sphere.RADIAN;
y3 = ys[i + 1] * Sphere.RADIAN;
a1 = Math.cos(y1) * Math.cos(x1);
b1 = Math.cos(y1) * Math.sin(x1);
c1 = Math.sin(y1);
a2 = Math.cos(y2) * Math.cos(x2);
b2 = Math.cos(y2) * Math.sin(x2);
c2 = Math.sin(y2);
a3 = Math.cos(y3) * Math.cos(x3);
b3 = Math.cos(y3) * Math.sin(x3);
c3 = Math.sin(y3);
double v = a2 * a2 + b2 * b2 + c2 * c2;
double coe1 = v / (a2 * a1 + b2 * b1 + c2 * c1);
double at1 = coe1 * a1 - a2;
double bt1 = coe1 * b1 - b2;
double ct1 = coe1 * c1 - c2;
double coe3 = v / (a2 * a3 + b2 * b3 + c2 * c3);
double at3 = coe3 * a3 - a2;
double bt3 = coe3 * b3 - b2;
double ct3 = coe3 * c3 - c2;
double anl = bt3 * ct1 - ct3 * bt1;
double bnl = ct3 * at1 - at3 * ct1;
double cnl = at3 * bt1 - bt3 * at1;
double degree = Math.acos((at3 * at1 + bt3 * bt1 + ct3 * ct1) / (Math.sqrt(at3 * at3 + bt3 * bt3 + ct3 * ct3) * Math.sqrt(at1 * at1 + bt1 * bt1 + ct1 * ct1)));
if ((a2 != 0D ? anl / a2 : b2 != 0D ? bnl / b2 : cnl / c2) > 0D) {
degreeSum1 += degree;
++count1;
} else {
degreeSum2 += degree;
++count2;
}
++i;
for (; i < max; ++i) {
x1 = xs[i - 1] * Sphere.RADIAN;
y1 = ys[i - 1] * Sphere.RADIAN;
x2 = xs[i] * Sphere.RADIAN;
y2 = ys[i] * Sphere.RADIAN;
x3 = xs[i + 1] * Sphere.RADIAN;
y3 = ys[i + 1] * Sphere.RADIAN;
a1 = Math.cos(y1) * Math.cos(x1);
b1 = Math.cos(y1) * Math.sin(x1);
c1 = Math.sin(y1);
a2 = Math.cos(y2) * Math.cos(x2);
b2 = Math.cos(y2) * Math.sin(x2);
c2 = Math.sin(y2);
a3 = Math.cos(y3) * Math.cos(x3);
b3 = Math.cos(y3) * Math.sin(x3);
c3 = Math.sin(y3);
v = a2 * a2 + b2 * b2 + c2 * c2;
coe1 = v / (a2 * a1 + b2 * b1 + c2 * c1);
at1 = coe1 * a1 - a2;
bt1 = coe1 * b1 - b2;
ct1 = coe1 * c1 - c2;
coe3 = v / (a2 * a3 + b2 * b3 + c2 * c3);
at3 = coe3 * a3 - a2;
bt3 = coe3 * b3 - b2;
ct3 = coe3 * c3 - c2;
anl = bt3 * ct1 - ct3 * bt1;
bnl = ct3 * at1 - at3 * ct1;
cnl = at3 * bt1 - bt3 * at1;
degree = Math.acos((at3 * at1 + bt3 * bt1 + ct3 * ct1) / (Math.sqrt(at3 * at3 + bt3 * bt3 + ct3 * ct3) * Math.sqrt(at1 * at1 + bt1 * bt1 + ct1 * ct1)));
if ((a2 != 0D ? anl / a2 : b2 != 0D ? bnl / b2 : cnl / c2) > 0D) {
degreeSum1 += degree;
++count1;
} else {
degreeSum2 += degree;
++count2;
}
}
x1 = xs[i - 1] * Sphere.RADIAN;
y1 = ys[i - 1] * Sphere.RADIAN;
x2 = xs[i] * Sphere.RADIAN;
y2 = ys[i] * Sphere.RADIAN;
x3 = xs[0] * Sphere.RADIAN;
y3 = ys[0] * Sphere.RADIAN;
a1 = Math.cos(y1) * Math.cos(x1);
b1 = Math.cos(y1) * Math.sin(x1);
c1 = Math.sin(y1);
a2 = Math.cos(y2) * Math.cos(x2);
b2 = Math.cos(y2) * Math.sin(x2);
c2 = Math.sin(y2);
a3 = Math.cos(y3) * Math.cos(x3);
b3 = Math.cos(y3) * Math.sin(x3);
c3 = Math.sin(y3);
v = a2 * a2 + b2 * b2 + c2 * c2;
coe1 = v / (a2 * a1 + b2 * b1 + c2 * c1);
at1 = coe1 * a1 - a2;
bt1 = coe1 * b1 - b2;
ct1 = coe1 * c1 - c2;
coe3 = v / (a2 * a3 + b2 * b3 + c2 * c3);
at3 = coe3 * a3 - a2;
bt3 = coe3 * b3 - b2;
ct3 = coe3 * c3 - c2;
anl = bt3 * ct1 - ct3 * bt1;
bnl = ct3 * at1 - at3 * ct1;
cnl = at3 * bt1 - bt3 * at1;
degree = Math.acos((at3 * at1 + bt3 * bt1 + ct3 * ct1) / (Math.sqrt(at3 * at3 + bt3 * bt3 + ct3 * ct3) * Math.sqrt(at1 * at1 + bt1 * bt1 + ct1 * ct1)));
if ((a2 != 0D ? anl / a2 : b2 != 0D ? bnl / b2 : cnl / c2) > 0D) {
degreeSum1 += degree;
++count1;
} else {
degreeSum2 += degree;
++count2;
}
double tempSum1 = degreeSum1 + (2 * Math.PI * count2 - degreeSum2);
double tempSum2 = (2 * Math.PI * count1 - degreeSum1) + degreeSum2;
if (degreeSum1 > degreeSum2) return tempSum1 < (xs.length - 2) * Math.PI + 1 ? tempSum1 : tempSum2;
else return tempSum2 < (xs.length - 2) * Math.PI + 1 ? tempSum2 : tempSum1;
}
private GeneralPath path;
public final GeneralPath path() {
if (path != null) return path;
path = new GeneralPath(PathIterator.WIND_NON_ZERO, n);
path.moveTo(xs[0], ys[0]);
for (int i = 1; i < n; ++i) path.lineTo(xs[i], ys[i]);
path.lineTo(xs[0], ys[0]);
path.closePath();
return path;
}
public final Rectangle2D rectangle() {
return path().getBounds2D();
}
public final boolean contains(double x, double y) {
return path().contains(x, y);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy