Example usage for org.apache.commons.math3.geometry.partitioning RegionFactory difference

List of usage examples for org.apache.commons.math3.geometry.partitioning RegionFactory difference

Introduction

In this page you can find the example usage for org.apache.commons.math3.geometry.partitioning RegionFactory difference.

Prototype

public Region<S> difference(final Region<S> region1, final Region<S> region2) 

Source Link

Document

Compute the difference of two regions.

Usage

From source file:org.orekit.models.earth.tessellation.EllipsoidTessellator.java

/** Tessellate a zone of interest into tiles.
 * <p>/*from   w w w  .j  a  v  a2s  . c  o m*/
 * The created tiles will completely cover the zone of interest.
 * </p>
 * <p>
 * The distance between a vertex at a tile corner and the vertex at the same corner
 * in the next vertex are computed by subtracting the overlap width (resp. overlap length)
 * from the full width (resp. full length). If for example the full width is specified to
 * be 55 km and the overlap in width is specified to be +5 km, successive tiles would span
 * as follows:
 * </p>
 * <ul>
 *   <li>tile 1 covering from   0 km to  55 km</li>
 *   <li>tile 2 covering from  50 km to 105 km</li>
 *   <li>tile 3 covering from 100 km to 155 km</li>
 *   <li>...</li>
 * </ul>
 * <p>
 * In order to achieve the same 50 km step but using a 5 km gap instead of an overlap, one would
 * need to specify the full width to be 45 km and the overlap to be -5 km. With these settings,
 * successive tiles would span as follows:
 * </p>
 * <ul>
 *   <li>tile 1 covering from   0 km to  45 km</li>
 *   <li>tile 2 covering from  50 km to  95 km</li>
 *   <li>tile 3 covering from 100 km to 155 km</li>
 *   <li>...</li>
 * </ul>
 * @param zone zone of interest to tessellate
 * @param fullWidth full tiles width as a distance on surface, including overlap (in meters)
 * @param fullLength full tiles length as a distance on surface, including overlap (in meters)
 * @param widthOverlap overlap between adjacent tiles (in meters), if negative the tiles
 * will have a gap between each other instead of an overlap
 * @param lengthOverlap overlap between adjacent tiles (in meters), if negative the tiles
 * will have a gap between each other instead of an overlap
 * @param truncateLastWidth if true, the first tiles strip will be started as close as
 * possible to the zone of interest, and the last tiles strip will have its width reduced
 * to also remain close to the zone of interest; if false all tiles strip will have the
 * same {@code fullWidth} and they will be balanced around zone of interest
 * @param truncateLastLength if true, the first tile in each strip will be started as close as
 * possible to the zone of interest, and the last tile in each strip will have its length reduced
 * to also remain close to the zone of interest; if false all tiles in each strip will have the
 * same {@code fullLength} and they will be balanced around zone of interest
 * @return a list of lists of tiles covering the zone of interest,
 * each sub-list corresponding to a part not connected to the other
 * parts (for example for islands)
 * @exception OrekitException if the zone cannot be tessellated
 */
public List<List<Tile>> tessellate(final SphericalPolygonsSet zone, final double fullWidth,
        final double fullLength, final double widthOverlap, final double lengthOverlap,
        final boolean truncateLastWidth, final boolean truncateLastLength) throws OrekitException {

    final double splitWidth = (fullWidth - widthOverlap) / quantization;
    final double splitLength = (fullLength - lengthOverlap) / quantization;
    final Map<Mesh, List<Tile>> map = new IdentityHashMap<Mesh, List<Tile>>();
    final RegionFactory<Sphere2D> factory = new RegionFactory<Sphere2D>();
    SphericalPolygonsSet remaining = (SphericalPolygonsSet) zone.copySelf();
    S2Point inside = getInsidePoint(remaining);

    while (inside != null) {

        // find a mesh covering at least one connected part of the zone
        final List<Mesh.Node> mergingSeeds = new ArrayList<Mesh.Node>();
        Mesh mesh = new Mesh(ellipsoid, zone, aiming, splitLength, splitWidth, inside);
        mergingSeeds.add(mesh.getNode(0, 0));
        List<Tile> tiles = null;
        while (!mergingSeeds.isEmpty()) {

            // expand the mesh around the seed
            neighborExpandMesh(mesh, mergingSeeds, zone);

            // extract the tiles from the mesh
            // this further expands the mesh so tiles dimensions are multiples of quantization,
            // hence it must be performed here before checking meshes independence
            tiles = extractTiles(mesh, zone, lengthOverlap, widthOverlap, truncateLastWidth,
                    truncateLastLength);

            // check the mesh is independent from existing meshes
            mergingSeeds.clear();
            for (final Map.Entry<Mesh, List<Tile>> entry : map.entrySet()) {
                if (!factory.intersection(mesh.getCoverage(), entry.getKey().getCoverage()).isEmpty()) {
                    // the meshes are not independent, they intersect each other!

                    // merge the two meshes together
                    mesh = mergeMeshes(mesh, entry.getKey(), mergingSeeds);
                    map.remove(entry.getKey());
                    break;

                }
            }

        }

        // remove the part of the zone covered by the mesh
        remaining = (SphericalPolygonsSet) factory.difference(remaining, mesh.getCoverage());
        inside = getInsidePoint(remaining);

        map.put(mesh, tiles);

    }

    // concatenate the lists from the independent meshes
    final List<List<Tile>> tilesLists = new ArrayList<List<Tile>>(map.size());
    for (final Map.Entry<Mesh, List<Tile>> entry : map.entrySet()) {
        tilesLists.add(entry.getValue());
    }

    return tilesLists;

}

From source file:org.orekit.models.earth.tessellation.EllipsoidTessellator.java

/** Sample a zone of interest into a grid sample of {@link GeodeticPoint geodetic points}.
 * <p>/*from w  w  w . j  ava 2s. com*/
 * The created points will be entirely within the zone of interest.
 * </p>
 * @param zone zone of interest to sample
 * @param width grid sample cells width as a distance on surface (in meters)
 * @param length grid sample cells length as a distance on surface (in meters)
 * @return a list of lists of points sampling the zone of interest,
 * each sub-list corresponding to a part not connected to the other
 * parts (for example for islands)
 * @exception OrekitException if the zone cannot be sampled
 */
public List<List<GeodeticPoint>> sample(final SphericalPolygonsSet zone, final double width,
        final double length) throws OrekitException {

    final double splitWidth = width / quantization;
    final double splitLength = length / quantization;
    final Map<Mesh, List<GeodeticPoint>> map = new IdentityHashMap<Mesh, List<GeodeticPoint>>();
    final RegionFactory<Sphere2D> factory = new RegionFactory<Sphere2D>();
    SphericalPolygonsSet remaining = (SphericalPolygonsSet) zone.copySelf();
    S2Point inside = getInsidePoint(remaining);

    while (inside != null) {

        // find a mesh covering at least one connected part of the zone
        final List<Mesh.Node> mergingSeeds = new ArrayList<Mesh.Node>();
        Mesh mesh = new Mesh(ellipsoid, zone, aiming, splitLength, splitWidth, inside);
        mergingSeeds.add(mesh.getNode(0, 0));
        List<GeodeticPoint> sample = null;
        while (!mergingSeeds.isEmpty()) {

            // expand the mesh around the seed
            neighborExpandMesh(mesh, mergingSeeds, zone);

            // extract the sample from the mesh
            // this further expands the mesh so sample cells dimensions are multiples of quantization,
            // hence it must be performed here before checking meshes independence
            sample = extractSample(mesh, zone);

            // check the mesh is independent from existing meshes
            mergingSeeds.clear();
            for (final Map.Entry<Mesh, List<GeodeticPoint>> entry : map.entrySet()) {
                if (!factory.intersection(mesh.getCoverage(), entry.getKey().getCoverage()).isEmpty()) {
                    // the meshes are not independent, they intersect each other!

                    // merge the two meshes together
                    mesh = mergeMeshes(mesh, entry.getKey(), mergingSeeds);
                    map.remove(entry.getKey());
                    break;

                }
            }

        }

        // remove the part of the zone covered by the mesh
        remaining = (SphericalPolygonsSet) factory.difference(remaining, mesh.getCoverage());
        inside = getInsidePoint(remaining);

        map.put(mesh, sample);

    }

    // concatenate the lists from the independent meshes
    final List<List<GeodeticPoint>> sampleLists = new ArrayList<List<GeodeticPoint>>(map.size());
    for (final Map.Entry<Mesh, List<GeodeticPoint>> entry : map.entrySet()) {
        sampleLists.add(entry.getValue());
    }

    return sampleLists;

}