//
// VisADGeometryArray.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad;
import java.util.*;
/**
VisADGeometryArray stands in for j3d.GeometryArray
and is Serializable.
*/
public abstract class VisADGeometryArray extends VisADSceneGraphObject
implements Cloneable {
public int vertexCount;
public int vertexFormat;
public float[] coordinates;
public float[] normals;
public byte[] colors;
public float[] texCoords;
// stuff for longitude
boolean any_longitude_rotate = false;
int longitude_axis = -1;
ScalarMap longitude_map = null;
CoordinateSystem longitude_cs = null;
float[][] longitude_coords = null;
public VisADGeometryArray() {
vertexCount = 0;
vertexFormat = 0;
coordinates = null;
normals = null;
colors = null;
texCoords = null;
}
/** eliminate any vectors or triangles crossing seams of
map projections, defined by display-side CoordinateSystems;
this default implementation does nothing */
public VisADGeometryArray adjustSeam(DataRenderer renderer)
throws VisADException {
CoordinateSystem coord_sys = renderer.getDisplayCoordinateSystem();
// WLH 13 March 2000
// if (coord_sys == null) return this;
if (coord_sys == null || coord_sys instanceof SphericalCoordinateSystem) {
return this;
}
return this;
}
/** like adjustLongitude, but rather than splitting vectors or
triangles, keep the VisADGeometryArray intact but possibly
move it in longitude (try to keep its centroid on the "main"
side of the seam) */
public VisADGeometryArray adjustLongitudeBulk(DataRenderer renderer)
throws VisADException {
float[] lons = getLongitudes(renderer, true); // bulk = true
return this;
}
/** split any vectors or triangles crossing crossing longitude
seams when Longitude is mapped to a Cartesian display axis;
default implementation: rotate if necessary, then return points */
public VisADGeometryArray adjustLongitude(DataRenderer renderer)
throws VisADException {
float[] lons = getLongitudes(renderer);
if (any_longitude_rotate) {
// some coordinates changed, so return VisADPointArray
VisADPointArray array = new VisADPointArray();
array.vertexCount = vertexCount;
array.coordinates = coordinates;
array.colors = colors;
return array;
}
else {
return this;
}
}
static float rotateOneLongitude(float lon, float base) {
if (lon == lon) {
float x = (lon - base) % 360.0f;
return (x + ((x < 0.0f) ? (360.0f + base) : base));
}
else {
return lon;
}
}
void rotateLongitudes(float[] lons, float base, boolean bulk)
throws VisADException {
boolean any = false;
// so rotate longitudes to base
if (bulk) {
float mean_lon = 0.0f;
int n = 0;
for (int i=0; i lon_max) lon_max = lons[i];
}
}
// System.out.println("lon_min = " + lon_min + " lon_max = " + lon_max);
if (lon_min == Float.MAX_VALUE) {
longitude_coords = null;
return lons;
}
boolean any_rotate = false;
if (map_min == map_min && map_max == map_max) {
float map_delta = 0.1f * (map_max - map_min);
// System.out.println("map_delta = " + map_delta);
if ( ((map_min + map_delta) < lon_min &&
(map_max + map_delta) < lon_max) ||
(lon_min < (map_min - map_delta) &&
lon_max < (map_max - map_delta)) ) {
float new_lon_min = rotateOneLongitude(lon_min, map_min);
float new_lon_max = rotateOneLongitude(lon_max, map_min);
float dist_min =
(lon_min < map_min) ? (map_min - lon_min) :
(map_max < lon_min) ? (lon_min - map_max) : 0.0f;
float new_dist_min =
(new_lon_min < map_min) ? (map_min - new_lon_min) :
(map_max < new_lon_min) ? (new_lon_min - map_max) : 0.0f;
float dist_max =
(lon_max < map_min) ? (map_min - lon_max) :
(map_max < lon_max) ? (lon_max - map_max) : 0.0f;
float new_dist_max =
(new_lon_max < map_min) ? (map_min - new_lon_max) :
(map_max < new_lon_max) ? (new_lon_max - map_max) : 0.0f;
if ((new_dist_min + new_dist_max) < (dist_min + dist_max)) {
// actual longitudes are shifted significantly from map,
// so rotate longitudes to base at map_min
// System.out.println("rotateLongitudes to map_min " + map_min);
any_rotate = true;
rotateLongitudes(lons, map_min, bulk);
}
}
}
if (!any_rotate && (lon_min + 360.0f) < lon_max) {
// System.out.println("rotateLongitudes to lon_min " + lon_min);
rotateLongitudes(lons, lon_min, bulk);
}
/*
for (int i=0; i lon_max) lon_max = lons[i];
}
}
// WLH 30 Dec 99
if ((lon_max - lon_min) < 1.0f) {
lon_max += 0.5f;
lon_min -= 0.5f;
}
if (lon_min <= lon_max) {
/* WLH 30 Dec 99
float delta = 1.0f; // allow a little slop in Longitudes
*/
float delta = (lon_max - lon_min) / 10.0f; // allow a little slop in Longitudes
if (delta > 1.0f) delta = 1.0f;
float x = (lon_min + delta) % 180.0f;
if (x < 0.0f) x += 180.0f;
float y = (lon_min + delta) - x;
if ((lon_max - delta) < y + 360.0f) {
lon_range[0] = y;
lon_range[1] = y + 360.0f;
}
else {
lon_range[0] = lon_min;
lon_range[1] = lon_min + 360.0f;
}
if (longitude_map != null && longitude_cs == null) {
float[] xcoords = longitude_map.scaleValues(lon_range);
coords[0] = xcoords[0];
coords[1] = xcoords[1];
axis[0] = longitude_axis;
}
else {
coords[0] = Float.NaN;
coords[1] = Float.NaN;
axis[0] = -1;
}
}
return lon_range;
}
public VisADGeometryArray removeMissing() {
VisADPointArray array = new VisADPointArray();
float[] coords = new float[coordinates.length];
int color_length = 3;
byte[] cols = null;
if (colors != null) {
cols = new byte[colors.length];
if (colors.length != coordinates.length) color_length = 4;
}
int k = 0;
int m = 0;
int j = 0;
boolean any_missing = false;
for (int i=0; i
Ads help maintain this website.