/*
* MollweideImageProjection.java 1.0 98/06/03 Carl Burke
*
* Provides a mollweide projection of data on a sphere.
*
* Copyright (c) 1998 Carl Burke.
*
* Derived from code in planet.c Copyright 1998 Torben AE. Mogensen
*/
public class MollweideImageProjection extends ImageProjection
{
static private final double[] moll_table =
{0.0, 0.0685055811, 0.1368109534, 0.2047150027,
0.2720147303, 0.3385041213, 0.4039727534,
0.4682040106, 0.5309726991, 0.5920417499,
0.6511575166, 0.7080428038, 0.7623860881,
0.8138239166, 0.8619100185, 0.9060553621,
0.9453925506, 0.9783738403, 1.0};
public MollweideImageProjection(int w, int h, SolidNoiseGenerator sng)
{
super(w, h, sng);
}
public void renderTerrain()
{
double x,y,y1,zz,scale1,cos2,theta1,theta2;
int i,j,i1=0,k;
for (j = 0; j < Height; j++) {
y1 = 2*(2.0*j-Height)/Width/scale;
if (Math.abs(y1)>=1.0) for (i = 0; i < Width ; i++) pixels[j*Width+i] = SNG.background();
else {
zz = Math.sqrt(1.0-y1*y1);
y = 2.0/Math.PI*(y1*zz+Math.asin(y1));
cos2 = Math.sqrt(1.0-y*y);
if (cos2>0.0) {
SNG.setScaling((scale*Width/Height/cos2/Math.PI), Width, Height);
for (i = 0; i < Width ; i++) {
theta1 = Math.PI/zz*(2.0*i-Width)/Width/scale;
if (Math.abs(theta1)>Math.PI) pixels[j*Width+i] = SNG.background();
else {
theta1 += longi-0.5*Math.PI;
pixels[j*Width+i] = SNG.color(Math.cos(theta1)*cos2,y,-Math.sin(theta1)*cos2);
}
}
}
}
}
}
public void renderLatitudes()
{
double x,y,theta1,theta2;
int i,j,k;
for (theta1 = 0.0; theta1>-90.0; theta1-=hgrid);
for (theta1 = theta1; theta1<90.0; theta1+=hgrid)
{
theta2 = Math.abs(theta1);
x = Math.floor(theta2/5.0); y = theta2/5.0-x;
try {
y = (1.0-y)*moll_table[(int)x]+y*moll_table[(int)x+1];
} catch (ArrayIndexOutOfBoundsException b) {
y = 1.0;
}
if (theta1<0.0) y = -y;
j = Height/2+(int)(0.25*y*Width*scale);
if (j>=0 && j< Height)
{
for (i = max(0,Width/2-(int)(0.5*Width*scale*Math.sqrt(1.0-y*y)));
i < min(Width,Width/2+(int)(0.5*Width*scale*Math.sqrt(1.0-y*y)));
i++)
pixels[j*Width+i] = SNG.background();
}
}
}
public void renderLongitudes()
{
double x,y,y1,theta1;
int i,i1=0,j,k;
for (theta1 = 0.0; theta1>-360.0; theta1-=vgrid);
for (theta1 = theta1; theta1<360.0; theta1+=vgrid)
{
if (DEG2RAD*theta1-longi+0.5*Math.PI>-Math.PI &&
DEG2RAD*theta1-longi+0.5*Math.PI<=Math.PI)
{
x = 0.5*(DEG2RAD*theta1-longi+0.5*Math.PI)*Width*scale/Math.PI;
j = max(0,Height/2-(int)(0.25*Width*scale));
y = 2*(2.0*j-Height)/Width/scale;
i = (int)(Width/2+x*Math.sqrt(1.0-y*y));
for (; j <= min(Height,Height/2+(int)(0.25*Width*scale)); j++)
{
y1 = 2*(2.0*j-Height)/Width/scale;
if (Math.abs(y1)<=1.0)
{
i1 = (int)(Width/2+x*Math.sqrt(1.0-y1*y1));
if (i1>0 && i1<=Width) pixels[j*Width+i1] = SNG.background();
}
if (Math.abs(y)<=1.0)
{
if (i0 && k<=Width) pixels[j*Width+k] = SNG.background();
}
else if (i>i1)
{
for (k=i-1; k>i1; k--)
if (k>0 && k<=Width) pixels[j*Width+k] = SNG.background();
}
}
y = y1;
i = i1;
}
}
}
}
}