Tile.java
- /* Copyright 2002-2024 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.models.earth.tessellation;
- import java.io.Serializable;
- import org.hipparchus.geometry.euclidean.threed.Vector3D;
- import org.hipparchus.util.FastMath;
- import org.orekit.bodies.GeodeticPoint;
- /** Simple data structure for a quadrilateral tile shape on a body surface.
- * <p>
- * This class is devoted to simple usage only. It assumes the edges
- * are strictly between 0 and π radians and that the angles between
- * edges are also strictly between 0 and π radians.
- * </p>
- * @see AlongTrackAiming
- * @see ConstantAzimuthAiming
- * @author Luc Maisonobe
- */
- public class Tile implements Serializable {
- /** Serializable UID. */
- private static final long serialVersionUID = 20150313L;
- /** First vertex. */
- private final GeodeticPoint v0;
- /** Second vertex. */
- private final GeodeticPoint v1;
- /** Third vertex. */
- private final GeodeticPoint v2;
- /** Fourth vertex. */
- private final GeodeticPoint v3;
- /** Create a tile.
- * <p>
- * It is caller responsibility o ensure the vertices define a
- * simple non-degenerated tile (i.e. edges are strictly between
- * 0 than π radians and angles between edges are also strictly
- * between 0 and π radians). No checks are performed here.
- * </p>
- * @param v0 first vertex
- * @param v1 second vertex
- * @param v2 third vertex
- * @param v3 fourth vertex
- */
- public Tile(final GeodeticPoint v0, final GeodeticPoint v1,
- final GeodeticPoint v2, final GeodeticPoint v3) {
- this.v0 = v0;
- this.v1 = v1;
- this.v2 = v2;
- this.v3 = v3;
- }
- /** Get the four vertices.
- * @return four vertices
- */
- public GeodeticPoint[] getVertices() {
- return new GeodeticPoint[] {
- v0, v1, v2, v3
- };
- }
- /** Get an interpolated point inside the tile.
- * <p>
- * The interpolated point is based on bilinear interpolations
- * along the body surface assumed to be <em>spherical</em>,
- * and along the vertical axis.
- * </p>
- * <p>
- * The interpolation parameters are chosen such that
- * (u = 0, v = 0) maps to vertex v0, (u = 1, v = 0) maps
- * to vertex v1, (u = 1, v = 1) maps to vertex v2 and
- * (u = 0, v = 1) maps to vertex v3.
- * </p>
- * @param u first interpolation parameter (should be between
- * 0 and 1 to remain inside the tile)
- * @param v second interpolation parameter (should be between
- * 0 and 1 to remain inside the tile)
- * @return interpolated point
- */
- public GeodeticPoint getInterpolatedPoint(final double u, final double v) {
- // bilinear interpolation along a spherical shape
- final Vector3D pu0 = interpolate(v0.getZenith(), v1.getZenith(), u);
- final Vector3D pu1 = interpolate(v3.getZenith(), v2.getZenith(), u);
- final Vector3D puv = interpolate(pu0, pu1, v);
- // bilinear interpolation of altitude
- final double hu0 = v1.getAltitude() * u + v0.getAltitude() * (1 - u);
- final double hu1 = v2.getAltitude() * u + v3.getAltitude() * (1 - u);
- final double huv = hu1 * v + hu0 * (1 - v);
- // create interpolated point
- return new GeodeticPoint(puv.getDelta(), puv.getAlpha(), huv);
- }
- /** Interpolate a vector along a unit sphere.
- * @param p0 first base unit vector
- * @param p1 second base unit vector
- * @param r interpolation parameter (0 for p0, 1 for p1)
- * @return interpolated unit vector
- */
- private Vector3D interpolate(final Vector3D p0, final Vector3D p1, final double r) {
- // find all interpolation angles
- final double theta = Vector3D.angle(p0, p1);
- final double alpha = r * theta;
- final double thetaMAlpha = (1 - r) * theta;
- final double sinTheta = FastMath.sin(theta);
- final double sinAlpha = FastMath.sin(alpha);
- final double sinThetaMAlpha = FastMath.sin(thetaMAlpha);
- // interpolate
- return new Vector3D(sinThetaMAlpha / sinTheta, p0, sinAlpha / sinTheta, p1);
- }
- /** Get the center point.
- * <p>
- * The center points corresponds to {@link
- * #getInterpolatedPoint(double, double) getInterpolatedPoint(0.5, 0.5)}
- * </p>
- * @return center point
- */
- public GeodeticPoint getCenter() {
- return getInterpolatedPoint(0.5, 0.5);
- }
- }