Class OrthographicProjection
- All Implemented Interfaces:
IMapProjection
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 Summary
ConstructorsConstructorDescriptionOrthographicProjection(double centerLon, double centerLat) Creates an orthographic projection centered at the given geographic point on a unit sphere.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 callingdrawMapOutline(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer)before the theme is set. -
Method Summary
Modifier and TypeMethodDescriptioncreateClipShape(IContainer container) Creates a clipShapein device coordinates that matches the projection's valid domain.voiddrawLatitudeLine(Graphics2D g2, IContainer container, double latitude) Draws a line of constant latitude (a parallel) at the given latitude.voiddrawLongitudeLine(Graphics2D g2, IContainer container, double longitude) Draws a line of constant longitude (a meridian) at the given longitude.voiddrawMapOutline(Graphics2D g2, IContainer container) Draws the outer boundary of the projection domain.Returns theEProjectionenum constant that identifies this implementation, if this projection is one of MDI's built-in projections.getTheme()Returns theMapThemecurrently used by this projection for drawing outlines and graticule lines.Returns the bounding rectangle of the projection-space domain in world coordinates.booleanTests whether a projection-space point lies within the valid domain of this projection.booleanisPointVisible(Point2D.Double latLon) Tests whether a geographic location is visible in this projection.voidlatLonFromXY(Point2D.Double latLon, Point2D.Double xy) Inverse projection: projection-space (x, y) → geographic (λ, φ).voidlatLonToXY(Point2D.Double latLon, Point2D.Double xy) Forward projection: geographic (λ, φ) → projection-space (x, y).voidsetCenter(double centerLon, double centerLat) Changes the center of the projection.voidSets theMapThemeused by this projection for all subsequent drawing operations.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface edu.cnu.mdi.mapping.projection.IMapProjection
crossesSeam, fillOcean, isLongitudePeriodic, name, recenterOn, supportsRecenter, wrapLatitude, wrapLongitude
-
Constructor Details
-
OrthographicProjection
public OrthographicProjection(double centerLon, double centerLat) Creates an orthographic projection centered at the given geographic point on a unit sphere. TheMapThememust be supplied separately viasetTheme(MapTheme)before any drawing methods are called.Prefer the three-argument constructor or
ProjectionFactoryto ensure the theme is set atomically with the center.- Parameters:
centerLon- central longitude λ₀ in radianscenterLat- central latitude φ₀ in radians
-
OrthographicProjection
Convenience constructor that sets both the center and the theme in a single step, eliminating the NullPointerException risk of callingdrawMapOutline(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer)before the theme is set.- Parameters:
centerLon- central longitude λ₀ in radianscenterLat- central latitude φ₀ in radianstheme- map theme; must not benull
-
-
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 radianscenterLat- central latitude φ₀ in radians
-
latLonToXY
Forward projection: geographic (λ, φ) → projection-space (x, y).Implementations should clamp the latitude to their valid range before computing to avoid
NaNorInfinityresults at the poles.For hemispherical projections (e.g. orthographic) a point on the far side of the globe should set
xyto(Double.NaN, Double.NaN)rather than throwing, because callers testisPointVisibleseparately.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:
latLonToXYin interfaceIMapProjection- Parameters:
latLon- input geographic point in radians (x=λ, y=φ); must not benullxy- output projection-space point; must not benull
-
latLonFromXY
Inverse projection: projection-space (x, y) → geographic (λ, φ).If the input point lies outside the valid projection domain, implementations should set
latLonto(Double.NaN, Double.NaN)rather than throwing.- Specified by:
latLonFromXYin interfaceIMapProjection- Parameters:
latLon- output geographic point in radians (x=λ, y=φ); must not benullxy- input projection-space point; must not benull
-
isPointVisible
Tests whether a geographic location is visible in this projection.Global projections (Mercator, Mollweide, Lambert) generally return
truefor any point within their latitude range. Hemispherical projections (Orthographic) returntrueonly 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:
isPointVisiblein interfaceIMapProjection- Parameters:
latLon- geographic point in radians (x=λ, y=φ)- Returns:
trueif the point is visible;falseotherwise
-
isPointOnMap
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:
isPointOnMapin interfaceIMapProjection- Parameters:
xy- projection-space point- Returns:
trueif the point is on (or inside) the map;falseotherwise
-
drawMapOutline
Draws the outer boundary of the projection domain.Typical implementations build a
Path2Din world coordinates, transform each vertex to screen space viacontainer.worldToLocal, then stroke the path using colors and widths from the currentMapTheme.Draws the unit-circle boundary of the projection disk using the theme's outline color and stroke width.
- Specified by:
drawMapOutlinein interfaceIMapProjection- Parameters:
g2- graphics context to draw intocontainer- container providing the world-to-local transform
-
drawLatitudeLine
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_SEGMENTSevenly-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. UsesMapTheme.getGraticuleColor()rather than a hardcoded color.- Specified by:
drawLatitudeLinein interfaceIMapProjection- Parameters:
g2- graphics contextcontainer- container providing the world-to-local transformlatitude- latitude φ in radians, typically in [-π/2, π/2]
-
drawLongitudeLine
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_SEGMENTSevenly-spaced latitudes across the visible latitude band for the current center latitude. Invisible points are skipped. UsesMapTheme.getGraticuleColor()for the line color.- Specified by:
drawLongitudeLinein interfaceIMapProjection- Parameters:
g2- graphics contextcontainer- container providing the world-to-local transformlongitude- longitude λ in radians, typically in [-π, π]
-
getProjection
Returns theEProjectionenum 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 modifyingEProjection,ProjectionFactory, or other MDI built-in projection registries.- Specified by:
getProjectionin interfaceIMapProjection- Returns:
- the built-in projection type, or
nullfor a custom application-supplied projection
-
getXYBounds
Returns the bounding rectangle of the projection-space domain in world coordinates.This rectangle is used by
IContainerimplementations 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:
getXYBoundsin interfaceIMapProjection- Returns:
- bounding rectangle in projection space; never
null
-
getTheme
Returns theMapThemecurrently used by this projection for drawing outlines and graticule lines.Implementations must never return
nullonce the theme has been set.- Specified by:
getThemein interfaceIMapProjection- Returns:
- the active map theme
-
setTheme
Sets theMapThemeused by this projection for all subsequent drawing operations.- Specified by:
setThemein interfaceIMapProjection- Parameters:
theme- the new theme; must not benull- Throws:
IllegalArgumentException- ifthemeisnull
-
createClipShape
Creates a clipShapein device coordinates that matches the projection's valid domain.This shape is used to:
- Clip land/ocean rendering to the map region.
- Fill the ocean background via
IMapProjection.fillOcean(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer).
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:
createClipShapein interfaceIMapProjection- Parameters:
container- container providing the world-to-local transform- Returns:
- a device-space
Shape, ornullif no clip is defined for this projection
-