package com.huayu.gps;
public class Deg {
public static final int SEC = 500;
public static final int MIN = 60 * SEC;
public static final int DEG = 60 * MIN;
public static final int FORMAT_AUTO = -1;
public static final int FORMAT_D = 0;
public static final int FORMAT_DM = 1;
public static final int FORMAT_DMS = 2;
public static final int FORMAT_NMEA = 3;
public static final int FORMAT_FIXED = 4;
public static final int PRECISION_D = 6;
public static final int PRECISION_M = 4;
public static final int PRECISION_S = 2;
// fixed decimal point = 1
public static final int iFIXED = 1000; // Integer.MAX_VALUE;
//public static final long FIXED = Long.MAX_VALUE;
private static int format = FORMAT_D;
protected int deg;
public Deg() { this.deg = 0; }
public Deg( int deg ) { this.deg = limitDeg( deg ); }
public Deg( long deg ) { this.deg = limitDeg( deg ); }
public Deg( Deg deg ) { this.deg = deg.deg; }
public void set( int deg ) { this.deg = limitDeg( deg ); }
public void set( long deg ) { this.deg = limitDeg( deg ); }
public void set( Deg deg ) { this.deg = deg.deg; }
public int get() { return deg; }
public String toString() {
return ""; // TODO
}
public static void setFormat( int f ) { format = f; }
public static int getFormat() { return format; }
public static int min( int a, int b ) {
return ( a < b ) ? a : b;
}
public static int max( int a, int b ) {
return ( a > b ) ? a : b;
}
public static int abs( int x ) {
return ( x < 0 ) ? -x : x;
}
public static int limitDeg( int deg ) {
while( deg >= 360 * DEG ) deg -= 360 * DEG;
while( deg < 0 ) deg += 360 * DEG;
return deg;
}
public static int limitDeg( long deg ) {
while( deg >= 360 * DEG ) deg -= 360 * DEG;
while( deg < 0 ) deg += 360 * DEG;
return (int) deg;
}
public static int limitDeg( double deg ) {
while( deg >= 360 * DEG ) deg -= 360 * DEG;
while( deg < 0 ) deg += 360 * DEG;
return (int) deg;
}
public static String degToStr( int value, int f, int n, int precision, String signPlus, String signMinus ) {
StringBuffer tmpsb = new StringBuffer();
if( ( ( f < 0 ) ? format : f ) != FORMAT_FIXED ) {
tmpsb.append( ( value < 0 ) ? signMinus : signPlus );
value = ( value < 0 ) ? -value : value;
}
switch( ( f < 0 ) ? format : f ) {
case FORMAT_FIXED :
case FORMAT_D :
tmpsb.append( VlkText.fixToStr( value, DEG, n, ( precision < 0) ? PRECISION_D : precision ) );
break;
case FORMAT_DM :
tmpsb.append( VlkText.intToStr( value / DEG, n ) );
tmpsb.append( "°" );
tmpsb.append( VlkText.fixToStr( value % DEG, MIN, 2, ( precision < 0) ? PRECISION_M : precision ) );
break;
case FORMAT_DMS :
tmpsb.append( VlkText.intToStr( value / DEG, n ) );
tmpsb.append( "°" );
tmpsb.append( VlkText.intToStr( ( value % DEG ) / MIN, 2 ) );
tmpsb.append( "'" );
tmpsb.append( VlkText.fixToStr( value % MIN, SEC, 2, ( precision < 0) ? PRECISION_S : precision ) );
break;
}
return tmpsb.toString();
}
public static int strToDeg( String value ) {
int idp = value.indexOf( '.' );
int idk = value.indexOf( ',' );
int igr = value.indexOf( "°" );
int imn = value.indexOf( "'" );
if( imn > igr ) {
// FORMAT_DMS // DDD°MM'SS.ss // TODO rewrite to int
int tmpi = Integer.parseInt( value.substring( 0, igr ) ) * DEG;
tmpi += Integer.parseInt( value.substring( igr + 1, imn ) ) * MIN;
tmpi += (int) ( Double.parseDouble( value.substring( imn + 1 ) ) * SEC );
return tmpi;
}
if( igr > 0 ) {
// FORMAT_DM // DDD°MM.mmmm // TODO rewrite to int
int tmpi = Integer.parseInt( value.substring( 0, igr ) ) * DEG;
tmpi += (int) ( Double.parseDouble( value.substring( igr + 1 ) ) * MIN );
return tmpi;
}
if( ( idp == 4 ) || ( idp == 5 ) ) {
// FORMAT_NMEA // DDDMM.mmmm
int tmpi = Integer.parseInt( value.substring( 0, idp - 2 ) ) * DEG;
tmpi += (int) ( Double.parseDouble( value.substring( idp - 2 ) ) * MIN );
// tmpi += Integer.parseInt( value.substring( idp - 2, idp ) ) * MIN;
// tmpi += Integer.parseInt( value.substring( idp + 1 ) ) * ( MIN / 10000 );
return tmpi;
}
if( ( idp >= 0 ) && ( idp <= 3 ) ) {
// FORMAT_D // DDD.dddddd
double tmpd = Double.parseDouble( value );
return degToInt( tmpd );
}
if( ( idk >= 0 ) && ( idk <= 3 ) ) {
// FORMAT_D // DDD,dddddd
double tmpd = Double.parseDouble( value.replace(',','.') );
return degToInt( tmpd );
}
// FORMAT_ERROR
return 0; // make exception!
}
public static int degToInt( double deg ) {
return( (int) ( deg * DEG ) );
}
public static double sqr( double x ) {
return ( x * x );
}
public static int asin( double x ) {
return (int)( (double)DEG * Math.toDegrees( Float11.asin( x ) ) );
}
// public static int asin( long x ) {
// return (int)( (double)DEG * Math.toDegrees( Float11.asin( ( (double)x ) / FIXED ) ) );
// }
public static int acos( double x ) {
return (int)( (double)DEG * Math.toDegrees( Float11.acos( x ) ) );
}
// public static int acos( long x ) {
// return (int)( (double)DEG * Math.toDegrees( Float11.acos( ( (double)x ) / FIXED ) ) );
// }
public static int atan( double x ) {
return (int)( (double)DEG * Math.toDegrees( Float11.atan( x ) ) );
}
public static int atan2( double y, double x ) {
return (int)( (double)DEG * Math.toDegrees( Float11.atan2( y, x ) ) );
}
public static double sin( int x ) {
return Math.sin( Math.toRadians( ( (double) x ) / DEG ) );
}
public static double cos( int x ) {
return Math.cos( Math.toRadians( ( (double) x ) / DEG ) );
}
private static int[] tabSin = new int[ 720 ];
private static boolean mathTablesCreated = false;
public static int fastSin( int x ) {
return( tabSin[ limitDeg( x ) / ( DEG / 2 ) ] );
}
public static int fastCos( int x ) {
x += 90 * DEG;
return( tabSin[ limitDeg( x ) / ( DEG / 2 ) ] );
}
public static void initFastMath() {
if( ! mathTablesCreated ) {
//Debug.debug( "Generating fast math tables" );
for( int i = 0; i < 720; i++ ) {
tabSin[ i ] = ( int ) ( iFIXED * Math.sin( Math.toRadians( i / 2 ) ) );
}
mathTablesCreated = true;
}
}
public static void mathBench() {
//Debug.debug( "Math speed test:" );
int j = 0;
long drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++, j += MIN ) {
sin( j );
}
//Debug.debug( "sin(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
j = 0;
drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++, j += MIN ) {
cos( j );
}
//Debug.debug( "cos(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
j = 0;
drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++, j += MIN ) {
asin( j );
}
//Debug.debug( "asin(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
j = 0;
drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++, j += MIN ) {
acos( j );
}
//Debug.debug( "acos(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
j = 0;
drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++, j += MIN ) {
fastSin( j );
}
//Debug.debug( "fastSin(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
j = 0;
drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++, j += MIN ) {
fastCos( j );
}
//Debug.debug( "fastCos(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
Coords wpt1 = new Coords( 10 * DEG, 30 * DEG, 0 );
Coords wpt2 = new Coords( 20 * DEG, 70 * DEG, 0 );
drawTime = System.currentTimeMillis();
for( int i = 0; i < 1000; i++ ) {
j = wpt1.zenith( wpt2 );
}
//Debug.debug( "zenith(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
drawTime = System.currentTimeMillis();
int k = j;
for( int i = 0; i < 1000; i++ ) {
j = wpt1.azimuth( wpt2, k );
}
//Debug.debug( "azimuth(): " + (int)( System.currentTimeMillis() - drawTime ) + "us" );
}
}