📄 ellipsoidalglobe.java
字号:
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.globes;import gov.nasa.worldwind.*;import gov.nasa.worldwind.avlist.*;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.render.*;import gov.nasa.worldwind.terrain.*;import gov.nasa.worldwind.util.*;import java.util.*;/** * @author Tom Gaskins * @version $Id: EllipsoidalGlobe.java 9709 2009-03-27 01:33:50Z tgaskins $ */public class EllipsoidalGlobe extends WWObjectImpl implements Globe{ protected final double equatorialRadius; protected final double polarRadius; protected final double es; private final Vec4 center; private ElevationModel elevationModel; private Tessellator tessellator; public EllipsoidalGlobe(double equatorialRadius, double polarRadius, double es, ElevationModel em) { this.equatorialRadius = equatorialRadius; this.polarRadius = polarRadius; this.es = es; // assume it's consistent with the two radii this.center = Vec4.ZERO; this.elevationModel = em; this.tessellator = (Tessellator) WorldWind.createConfigurationComponent(AVKey.TESSELLATOR_CLASS_NAME); } public EllipsoidalGlobe(double equatorialRadius, double polarRadius, double es, ElevationModel em, Vec4 center) { this.equatorialRadius = equatorialRadius; this.polarRadius = polarRadius; this.es = es; // assume it's consistent with the two radii this.center = center; this.elevationModel = em; this.tessellator = (Tessellator) WorldWind.createConfigurationComponent(AVKey.TESSELLATOR_CLASS_NAME); } protected class StateKey { protected Globe globe; protected final Tessellator tessellator; protected double verticalExaggeration; public StateKey(DrawContext dc) { this.globe = dc.getGlobe(); this.tessellator = EllipsoidalGlobe.this.tessellator; this.verticalExaggeration = dc.getVerticalExaggeration(); } @SuppressWarnings({"RedundantIfStatement"}) @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; StateKey stateKey = (StateKey) o; if (Double.compare(stateKey.verticalExaggeration, verticalExaggeration) != 0) return false; if (globe != null ? !globe.equals(stateKey.globe) : stateKey.globe != null) return false; if (tessellator != null ? !tessellator.equals(stateKey.tessellator) : stateKey.tessellator != null) return false; return true; } @Override public int hashCode() { int result; long temp; result = (globe != null ? globe.hashCode() : 0); result = 31 * result + (tessellator != null ? tessellator.hashCode() : 0); temp = verticalExaggeration != +0.0d ? Double.doubleToLongBits(verticalExaggeration) : 0L; result = 31 * result + (int) (temp ^ (temp >>> 32)); return result; } } public Object getStateKey(DrawContext dc) { return new StateKey(dc); } public Tessellator getTessellator() { return tessellator; } public void setTessellator(Tessellator tessellator) { this.tessellator = tessellator; } public ElevationModel getElevationModel() { return elevationModel; } public void setElevationModel(ElevationModel elevationModel) { this.elevationModel = elevationModel; } public double getRadius() { return this.equatorialRadius; } public double getEquatorialRadius() { return this.equatorialRadius; } public double getPolarRadius() { return this.polarRadius; } public double getMaximumRadius() { return this.equatorialRadius; } public double getRadiusAt(Angle latitude, Angle longitude) { if (latitude == null || longitude == null) { String msg = Logging.getMessage("nullValue.AngleIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } return this.computePointFromPosition(latitude, longitude, 0d).getLength3(); } public double getRadiusAt(LatLon latLon) { if (latLon == null) { String msg = Logging.getMessage("nullValue.LatLonIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } return this.computePointFromPosition(latLon.getLatitude(), latLon.getLongitude(), 0d).getLength3(); } public double getEccentricitySquared() { return this.es; } public double getDiameter() { return this.equatorialRadius * 2; } public Vec4 getCenter() { return this.center; } public double getMaxElevation() { return this.elevationModel != null ? this.elevationModel.getMaxElevation() : 0; } public double getMinElevation() { return this.elevationModel != null ? this.elevationModel.getMinElevation() : 0; } public double[] getMinAndMaxElevations(Sector sector) { if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } return this.elevationModel != null ? this.elevationModel.getExtremeElevations(sector) : new double[] {0, 0}; } public Extent getExtent() { return this; } public boolean intersects(Frustum frustum) { if (frustum == null) { String message = Logging.getMessage("nullValue.FrustumIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } return frustum.intersects(this); } public Intersection[] intersect(Line line) { return this.intersect(line, this.equatorialRadius, this.polarRadius); } public Intersection[] intersect(Line line, double altitude) { return this.intersect(line, this.equatorialRadius + altitude, this.polarRadius + altitude); } protected Intersection[] intersect(Line line, double equRadius, double polRadius) { if (line == null) { String message = Logging.getMessage("nullValue.LineIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Taken from Lengyel, 2Ed., Section 5.2.3, page 148. double m = equRadius / polRadius; // "ratio of the x semi-axis length to the y semi-axis length" double n = 1d; // "ratio of the x semi-axis length to the z semi-axis length" double m2 = m * m; double n2 = n * n; double r2 = equRadius * equRadius; // nominal radius squared //equRadius * polRadius; double vx = line.getDirection().x; double vy = line.getDirection().y; double vz = line.getDirection().z; double sx = line.getOrigin().x; double sy = line.getOrigin().y; double sz = line.getOrigin().z; double a = vx * vx + m2 * vy * vy + n2 * vz * vz; double b = 2d * (sx * vx + m2 * sy * vy + n2 * sz * vz); double c = sx * sx + m2 * sy * sy + n2 * sz * sz - r2; double discriminant = discriminant(a, b, c); if (discriminant < 0) return null; double discriminantRoot = Math.sqrt(discriminant); if (discriminant == 0) { Vec4 p = line.getPointAt((-b - discriminantRoot) / (2 * a)); return new Intersection[] {new Intersection(p, true)}; } else // (discriminant > 0) { Vec4 near = line.getPointAt((-b - discriminantRoot) / (2 * a)); Vec4 far = line.getPointAt((-b + discriminantRoot) / (2 * a)); if (c >= 0) // Line originates outside the Globe. return new Intersection[] {new Intersection(near, false), new Intersection(far, false)}; else // Line originates inside the Globe. return new Intersection[] {new Intersection(far, false)}; } } static private double discriminant(double a, double b, double c) { return b * b - 4 * a * c; } /** * Determines if and where a <code>Triangle</code> intersects the globe ellipsoid at a given elevation. * * @param t the <code>Trinagle</code>. * @param elevation the elevation to test for. * @return an array of two <code>Intersection</code> or null if no intersection was found. */ public Intersection[] intersect(Triangle t, double elevation) { if (t == null) { String message = Logging.getMessage("nullValue.TriangleIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } boolean bA = isPointAboveElevation(t.getA(), elevation); boolean bB = isPointAboveElevation(t.getB(), elevation); boolean bC = isPointAboveElevation(t.getC(), elevation); if (!(bA ^ bB) && !(bB ^ bC)) return null; // all triangle points are either above or below the given elevation Intersection[] inter = new Intersection[2]; int idx = 0; // Assumes that intersect(Line) returns only one intersection when the line // originates inside the ellipsoid at the given elevation. if (bA ^ bB) if (bA) inter[idx++] = intersect(new Line(t.getB(), t.getA().subtract3(t.getB())), elevation)[0]; else inter[idx++] = intersect(new Line(t.getA(), t.getB().subtract3(t.getA())), elevation)[0]; if (bB ^ bC) if (bB) inter[idx++] = intersect(new Line(t.getC(), t.getB().subtract3(t.getC())), elevation)[0]; else inter[idx++] = intersect(new Line(t.getB(), t.getC().subtract3(t.getB())), elevation)[0]; if (bC ^ bA) if (bC) inter[idx] = intersect(new Line(t.getA(), t.getC().subtract3(t.getA())), elevation)[0]; else inter[idx] = intersect(new Line(t.getC(), t.getA().subtract3(t.getC())), elevation)[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -