barycentricquadrilateral.java

来自「world wind java sdk 源码」· Java 代码 · 共 222 行

JAVA
222
字号
/*Copyright (C) 2001, 2008 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.geom;import java.util.*;import java.awt.*;/** * See http://www.cs.kuleuven.be/~ares/Publications/LagaeDutre2005AnEfficientRayQuadrilateralIntersectionTest/paper.pdf * for a description of the calculations used to compute barycentric and bilinear coordinates. * * @author tag * @version $Id: BarycentricQuadrilateral.java 9080 2009-03-01 00:23:52Z tgaskins $ */public class BarycentricQuadrilateral extends BarycentricTriangle{    protected Vec4 p11;    private double[] w11;    public BarycentricQuadrilateral(Vec4 p00, Vec4 p10, Vec4 p11, Vec4 p01)    {        super(p00, p10, p01);        this.p11 = p11;        this.w11 = this.getBarycentricCoords(this.p11);    }    public BarycentricQuadrilateral(LatLon p00, LatLon p10, LatLon p11, LatLon p01)    {        super(p00, p10, p01);        this.p11 = new Vec4(p11.getLongitude().getRadians(), p11.getLatitude().getRadians(), 0);        this.w11 = this.getBarycentricCoords(this.p11);    }    public BarycentricQuadrilateral(Point p00, Point p10, Point p11, Point p01)    {        super(p00, p10, p01);        this.p11 = new Vec4(p11.x, p11.y, 0);        this.w11 = this.getBarycentricCoords(this.p11);    }    public Vec4 getP11()    {        return p11;    }    @Override    public boolean contains(Vec4 p)    {        return this.invertBilinear(p) != null;    }    @SuppressWarnings({"UnnecessaryLocalVariable"})    public double[] getBilinearCoords(double alpha, double beta)    {        // TODO: this method isn't always finding the correct -- or any -- roots        double eps = 1e-9;        double u, v;        double alpha11 = this.w11[1];        double beta11 = this.w11[2];        if (Math.abs(alpha11 - 1) < eps) // if alpha11 == 1        {            u = alpha;            if (Math.abs(beta11 - 1) < eps) // if beta == 1                v = beta;            else                v = beta / (u * (beta11 - 1) + 1);        }        else if (Math.abs(beta11 - 1) < eps) // if beta = 1        {            v = beta;            u = alpha / (v * (alpha11 - 1) + 1);        }        else        {            double a = 1d - beta11;            double b = alpha * (beta11 - 1) - beta * (alpha11 - 1) - 1;            double c = alpha;            double b24ac = b * b - 4 * a * c;            if (a == 0 || b24ac < 0)                return new double[] {-1, -1}; // TODO: Warn.            double q = -0.5 * (b + (b != 0 ? Math.signum(b) : 1) * Math.sqrt(b24ac));            u = q / a;            double ualt = c / q;            u = Math.abs(u) <= Math.abs(ualt) ? u : ualt;            if (u < 0 || u > 1)                u = c / q;            v = u * (beta11 - 1) + 1;            v = Math.abs(v) >= eps ? beta / v : -1;        }        return new double[] {u, v};    }    public double[] getBilinearCoords(Vec4 point)    {        double[] w = this.getBarycentricCoords(point);        return this.getBilinearCoords(w[1], w[2]);    }    public double[] invertBilinear(Vec4 U)    {        return invertBilinear(U, this.p00, this.p10, this.p11, this.p01);    }    public static double[] invertBilinear(Vec4 U, Vec4 X, Vec4 Y, Vec4 Z, Vec4 W)    {        Vec4 s1 = W.subtract3(X);        Vec4 s2 = Z.subtract3(Y);        Vec4 UminX = U.subtract3(X);        Vec4 UminY = U.subtract3(Y);        Vec4 normal = Z.subtract3(X).cross3(W.subtract3(Y));        double A = s1.cross3(s2).dot3(normal);        double B = s2.cross3(UminX).dot3(normal) - s1.cross3(UminY).dot3(normal);        double C = UminX.cross3(UminY).dot3(normal);        double descriminant = B * B - 4d * A * C;        if (descriminant < 0)            return null;        descriminant = Math.sqrt(descriminant);        double beta = B > 0 ? (-B - descriminant) / (2d * A) : 2d * C / (-B + descriminant);        Vec4 Sbeta1 = Vec4.mix3(beta, X, W);        Vec4 Sbeta2 = Vec4.mix3(beta, Y, Z);        double alpha = U.subtract3(Sbeta1).dot3(Sbeta2.subtract3(Sbeta1)) / Sbeta2.subtract3(Sbeta1).dotSelf3();        return new double[] {alpha, beta};    }////    private static ArrayList<Vec4> makePoints(double x0, double y0, double x1, double y1)//    {//        ArrayList<Vec4> points = new ArrayList<Vec4>();////        for (double y = y0; y <= y1; y += 1)//        {//            for (double x = x0; x <= x1; x += 1)//            {//                points.add(new Vec4(x, y, 0));//            }//        }////        return points;//    }//    private static Vec4 g0 = new Vec4(-122.4126, 34.3674, 0);//    private static Vec4 g1 = new Vec4(-117.6527, 34.3674, 0);//    private static Vec4 g2 = new Vec4(-117.6527, 41.4899, 0);//    private static Vec4 g3 = new Vec4(-122.4126, 41.4899, 0);//    private static Vec4 g0 = new Vec4(-144, 18, 0);//    private static Vec4 g1 = new Vec4(-108, 18, 0);//    private static Vec4 g2 = new Vec4(-108, 54, 0);//    private static Vec4 g3 = new Vec4(-144, 54, 0);    private static Vec4 g0 = new Vec4(-180, -90, 0);    private static Vec4 g1 = new Vec4( 180, -90, 0);    private static Vec4 g2 = new Vec4( 180,  90, 0);    private static Vec4 g3 = new Vec4(-180,  90, 0);//    private static Vec4 i0 = new Vec4(-122.1594, 34.3680, 0);//    private static Vec4 i1 = new Vec4(-117.9151, 34.3674, 0);//    private static Vec4 i2 = new Vec4(-117.6527, 41.4891, 0);//    private static Vec4 i3 = new Vec4(-122.4126, 41.4899, 0);    private static Vec4 i0 = new Vec4(0d, 0d, 0d);    private static Vec4 i1 = new Vec4(1d, 0d, 0d);    private static Vec4 i2 = new Vec4(2d, 2d, 0d);    private static Vec4 i3 = new Vec4(0d, 1d, 0d);    private static ArrayList<Vec4> testPoints = new ArrayList<Vec4>(Arrays.asList(        g0, g1, g2, g3,        i0, i1, i2, i3,        new Vec4(-17, 0, 0)//        new Vec4(-122.4, 34.2, 0),//        new Vec4(-120.6, 34.2, 0),//        new Vec4(-120.6, 36, 0),//        new Vec4(-122.4, 36, 0)    ));    public static void main(String[] args)    {        BarycentricPlanarShape bc = new BarycentricQuadrilateral(i0, i1, i2, i3);        for (Vec4 point : testPoints)        {            double[] w = bc.getBarycentricCoords(point);            Vec4 p = bc.getPoint(w);            double[] uv = bc.getBilinearCoords(w[1], w[2]);            System.out.printf("%s, %s: ( %f, %f, %f) : ( %f, %f), %s\n",                point, p, w[0], w[1], w[2], uv[0], uv[1], p.equals(point) ? "true" : "false");        }////        BarycentricPlanarShape bc = new BarycentricQuadrilateral(new Vec4(4, 3, 0), new Vec4(7, 1, 0),//            new Vec4(10, 5, 0), new Vec4(7, 7, 0));////        ArrayList<Vec4> points = makePoints(0, 0, 14, 10);//        for (Vec4 point : points)//        {//            double[] w = bc.getBarycentricCoords(point);//            Vec4 p = bc.getPoint(w);//            double[] uv = bc.getBilinearCoords(w[1], w[2]);////            System.out.printf("%s, %s: ( %f, %f, %f) : ( %f, %f), %s\n",//                point, p, w[0], w[1], w[2], uv[0], uv[1], p.equals(point) ? "true" : "false");//        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?