public static double atan2(double y,double x){
  if (Double.isNaN(x) || Double.isNaN(y)) {
    return Double.NaN;
  }
  if (y == 0) {
    final double result=x * y;
    final double invx=1d / x;
    final double invy=1d / y;
    if (invx == 0) {
      if (x > 0) {
        return y;
      }
 else {
        return copySign(Math.PI,y);
      }
    }
    if (x < 0 || invx < 0) {
      if (y < 0 || invy < 0) {
        return -Math.PI;
      }
 else {
        return Math.PI;
      }
    }
 else {
      return result;
    }
  }
  if (y == Double.POSITIVE_INFINITY) {
    if (x == Double.POSITIVE_INFINITY) {
      return Math.PI * F_1_4;
    }
    if (x == Double.NEGATIVE_INFINITY) {
      return Math.PI * F_3_4;
    }
    return Math.PI * F_1_2;
  }
  if (y == Double.NEGATIVE_INFINITY) {
    if (x == Double.POSITIVE_INFINITY) {
      return -Math.PI * F_1_4;
    }
    if (x == Double.NEGATIVE_INFINITY) {
      return -Math.PI * F_3_4;
    }
    return -Math.PI * F_1_2;
  }
  if (x == Double.POSITIVE_INFINITY) {
    if (y > 0 || 1 / y > 0) {
      return 0d;
    }
    if (y < 0 || 1 / y < 0) {
      return -0d;
    }
  }
  if (x == Double.NEGATIVE_INFINITY) {
    if (y > 0.0 || 1 / y > 0.0) {
      return Math.PI;
    }
    if (y < 0 || 1 / y < 0) {
      return -Math.PI;
    }
  }
  if (x == 0) {
    if (y > 0 || 1 / y > 0) {
      return Math.PI * F_1_2;
    }
    if (y < 0 || 1 / y < 0) {
      return -Math.PI * F_1_2;
    }
  }
  final double r=y / x;
  if (Double.isInfinite(r)) {
    return atan(r,0,x < 0);
  }
  double ra=doubleHighPart(r);
  double rb=r - ra;
  final double xa=doubleHighPart(x);
  final double xb=x - xa;
  rb+=(y - ra * xa - ra * xb - rb * xa - rb * xb) / x;
  final double temp=ra + rb;
  rb=-(temp - ra - rb);
  ra=temp;
  if (ra == 0) {
    ra=copySign(0d,y);
  }
  final double result=atan(ra,rb,x < 0);
  return result;
}

public static double atan2 ( double y , double x ) { if ( Double . isNaN ( x ) || Double . isNaN ( y ) ) { return Double . NaN ; } if ( y == 0 ) { final double result = x * y ; final double invx = 1d / x ; final double invy = 1d / y ; if ( invx == 0 ) { if ( x > 0 ) { return y ; } else { return copySign ( Math . PI , y ) ; } } if ( x < 0 || invx < 0 ) { if ( y < 0 || invy < 0 ) { return - Math . PI ; } else { return Math . PI ; } } else { return result ; } } if ( y == Double . POSITIVE_INFINITY ) { if ( x == Double . POSITIVE_INFINITY ) { return Math . PI * F_1_4 ; } if ( x == Double . NEGATIVE_INFINITY ) { return Math . PI * F_3_4 ; } return Math . PI * F_1_2 ; } if ( y == Double . NEGATIVE_INFINITY ) { if ( x == Double . POSITIVE_INFINITY ) { return - Math . PI * F_1_4 ; } if ( x == Double . NEGATIVE_INFINITY ) { return - Math . PI * F_3_4 ; } return - Math . PI * F_1_2 ; } if ( x == Double . POSITIVE_INFINITY ) { if ( y > 0 || 1 / y > 0 ) { return 0d ; } if ( y < 0 || 1 / y < 0 ) { return - 0d ; } } if ( x == Double . NEGATIVE_INFINITY ) { if ( y > 0.0 || 1 / y > 0.0 ) { return Math . PI ; } if ( y < 0 || 1 / y < 0 ) { return - Math . PI ; } } if ( x == 0 ) { if ( y > 0 || 1 / y > 0 ) { return Math . PI * F_1_2 ; } if ( y < 0 || 1 / y < 0 ) { return - Math . PI * F_1_2 ; } } final double r = y / x ; if ( Double . isInfinite ( r ) ) { return atan ( r , 0 , x < 0 ) ; } double ra = doubleHighPart ( r ) ; double rb = r - ra ; final double xa = doubleHighPart ( x ) ; final double xb = x - xa ; rb += ( y - ra * xa - ra * xb - rb * xa - rb * xb ) / x ; final double temp = ra + rb ; rb = - ( temp - ra - rb ) ; ra = temp ; if ( ra == 0 ) { ra = copySign ( 0d , y ) ; } final double result = atan ( ra , rb , x < 0 ) ; return result ; }
two arguments arctangent function
