All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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