Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include <u.h>
#include <libc.h>
#include "map.h"

#define ORTHRAD 1000
static double viewpt;

static int
Xperspective(struct place *place, double *x, double *y)
{
        double r;
        if(viewpt<=1+FUZZ && fabs(place->nlat.s<=viewpt+.01))
                return(-1);
        r = place->nlat.c*(viewpt - 1.)/(viewpt - place->nlat.s);
        *x = - r*place->wlon.s;
        *y = - r*place->wlon.c;
        if(r>4.)
                return(-1);
        if(fabs(viewpt)>1 && place->nlat.s<1/viewpt ||
           fabs(viewpt)<=1 && place->nlat.s<viewpt)
                        return 0;
        return(1);
}

proj
perspective(double radius)
{
        viewpt = radius;
        if(viewpt >= ORTHRAD)
                return(Xorthographic);
        if(fabs(viewpt-1.)<.0001)
                return(0);
        return(Xperspective);
}

        /* called from various conformal projections,
           but not from stereographic itself */
int
Xstereographic(struct place *place, double *x, double *y)
{
        double v = viewpt;
        int retval;
        viewpt = -1;
        retval = Xperspective(place, x, y);
        viewpt = v;
        return retval;
}

proj
stereographic(void)
{
        viewpt = -1.;
        return(Xperspective);
}

proj
gnomonic(void)
{
        viewpt = 0.;
        return(Xperspective);
}

int
plimb(double *lat, double *lon, double res)
{
        static first = 1;
        if(viewpt >= ORTHRAD)
                return olimb(lat, lon, res);
        if(first) {
                first = 0;
                *lon = -180;
                if(fabs(viewpt) < .01)
                        *lat = 0;
                else if(fabs(viewpt)<=1)
                        *lat = asin(viewpt)/RAD;
                else
                        *lat = asin(1/viewpt)/RAD;
        } else
                *lon += res;
        if(*lon <= 180)
                return 1;
        first = 1;
        return -1;
}