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

📄 edgeboundedsector.java

📁 world wind java sdk 源码
💻 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.terrain.ebs;import gov.nasa.worldwind.geom.Angle;import gov.nasa.worldwind.geom.LatLon;import gov.nasa.worldwind.geom.Sector;import gov.nasa.worldwind.geom.Vec4;import gov.nasa.worldwind.globes.Globe;import gov.nasa.worldwind.util.Logging;import java.util.Iterator;import java.util.NoSuchElementException;/** * @author Jim Miller * @version $Id: EdgeBoundedSector.java 7478 2008-11-11 14:54:53Z jmiller $ */public class EdgeBoundedSector extends Sector{	private Edge[] boundary;	private static Globe theGlobe = null;	private EdgeBoundedSector(Angle minLat, Angle maxLat, Angle minLon, Angle maxLon, Edge[] b)	{		super(minLat,maxLat,minLon,maxLon);		boundary = new Edge[4];        System.arraycopy(b,0,boundary,0,4);	}	public LatLon averageOfCorners()	{		Angle sumLat = Angle.fromDegrees(0.0);		Angle sumLon = Angle.fromDegrees(0.0);		for (int i=0 ; i<4 ; i++)		{			LatLon ll = boundary[i].getStartPoint();			sumLat = sumLat.add(ll.getLatitude());			sumLon = sumLon.add(ll.getLongitude());		}		return new LatLon(sumLat.multiply(0.25), sumLon.multiply(0.25));	}	@Override    public Vec4 computeCenterPoint(Globe globe, double exaggeration)    {        if (globe == null)        {            String msg = Logging.getMessage("nullValue.GlobeIsNull");            Logging.logger().severe(msg);            throw new IllegalArgumentException(msg);        }		LatLon average = averageOfCorners();		Angle avgLat = average.getLatitude();		Angle avgLon = average.getLongitude();        return globe.computePointFromPosition(avgLat, avgLon, exaggeration * globe.getElevation(avgLat, avgLon));    }	@Override    public Vec4[] computeCornerPoints(Globe globe, double exaggeration)    {        if (globe == null)        {            String msg = Logging.getMessage("nullValue.GlobeIsNull");            Logging.logger().severe(msg);            throw new IllegalArgumentException(msg);        }        Vec4[] corners = new Vec4[4];		for (int i=0 ; i<4 ; i++)		{			LatLon ll = boundary[i].getStartPoint();			Angle lat = ll.getLatitude();			Angle lon = ll.getLongitude();			corners[i] = globe.computePointFromPosition(lat,lon, exaggeration * globe.getElevation(lat,lon));		}        return corners;    }    @Override    public boolean containsDegrees(double degreesLatitude, double degreesLongitude)    {        double f = Math.PI / 180.0;        return containsRadians(f*degreesLatitude, f*degreesLongitude);    }    @Override    public boolean containsRadians(double radiansLatitude, double radiansLongitude)    {        // initial cull        if (!super.containsRadians(radiansLatitude,radiansLongitude))            return false;        // Need to look closer with respect to any GreatEllipseEdges that        // might be present        for (int i=0 ; i<4 ; i++)        {            if (boundary[i] instanceof GreatEllipseEdge)            {                GreatEllipseEdge ge = (GreatEllipseEdge)boundary[i];                Vec4 normal = ge.getOutwardPointingNormal();                Vec4 sp = ge.getStartPointXYZ();                Vec4 givenPoint = theGlobe.computePointFromPosition(                        Angle.fromRadians(radiansLatitude),Angle.fromRadians(radiansLongitude),0.0);                Vec4 toPoint = givenPoint.subtract3(sp);                if (normal.dot3(toPoint) > 0.0)                    return false;            }        }        return true;    }    private static EdgeBoundedSector fromEdges(Edge[] b)	{		double minLat=0.0, maxLat=0.0, minLon=0.0, maxLon=0.0;		// Determine the overall min/max latitude/longitude. This bounding box		// information will be loose for great ellipse edges.		for (int i=0 ; i<4 ; i++)		{			LatLon start = b[i].getStartPoint();			double lat = start.getLatitude().getDegrees();			double lon = start.getLongitude().getDegrees();			if (i == 0)			{				minLat = maxLat = lat;				minLon = maxLon = lon;			}			else			{				if (lat < minLat) minLat = lat;				else if (lat > maxLat) maxLat = lat;				if (lon < minLon) minLon = lon;				else if (lon > maxLon) maxLon = lon;			}		}		return new EdgeBoundedSector(			Angle.fromDegrees(minLat),Angle.fromDegrees(maxLat),			Angle.fromDegrees(minLon),Angle.fromDegrees(maxLon),b);	}    @Override    public LatLon getCentroid()    {        return averageOfCorners();    }    public Edge getEdge(int i) { return boundary[i]; }	public static EdgeBoundedSector[] initialCubeMapping(Angle latitudeCutoff)	{		EdgeBoundedSector[] s = new EdgeBoundedSector[6];		Edge[] e = new Edge[4];		// start at the dateline and work around, creating the four lateral Sectors		// We ensure that the edges are stored in a CCW order (when viewed from outside		// the ellipsoid) around the sector.		Angle negLatitudeCutoff = Angle.fromDegrees(-latitudeCutoff.getDegrees());		// face 0		e[0] = new ConstantLonEdge(negLatitudeCutoff,latitudeCutoff,   Angle.NEG180);		e[1] = new ConstantLatEdge(   latitudeCutoff,Angle.NEG180,     Angle.NEG90);		e[2] = new ConstantLonEdge(   latitudeCutoff,negLatitudeCutoff,Angle.NEG90);		e[3] = new ConstantLatEdge(negLatitudeCutoff,Angle.NEG90,      Angle.NEG180);		s[0] = EdgeBoundedSector.fromEdges(e);		// face 1		e[0] = new ConstantLonEdge(negLatitudeCutoff,latitudeCutoff,    Angle.NEG90);		e[1] = new ConstantLatEdge(   latitudeCutoff,Angle.NEG90,       Angle.ZERO);		e[2] = new ConstantLonEdge(   latitudeCutoff,negLatitudeCutoff, Angle.ZERO);		e[3] = new ConstantLatEdge(negLatitudeCutoff,Angle.ZERO,        Angle.NEG90);		s[1] = EdgeBoundedSector.fromEdges(e);		// face 2		e[0] = new ConstantLonEdge(negLatitudeCutoff,latitudeCutoff,    Angle.ZERO);		e[1] = new ConstantLatEdge(   latitudeCutoff,Angle.ZERO,        Angle.POS90);		e[2] = new ConstantLonEdge(   latitudeCutoff,negLatitudeCutoff, Angle.POS90);		e[3] = new ConstantLatEdge(negLatitudeCutoff,Angle.POS90,       Angle.ZERO);		s[2] = EdgeBoundedSector.fromEdges(e);		// face 3		e[0] = new ConstantLonEdge(negLatitudeCutoff,latitudeCutoff,    Angle.POS90);		e[1] = new ConstantLatEdge(   latitudeCutoff,Angle.POS90,       Angle.POS180);		e[2] = new ConstantLonEdge(   latitudeCutoff,negLatitudeCutoff, Angle.POS180);		e[3] = new ConstantLatEdge(negLatitudeCutoff,Angle.POS180,      Angle.POS90);		s[3] = EdgeBoundedSector.fromEdges(e);		// face 4 - south pole region		e[0] = new ConstantLatEdge(negLatitudeCutoff,Angle.POS180,Angle.POS90);		e[1] = new ConstantLatEdge(negLatitudeCutoff,Angle.POS90, Angle.ZERO);		e[2] = new ConstantLatEdge(negLatitudeCutoff,Angle.ZERO,  Angle.NEG90);		e[3] = new ConstantLatEdge(negLatitudeCutoff,Angle.NEG90, Angle.NEG180);		s[4] = EdgeBoundedSector.fromEdges(e);		// face 5 - north pole region		e[0] = new ConstantLatEdge(latitudeCutoff,Angle.NEG180, Angle.NEG90);		e[1] = new ConstantLatEdge(latitudeCutoff,Angle.NEG90,  Angle.ZERO);		e[2] = new ConstantLatEdge(latitudeCutoff,Angle.ZERO,   Angle.POS90);		e[3] = new ConstantLatEdge(latitudeCutoff,Angle.POS90,  Angle.POS180);		s[5] = EdgeBoundedSector.fromEdges(e);		return s;	}    /**     * Creates an iterator over the four corners of the sector, starting with the southwest position and continuing     * counter-clockwise.     *     * @return an iterator for the sector.     */    public Iterator<LatLon> iterator()    {        return new Iterator<LatLon>()        {            private int position = 0;            public boolean hasNext()            {                return this.position < 4;            }            public LatLon next()            {                if (this.position > 3)                    throw new NoSuchElementException();                return boundary[position++].getStartPoint();            }            public void remove()            {                throw new UnsupportedOperationException();            }        };    }	public static void recordGlobe(Globe globe)	{		EdgeBoundedSector.theGlobe = globe;	}	@Override	public Sector[] subdivide()	{		// subdivide the sector into four pieces. The north and south poles		// are special cases for the initial subdivision. To ensure that the international		// dateline is never crossed, we propogate the original four constant longitude		// lines (PI=-PI, -PI/2, 0.0, PI/2) up to the north/south poles. Other than these		// two initial special cases, subdivison proceeds by computing the midpoints of		// the four sector edges, computing their intersection in the middle, and then		// forming the four sectors as a result.		// As in the initial cube mapping (see above), we continue to ensure that the edges		// are stored in a CCW order (when viewed from outside the ellipsoid) around the sector.		// the two pole sectors have four constant latitude edge boundaries		int numConstantLatEdges = 0;		for (int i=0 ; i<4 ; i++)			if (boundary[i] instanceof ConstantLatEdge)				numConstantLatEdges++;		if (numConstantLatEdges == 4)			return subdividePolarSector();		return subdivideNonPolarSector();	}	private EdgeBoundedSector[] subdivideNonPolarSector() // sector does NOT contain a pole	{		// working storage:		Edge[][] newEdges = new Edge[4][2];		Edge.EdgeType[] eT = new Edge.EdgeType[4];		boolean newEdgesMustBeGreatEllipses = false;		for (int i=0 ; i<4 ; i++)		{			eT[i] = boundary[i].subdivide(newEdges[i]);			if (eT[i] == Edge.EdgeType.GreatEllipse)				newEdgesMustBeGreatEllipses = true;		}		if (eT[0] != eT[2])			newEdgesMustBeGreatEllipses = true;		if (newEdgesMustBeGreatEllipses)			return subdivideUsingGreatEllipses(newEdges);		return subdivideUsingConstantLatLonEdges(newEdges,eT);	}	private EdgeBoundedSector[] subdividePolarSector()	// all four edges have Constant latitude. The north or south pole is at the center of this	// sector and will become the single point common to all subdivided patches. Each edge	// gets split in half and its endpoints get connected to the pole to form a four-sided	// sector.	{		// working storage:		Edge[] newEdges = new Edge[4];		EdgeBoundedSector[] result = new EdgeBoundedSector[4];		for (int i=0 ; i<4 ; i++)		{			LatLon start = boundary[i].getStartPoint();			LatLon end = boundary[i].getEndPoint();			Angle thePoleLat = Angle.POS90;			if (start.getLatitude().getRadians() < 0.0) thePoleLat = Angle.NEG90;			boundary[i].subdivide(newEdges); // fills positions 0 and 1			newEdges[2] = new ConstantLonEdge(end.getLatitude(),thePoleLat,end.getLongitude());			newEdges[3] = new ConstantLonEdge(thePoleLat,start.getLatitude(),start.getLongitude());			result[i] = EdgeBoundedSector.fromEdges(newEdges);		}		return result;	}	private EdgeBoundedSector[] subdivideUsingConstantLatLonEdges(Edge[][] newEdges, Edge.EdgeType[] eT)	{		// simple case of subdividing one of the Sectors on the lateral sides of the globe		EdgeBoundedSector[] result = new EdgeBoundedSector[4];		// first find central point		LatLon center = this.getCentroid();		Angle centerLat = center.getLatitude(), centerLon = center.getLongitude();		Edge[] oneSet = new Edge[4];		// see diagram for reasoning		int prevI = 3, curI = 0;		for (int ns=0 ; ns<4 ; ns++) // creating 4 new sectors (ns)		{			oneSet[0] = newEdges[prevI][1]; oneSet[1] = newEdges[curI][0];			LatLon start = oneSet[1].getStartPoint();			LatLon end = oneSet[1].getEndPoint();			if (eT[curI] == Edge.EdgeType.ConstantLatitude)			{				oneSet[2] = new ConstantLonEdge(end.getLatitude(),centerLat,centerLon);				oneSet[3] = new ConstantLatEdge(centerLat,centerLon,start.getLongitude());			}			else			{				oneSet[2] = new ConstantLatEdge(centerLat,start.getLongitude(),centerLon);				oneSet[3] = new ConstantLonEdge(centerLat,start.getLatitude(),centerLon);			}			result[ns] = EdgeBoundedSector.fromEdges(oneSet);			prevI = (prevI + 1) % 4; curI++;		}		return result;	}	private EdgeBoundedSector[] subdivideUsingGreatEllipses(Edge[][] newEdges)	{		// Logic is basically the same as in "subdivideUsingConstantLatLonEdges", except		// all edges are Great Ellipses		EdgeBoundedSector[] result = new EdgeBoundedSector[4];		// first find central point		LatLon[] edgeSplitPoints = new LatLon[4];		for (int i=0 ; i<4 ; i++)			// the new point in edge i of parent Sector is newEdges[i][0]'s end			// (or equivalently newEdges[i][1]'s start)			edgeSplitPoints[i] = newEdges[i][0].getEndPoint();		LatLon centerLatLon = GreatEllipseEdge.findCentralPoint(EdgeBoundedSector.theGlobe,edgeSplitPoints);		Edge[] oneSet = new Edge[4];		// see diagram for reasoning		int prevI = 3, curI = 0;		for (int ns=0 ; ns<4 ; ns++) // creating 4 new sectors (ns)		{			oneSet[0] = newEdges[prevI][1]; oneSet[1] = newEdges[curI][0];			oneSet[2] = new GreatEllipseEdge(EdgeBoundedSector.theGlobe,				edgeSplitPoints[curI].getLatitude(),centerLatLon.getLatitude(),				edgeSplitPoints[curI].getLongitude(),centerLatLon.getLongitude());			oneSet[3] = new GreatEllipseEdge(EdgeBoundedSector.theGlobe,				centerLatLon.getLatitude(), edgeSplitPoints[prevI].getLatitude(),				centerLatLon.getLongitude(), edgeSplitPoints[prevI].getLongitude());			result[ns] = EdgeBoundedSector.fromEdges(oneSet);			prevI = (prevI + 1) % 4; curI++;		}		return result;	}	public String toString()	{		String str = "EdgeBoundedSector[" +			super.toString() +			", Sector edges: ";		for (int i=0 ; i<4 ; i++)		{			str += boundary[i].toString();			if (i != 3) str += ", ";		}		return str + "]";	}}

⌨️ 快捷键说明

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