Class OrthographicProjection

java.lang.Object
edu.cnu.mdi.mapping.projection.OrthographicProjection
All Implemented Interfaces:
IMapProjection

public class OrthographicProjection extends Object implements IMapProjection
Orthographic azimuthal projection (spherical Earth, R = 1).

Forward equations

   x = R · cos φ · sin(λ - λ₀)
   y = R · (cos φ₀ · sin φ − sin φ₀ · cos φ · cos(λ - λ₀))
 

A point is only projected when the dot product of the surface normal with the view direction is positive (z > 0). Points on the far hemisphere yield (NaN, NaN) from latLonToXY(java.awt.geom.Point2D.Double, java.awt.geom.Point2D.Double) and false from isPointVisible(java.awt.geom.Point2D.Double).

Inverse equations

   ρ = √(x² + y²),   c = arcsin(ρ / R)
   φ = arcsin(cos c · sin φ₀ + (y · sin c · cos φ₀) / ρ)
   λ = λ₀ + atan2(x · sin c, ρ · cos φ₀ · cos c − y · sin φ₀ · sin c)
 

Domain

The unit disk: x² + y² ≤ 1. Only the visible hemisphere is rendered.

No seam

Unlike cylindrical projections the orthographic projection has no antimeridian seam; the default IMapProjection.crossesSeam(double, double) returning false is correct for this class.

  • Constructor Details

    • OrthographicProjection

      public OrthographicProjection(double centerLon, double centerLat)
      Creates an orthographic projection centered at the given geographic point on a unit sphere. The MapTheme must be supplied separately via setTheme(MapTheme) before any drawing methods are called.

      Prefer the three-argument constructor or ProjectionFactory to ensure the theme is set atomically with the center.

      Parameters:
      centerLon - central longitude λ₀ in radians
      centerLat - central latitude φ₀ in radians
    • OrthographicProjection

      public OrthographicProjection(double centerLon, double centerLat, MapTheme theme)
      Convenience constructor that sets both the center and the theme in a single step, eliminating the NullPointerException risk of calling drawMapOutline(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) before the theme is set.
      Parameters:
      centerLon - central longitude λ₀ in radians
      centerLat - central latitude φ₀ in radians
      theme - map theme; must not be null
  • Method Details

    • setCenter

      public void setCenter(double centerLon, double centerLat)
      Changes the center of the projection. The next repaint will show the globe as seen from above the new center point.
      Parameters:
      centerLon - central longitude λ₀ in radians
      centerLat - central latitude φ₀ in radians
    • latLonToXY

      public void latLonToXY(Point2D.Double latLon, Point2D.Double xy)
      Forward projection: geographic (λ, φ) → projection-space (x, y).

      Implementations should clamp the latitude to their valid range before computing to avoid NaN or Infinity results at the poles.

      For hemispherical projections (e.g. orthographic) a point on the far side of the globe should set xy to (Double.NaN, Double.NaN) rather than throwing, because callers test isPointVisible separately.

      If the point is on the far hemisphere (dot product z ≤ 0) the output is set to (NaN, NaN) and the caller should treat it as not visible. Latitude is clamped to [MIN_LAT, MAX_LAT] for numerical stability near the poles.

      Specified by:
      latLonToXY in interface IMapProjection
      Parameters:
      latLon - input geographic point in radians (x=λ, y=φ); must not be null
      xy - output projection-space point; must not be null
    • latLonFromXY

      public void latLonFromXY(Point2D.Double latLon, Point2D.Double xy)
      Inverse projection: projection-space (x, y) → geographic (λ, φ).

      If the input point lies outside the valid projection domain, implementations should set latLon to (Double.NaN, Double.NaN) rather than throwing.

      Specified by:
      latLonFromXY in interface IMapProjection
      Parameters:
      latLon - output geographic point in radians (x=λ, y=φ); must not be null
      xy - input projection-space point; must not be null
    • isPointVisible

      public boolean isPointVisible(Point2D.Double latLon)
      Tests whether a geographic location is visible in this projection.

      Global projections (Mercator, Mollweide, Lambert) generally return true for any point within their latitude range. Hemispherical projections (Orthographic) return true only for points on the visible hemisphere.

      A point is visible when the dot product of the surface normal with the view direction is positive (z > 0), i.e. the point lies on the near hemisphere.

      Specified by:
      isPointVisible in interface IMapProjection
      Parameters:
      latLon - geographic point in radians (x=λ, y=φ)
      Returns:
      true if the point is visible; false otherwise
    • isPointOnMap

      public boolean isPointOnMap(Point2D.Double xy)
      Tests whether a projection-space point lies within the valid domain of this projection.

      This is used after IMapProjection.latLonToXY(java.awt.geom.Point2D.Double, java.awt.geom.Point2D.Double) to guard against rendering points that fall slightly outside the projection boundary due to floating-point rounding.

      A point is on the map when it lies within or on the unit disk (x² + y² ≤ R²).

      Specified by:
      isPointOnMap in interface IMapProjection
      Parameters:
      xy - projection-space point
      Returns:
      true if the point is on (or inside) the map; false otherwise
    • drawMapOutline

      public void drawMapOutline(Graphics2D g2, IContainer container)
      Draws the outer boundary of the projection domain.

      Typical implementations build a Path2D in world coordinates, transform each vertex to screen space via container.worldToLocal, then stroke the path using colors and widths from the current MapTheme.

      Draws the unit-circle boundary of the projection disk using the theme's outline color and stroke width.

      Specified by:
      drawMapOutline in interface IMapProjection
      Parameters:
      g2 - graphics context to draw into
      container - container providing the world-to-local transform
    • drawLatitudeLine

      public void drawLatitudeLine(Graphics2D g2, IContainer container, double latitude)
      Draws a line of constant latitude (a parallel) at the given latitude.

      Implementations should approximate the curve by sampling at a sufficient number of longitude values, projecting each sample, and connecting the resulting screen points with a polyline. The line color must be MapTheme.getGraticuleColor() so that theme switching takes full effect.

      Samples NUM_SEGMENTS evenly-spaced longitudes at the given latitude. Invisible points (on the far hemisphere) are skipped so the path is not drawn across the globe's limb. Uses MapTheme.getGraticuleColor() rather than a hardcoded color.

      Specified by:
      drawLatitudeLine in interface IMapProjection
      Parameters:
      g2 - graphics context
      container - container providing the world-to-local transform
      latitude - latitude φ in radians, typically in [-π/2, π/2]
    • drawLongitudeLine

      public void drawLongitudeLine(Graphics2D g2, IContainer container, double longitude)
      Draws a line of constant longitude (a meridian) at the given longitude.

      Implementations should approximate the curve by sampling at a sufficient number of latitude values, projecting each sample, and connecting the resulting screen points with a polyline. The line color must be MapTheme.getGraticuleColor() so that theme switching takes full effect.

      Samples NUM_SEGMENTS evenly-spaced latitudes across the visible latitude band for the current center latitude. Invisible points are skipped. Uses MapTheme.getGraticuleColor() for the line color.

      Specified by:
      drawLongitudeLine in interface IMapProjection
      Parameters:
      g2 - graphics context
      container - container providing the world-to-local transform
      longitude - longitude λ in radians, typically in [-π, π]
    • getProjection

      public EProjection getProjection()
      Returns the EProjection enum constant that identifies this implementation, if this projection is one of MDI's built-in projections.

      Application-supplied projections are allowed to return null. This permits an application to provide a projection without modifying EProjection, ProjectionFactory, or other MDI built-in projection registries.

      Specified by:
      getProjection in interface IMapProjection
      Returns:
      the built-in projection type, or null for a custom application-supplied projection
    • getXYBounds

      public Rectangle2D.Double getXYBounds()
      Returns the bounding rectangle of the projection-space domain in world coordinates.

      This rectangle is used by IContainer implementations to build the initial world-to-screen transform. The returned rectangle should tightly enclose the entire valid projected domain (e.g. [-π, π] × [MIN_Y, MAX_Y] for Mercator).

      Returns the bounding square of the unit disk: [-R, -R] to [R, R], i.e. [-1, -1] to [1, 1].

      Specified by:
      getXYBounds in interface IMapProjection
      Returns:
      bounding rectangle in projection space; never null
    • getTheme

      public MapTheme getTheme()
      Returns the MapTheme currently used by this projection for drawing outlines and graticule lines.

      Implementations must never return null once the theme has been set.

      Specified by:
      getTheme in interface IMapProjection
      Returns:
      the active map theme
    • setTheme

      public void setTheme(MapTheme theme)
      Sets the MapTheme used by this projection for all subsequent drawing operations.
      Specified by:
      setTheme in interface IMapProjection
      Parameters:
      theme - the new theme; must not be null
      Throws:
      IllegalArgumentException - if theme is null
    • createClipShape

      public Shape createClipShape(IContainer container)
      Creates a clip Shape in device coordinates that matches the projection's valid domain.

      This shape is used to:

      Returns a circular path in device coordinates matching the unit-disk boundary, used as a clip region for ocean fill and land rendering.

      Specified by:
      createClipShape in interface IMapProjection
      Parameters:
      container - container providing the world-to-local transform
      Returns:
      a device-space Shape, or null if no clip is defined for this projection