⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surfaceshapegeometry.java

📁 world wind java sdk 源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                this.p1Lon = p1.getLongitude().degrees;                this.p1Lat = p1.getLatitude().degrees;            }            deltaX = p1Lon - p0Lon;            deltaY = p1Lat - p0Lat;        }        public double getLonAtLat(double lat) {            if (Math.abs(deltaY) < 1.e-10) {                return Double.MAX_VALUE;            }            double t = (lat - p0Lat) / deltaY;            return (p0Lon + t * deltaX);        }        public double getLatAtLon(double lon) {            if (Math.abs(deltaX) < 1.e-10) {                return Double.MAX_VALUE;            }            double t = (lon - p0Lon) / deltaX;            return (p0Lat + t * deltaY);        }    }    //    // Returns a list of SectorGeometry objects whose extent overlaps that of this object.    //    protected Iterable<SectorGeometry> getIntersectingGeometryTiles(SectorGeometryList sg) {        ArrayList<SectorGeometry> intersectingGeom = null;        for (SectorGeometry geom : sg) {            if (!this.getSector().intersects(geom.getSector()))                continue;            if (intersectingGeom == null)                intersectingGeom = new ArrayList<SectorGeometry>();            intersectingGeom.add(geom);        }        return intersectingGeom;    }    public Position getReferencePosition() {        // Here we pick a vertex arbitrarily. Whereas it might seem reasonable to pick the centroid of the        // collection of points, computing that value is tricky in cases where the shape spans the dateline.        return new Position(positions.get(0), 0);    }    public Vec4 getReferencePoint() {        Position ref = getReferencePosition();        double elev = this.globe.getElevation(ref.getLatitude(), ref.getLongitude());        return this.globe.computePointFromPosition(ref.getLatitude(), ref.getLongitude(), elev);    }    public void move(Position delta) {        if (delta == null) {            String msg = Logging.getMessage("nullValue.PositionIsNull");            Logging.logger().severe(msg);            throw new IllegalArgumentException(msg);        }        this.moveTo(this.getReferencePosition().add(delta));    }    /**     * Move the shape over the sphereoid surface without maintaining its original azimuth -- its orientation relative to     * North.     *     * @param position the new position to move the shapes reference position to.     */    public void shiftTo(Position position) {        if (this.globe == null)            return;        if (position == null) {            String msg = Logging.getMessage("nullValue.PositionIsNull");            Logging.logger().severe(msg);            throw new IllegalArgumentException(msg);        }        Vec4 p1 = globe.computePointFromPosition(this.getReferencePosition().getLatitude(),                this.getReferencePosition().getLongitude(), 0);        Vec4 p2 = globe.computePointFromPosition(position.getLatitude(), position.getLongitude(), 0);        Vec4 delta = p2.subtract3(p1);        for (int i = 0; i < this.positions.size(); i++) {            LatLon ll = this.positions.get(i);            Vec4 p = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0);            p = p.add3(delta);            Position pos = globe.computePositionFromPoint(p);            this.positions.set(i, new LatLon(pos.getLatitude(), pos.getLongitude()));        }        this.polyline.setPositions(this.positions, 0.);        for (Triangle t : triangles) {            for (int i = 0; i < 3; i++) {                LatLon ll = t.vertices[i];                Vec4 p = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0);                p = p.add3(delta);                Position pos = globe.computePositionFromPoint(p);                t.vertices[i] = new LatLon(pos.getLatitude(), pos.getLongitude());            }            t.setOrClearDatelineFlag();        }        resetBounds();        this.forceSurfaceIntersect = true;    }    /**     * Move the shape over the sphereoid surface while maintaining its original azimuth -- its orientation relative to     * North.     *     * @param position the new position to move the shapes reference position to.     */    public void moveTo(Position position) {        if (LatLon.positionsCrossDateLine(this.positions)) {            // TODO: Replace this hack by figuring out how to *accurately* move date-line crossing shapes using the            // distance/azimuth method used below for shapes that do not cross the dateline.            shiftTo(position);            return;        }        LatLon oldRef = this.getReferencePosition();        for (int i = 0; i < this.positions.size(); i++) {            LatLon p = this.positions.get(i);            double distance = LatLon.greatCircleDistance(oldRef, p).radians;            double azimuth = LatLon.greatCircleAzimuth(oldRef, p).radians;            LatLon pp = LatLon.greatCircleEndPosition(position, azimuth, distance);            this.positions.set(i, pp);        }        this.polyline.setPositions(positions, 0.);        for (Triangle t : this.triangles) {            for (int i = 0; i < 3; i++) {                LatLon p = t.vertices[i];                double distance = LatLon.greatCircleDistance(oldRef, p).radians;                double azimuth = LatLon.greatCircleAzimuth(oldRef, p).radians;                LatLon pp = LatLon.greatCircleEndPosition(position, azimuth, distance);                t.vertices[i] = pp;            }            t.setOrClearDatelineFlag();        }        resetBounds();        this.forceSurfaceIntersect = true;    }    public static SurfaceShapeGeometry createEllipse(Globe globe, LatLon center, double majorAxisLength,                                                     double minorAxisLength, Angle orientation, int intervals,                                                     Color interiorColor, Color borderColor) {        if (orientation == null)            orientation = Angle.ZERO;        if (majorAxisLength <= 0) {            String message = Logging.getMessage("Geom.MajorAxisInvalid");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (minorAxisLength <= 0) {            String message = Logging.getMessage("Geom.MajorAxisInvalid");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        int numPositions = 1 + Math.max(intervals, 4);        final ArrayList<LatLon> positions = new ArrayList<LatLon>();        double radius = globe.getRadiusAt(center.getLatitude(), center.getLongitude());        double da = 2 * Math.PI / (numPositions - 1);        for (int i = 0; i < numPositions; i++) {            // azimuth runs positive clockwise from north and through 360 degrees.            double angle = (i != numPositions - 1) ? i * da : 0;            double azimuth = Math.PI / 2 - (angle + orientation.radians);            double xLength = majorAxisLength * Math.cos(angle);            double yLength = minorAxisLength * Math.sin(angle);            double distance = Math.sqrt(xLength * xLength + yLength * yLength);            LatLon p = LatLon.greatCircleEndPosition(center, azimuth, distance / radius);            positions.add(p);        }        return new SurfacePolygonGeometry(positions, interiorColor, borderColor);    }    private Sector getSector() {        if (this.sector == null)            this.sector = Sector.boundingSector(this.positions);        return this.sector;    }    private Extent getExtent(DrawContext dc) {        if (this.extent == null)            this.extent = this.globe.computeBoundingCylinder(dc.getVerticalExaggeration(), this.getSector());        return extent;    }    private void resetBounds() {        this.sector = null;        this.extent = null;    }    //    // Uses OpenGL's GLU facilities to perform a top-level triangulation of our SurfaceShape.    //    private void tessellate() {        this.triangles = new Vector<Triangle>();        GLU glu = new GLU();        GLUtessellator tobj = glu.gluNewTess();        TessCallback tessCallback = new TessCallback(glu);        glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback);        glu.gluTessCallback(tobj, GLU.GLU_TESS_COMBINE, tessCallback);        glu.gluTessCallback(tobj, GLU.GLU_EDGE_FLAG, tessCallback);        glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback);        glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback);        glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback);        // GLU wants double arrays for the vertices...        int len = this.positions.size();        double[][] pnts = new double[len][3];        glu.gluTessBeginPolygon(tobj, null);        glu.gluTessBeginContour(tobj);        for (int i = 0; i < len; i++) {            LatLon p = this.positions.get(i);            pnts[i][X] = p.getLongitude().degrees;            if (pnts[i][X] > 0.)                pnts[i][X] -= Angle.POS360.degrees;  // deal with dateline issues; will get correct at triangle re-assembly...            pnts[i][Y] = p.getLatitude().degrees;            // NOTE: found out the hard way that these polygons had better be planar!            // The tessellation fails or misbehaves otherwise.            pnts[i][Z] = 0.;            glu.gluTessVertex(tobj, pnts[i], 0, pnts[i]);        }        glu.gluTessEndContour(tobj);        glu.gluTessEndPolygon(tobj);        glu.gluDeleteTess(tobj);  // free this resource.    }    //    // Tessellation callback implementation.    //    private class TessCallback extends GLUtessellatorCallbackAdapter {        public TessCallback(GLU glu) {            this.glu = glu;        }        public void begin(int type) {            this.state = 0;            this.type = type;            this.flipOrder = false;            this.currTriangle = new Triangle();        }        public void end() {            // NO-OP        }        public void vertex(Object data) {            if (!(data instanceof double[])) {                return;            }            double[] d = (double[]) data;            Angle lon = Angle.normalizedLongitude(Angle.fromDegrees(d[0]));            Angle lat = Angle.normalizedLatitude(Angle.fromDegrees(d[1]));            this.currTriangle.vertices[this.state++] = new LatLon(lat, lon);            if (this.state == 3) {                this.currTriangle.setOrClearDatelineFlag();                SurfaceShapeGeometry.this.triangles.add(this.currTriangle);                // Depending upon type of triangles we're being handed, we may already have 2 vertices for the                // next triangle;  gather those accordingly.                switch (this.type) {                    case GL.GL_TRIANGLE_FAN:                        Triangle t = new Triangle();                        t.vertices[0] = this.currTriangle.vertices[0];  // these indices reflect the definition of                        t.vertices[1] = this.currTriangle.vertices[2];  // TRIANGLE_FAN                        this.currTriangle = t;                        this.state = 2;                        break;                    case GL.GL_TRIANGLE_STRIP:                        t = new Triangle();                        short first;                        short second;                        if (this.flipOrder) {                            first = 0;      // Again, these indices reflect how TRIANGLE_STRIPs work.                            second = 2;                        } else {                            first = 2;                            second = 1;                        }                        this.flipOrder = !this.flipOrder;                        t.vertices[0] = this.currTriangle.vertices[first];                        t.vertices[1] = this.currTriangle.vertices[second];                        this.currTriangle = t;                        this.state = 2;                        break;                    case GL.GL_TRIANGLES:                        this.currTriangle = new Triangle();                        this.state = 0;                        break;                    default:                        String msg = Logging.getMessage("SurfaceShape.UnknownTriangleForm", this.type);                        Logging.logger().severe(msg);                }            }        }        public void combine(double[] coords, Object[] data, float[] weight, Object[] outData) {            double[] newCoord = new double[3];            newCoord[X] = coords[X];            newCoord[Y] = coords[Y];            newCoord[Z] = coords[Z];            outData[0] = newCoord;        }        public void edgeFlag(boolean isEdge) {        }        public void error(int errnum) {            String glErrorMsg = glu.gluErrorString(errnum);            String msg = Logging.getMessage("SurfaceShape.TessellationError", glErrorMsg);            Logging.logger().severe(msg);            throw new RuntimeException();        }        private GLU glu;        private int type;        private Triangle currTriangle;        private short state;        // state is the number of vertices we've collected to make a triangle...        private boolean flipOrder;  // reflect the rules for gathering vertices from a triangle_strip    }    private static class Triangle {        LatLon[] vertices;        boolean spansDateline;        public Triangle() {            vertices = new LatLon[3];            spansDateline = false;        }        public void setOrClearDatelineFlag() {            spansDateline = false;            if (vertices[0] != null || vertices[1] != null || vertices[2] != null) {                if (LatLon.positionsCrossLongitudeBoundary(vertices[0], vertices[1]) ||                        LatLon.positionsCrossLongitudeBoundary(vertices[1], vertices[2]) ||                        LatLon.positionsCrossLongitudeBoundary(vertices[0], vertices[2])) {                    spansDateline = true;                }            }        }    }}

⌨️ 快捷键说明

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