📄 orthographic.java
字号:
// **********************************************************************// // <copyright>// // BBN Technologies// 10 Moulton Street// Cambridge, MA 02138// (617) 873-8000// // Copyright (C) BBNT Solutions LLC. All rights reserved.// // </copyright>// **********************************************************************// // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/proj/Orthographic.java,v $// $RCSfile: Orthographic.java,v $// $Revision: 1.3.2.1 $// $Date: 2004/10/14 18:27:37 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.proj;import java.awt.Point;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.MoreMath;import com.bbn.openmap.util.Debug;/** * Implements the Orthographic projection. */public class Orthographic extends Azimuth { /** * The Orthographic name. */ public final static transient String OrthographicName = "Orthographic"; /** * The Orthographic type of projection. */ public final static transient int OrthographicType = 7; protected int hy, wx; // almost constant projection parameters protected float cosCtrLat; protected float sinCtrLat; public final static transient float epsilon = 0.0001f; protected final static transient float NORTH_BOUNDARY = NORTH_POLE - epsilon; protected final static transient float SOUTH_BOUNDARY = -NORTH_BOUNDARY; /** * Construct an Orthographic projection. * * @param center LatLonPoint center of projection * @param scale float scale of projection * @param width width of screen * @param height height of screen */ public Orthographic(LatLonPoint center, float scale, int width, int height) { super(center, scale, width, height, OrthographicType); setMinScale(1000.0f); } /** * Construct an Orthographic projection. * * @param center LatLonPoint center of projection * @param scale float scale of projection * @param width width of screen * @param height height of screen * @param type subclass's type */ public Orthographic(LatLonPoint center, float scale, int width, int height, int type) { super(center, scale, width, height, type); setMinScale(1000.0f); } // protected void finalize() { // Debug.message("proj", "Orthographic finalized"); // } /** * Return stringified description of this projection. * * @return String * @see Projection#getProjectionID */ public String toString() { return "Orthographic[" + super.toString(); } /** * Called when some fundamental parameters change. * <p> * Each projection will decide how to respond to this change. For * instance, they may need to recalculate "constant" paramters * used in the forward() and inverse() calls. * <p> */ protected void computeParameters() { Debug.message("proj", "Orthographic.computeParameters()"); super.computeParameters(); // do some precomputation of stuff cosCtrLat = (float) Math.cos(ctrLat); sinCtrLat = (float) Math.sin(ctrLat); // compute the offsets hy = height / 2; wx = width / 2; } /** * Sets radian latitude to something sane. This is an abstract * function since some projections don't deal well with extreme * latitudes. * <p> * * @param lat float latitude in radians * @return float latitude (-PI/2 <= y <= PI/2) * @see com.bbn.openmap.LatLonPoint#normalize_latitude(float) * */ public float normalize_latitude(float lat) { if (lat > NORTH_BOUNDARY) { return NORTH_BOUNDARY; } else if (lat < SOUTH_BOUNDARY) { return SOUTH_BOUNDARY; } return lat; } /** * Check if a given lat/lon is within the visible hemisphere. * * @param phi1 latitude * @param lambda0 longitude * @param phi latitude * @param lambda longitude * @return boolean true if within the visible hemisphere, false if * not */ final public static boolean hemisphere_clip(float phi1, float lambda0, float phi, float lambda) { return (GreatCircle.spherical_distance(phi1, lambda0, phi, lambda)/*-epsilon*/<= MoreMath.HALF_PI); } /** * Calculate point along edge of hemisphere (using center point * and current azimuth). * <p> * This is invoked for points that aren't visible in the current * hemisphere. * * @param p Point * @return Point p */ private Point edge_point(Point p, float current_azimuth) { LatLonPoint tmpll = GreatCircle.spherical_between(ctrLat, ctrLon, MoreMath.HALF_PI/*-epsilon*/, current_azimuth); float phi = tmpll.radlat_; float lambda = tmpll.radlon_; float cosPhi = (float) Math.cos(phi); float lambdaMinusCtrLon = (float) (lambda - ctrLon); p.x = (int) (scaled_radius * cosPhi * (float) Math.sin(lambdaMinusCtrLon)) + wx; p.y = hy - (int) (scaled_radius * (cosCtrLat * (float) Math.sin(phi) - sinCtrLat * cosPhi * (float) Math.cos(lambdaMinusCtrLon))); return p; } /** * Checks if a LatLonPoint is plot-able. * <p> * A point is plot-able if it is within the visible hemisphere. * * @param lat float latitude in decimal degrees * @param lon float longitude in decimal degrees * @return boolean */ public boolean isPlotable(float lat, float lon) { lat = normalize_latitude(ProjMath.degToRad(lat)); lon = wrap_longitude(ProjMath.degToRad(lon)); return hemisphere_clip(ctrLat, ctrLon, lat, lon); } /** * Forward project a point. If the point is not within the * viewable hemisphere, return flags in AzimuthVar variable if * specified. * * @param phi float latitude in radians * @param lambda float longitude in radians * @param p Point * @param azVar AzimuthVar or null * @return Point pt */ protected Point _forward(float phi, float lambda, Point p, AzimuthVar azVar) { float cosPhi = (float) Math.cos(phi); float lambdaMinusCtrLon = (float) (lambda - ctrLon); // normalize invalid point to the edge of the sphere if (!hemisphere_clip(ctrLat, ctrLon, phi, lambda)) { float az = GreatCircle.spherical_azimuth(ctrLat, ctrLon, phi, lambda); if (azVar != null) { azVar.invalid_forward = true; // set the invalid flag azVar.current_azimuth = az; // record azimuth of this // point } return edge_point(p, az); } p.x = (int) (scaled_radius * cosPhi * (float) Math.sin(lambdaMinusCtrLon)) + wx; p.y = hy - (int) (scaled_radius * (cosCtrLat * (float) Math.sin(phi) - sinCtrLat * cosPhi * (float) Math.cos(lambdaMinusCtrLon))); return p; } /** * Inverse project x,y coordinates into a LatLonPoint. * * @param x integer x coordinate * @param y integer y coordinate * @param llp LatLonPoint * @return LatLonPoint llp * @see Proj#inverse(Point) */ public LatLonPoint inverse(int x, int y, LatLonPoint llp) { // convert from screen to world coordinates x = x - wx; y = hy - y; // Debug.output("Orthographic.inverse: x,y=" + x + "," + y); // sqrt(pt . pt) float rho = (float) Math.sqrt(x * x + y * y); if (rho == 0f) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -