CircularFieldOfView.java

  1. /* Copyright 2002-2025 CS GROUP
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.geometry.fov;

  18. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  19. import org.hipparchus.util.FastMath;
  20. import org.hipparchus.util.SinCos;
  21. import org.orekit.propagation.events.VisibilityTrigger;

  22. /** Class representing a spacecraft sensor Field Of View with circular shape.
  23.  * <p>The field of view is defined by an axis and an half-aperture angle.</p>
  24.  * @author Luc Maisonobe
  25.  * @since 10.1
  26.  */
  27. public class CircularFieldOfView extends SmoothFieldOfView {

  28.     /** FOV half aperture angle. */
  29.     private final double halfAperture;

  30.     /** Scaled X axis defining FoV boundary. */
  31.     private final Vector3D scaledX;

  32.     /** Scaled Y axis defining FoV boundary. */
  33.     private final Vector3D scaledY;

  34.     /** Scaled Z axis defining FoV boundary. */
  35.     private final Vector3D scaledZ;

  36.     /** Build a new instance.
  37.      * @param center direction of the FOV center, in spacecraft frame
  38.      * @param halfAperture FOV half aperture angle
  39.      * @param margin angular margin to apply to the zone (if positive,
  40.      * the Field Of View will consider points slightly outside of the
  41.      * zone are still visible)
  42.      */
  43.     public CircularFieldOfView(final Vector3D center, final double halfAperture,
  44.                                final double margin) {

  45.         super(center, center.orthogonal(), margin);
  46.         this.halfAperture = halfAperture;

  47.         // precompute utility vectors for walking around the FoV
  48.         final SinCos sc = FastMath.sinCos(halfAperture);
  49.         scaledX   = new Vector3D(sc.sin(), getX());
  50.         scaledY   = new Vector3D(sc.sin(), getY());
  51.         scaledZ   = new Vector3D(sc.cos(), getZ());

  52.     }

  53.     /** get the FOV half aperture angle.
  54.      * @return FOV half aperture angle
  55.      */
  56.     public double getHalfAperture() {
  57.         return halfAperture;
  58.     }

  59.     /** {@inheritDoc} */
  60.     @Override
  61.     public double offsetFromBoundary(final Vector3D lineOfSight, final double angularRadius,
  62.                                      final VisibilityTrigger trigger) {
  63.         return Vector3D.angle(getCenter(), lineOfSight) - halfAperture +
  64.                trigger.radiusCorrection(angularRadius) - getMargin();
  65.     }

  66.     /** {@inheritDoc} */
  67.     @Override
  68.     public Vector3D projectToBoundary(final Vector3D lineOfSight) {
  69.         return directionAt(FastMath.atan2(Vector3D.dotProduct(lineOfSight, getY()),
  70.                                           Vector3D.dotProduct(lineOfSight, getX())));
  71.     }

  72.     /** {@inheritDoc} */
  73.     @Override
  74.     protected Vector3D directionAt(final double angle) {
  75.         final SinCos sc = FastMath.sinCos(angle);
  76.         return new Vector3D(sc.cos(), scaledX, sc.sin(), scaledY, 1.0, scaledZ);
  77.     }

  78. }