public PlaPointFloat[] tangential_points(PlaPointFloat p_to_point,double p_distance){
  double dx=Math.abs(v_x - p_to_point.v_x);
  double dy=Math.abs(v_y - p_to_point.v_y);
  boolean situation_turned=(dy > dx);
  PlaPointFloat pole;
  PlaPointFloat circle_center;
  if (situation_turned) {
    pole=new PlaPointFloat(-v_y,v_x);
    circle_center=new PlaPointFloat(-p_to_point.v_y,p_to_point.v_x);
  }
 else {
    pole=this;
    circle_center=p_to_point;
  }
  dx=pole.v_x - circle_center.v_x;
  dy=pole.v_y - circle_center.v_y;
  double dx_square=dx * dx;
  double dy_square=dy * dy;
  double dist_square=dx_square + dy_square;
  double radius_square=p_distance * p_distance;
  double discriminant=radius_square * dy_square - (radius_square - dx_square) * dist_square;
  if (discriminant <= 0) {
    return new PlaPointFloat[0];
  }
  double square_root=Math.sqrt(discriminant);
  PlaPointFloat[] result=new PlaPointFloat[2];
  double a1=radius_square * dy;
  double dy1=(a1 + p_distance * square_root) / dist_square;
  double dy2=(a1 - p_distance * square_root) / dist_square;
  double first_point_y=dy1 + circle_center.v_y;
  double first_point_x=(radius_square - dy * dy1) / dx + circle_center.v_x;
  double second_point_y=dy2 + circle_center.v_y;
  double second_point_x=(radius_square - dy * dy2) / dx + circle_center.v_x;
  if (situation_turned) {
    result[0]=new PlaPointFloat(first_point_y,-first_point_x);
    result[1]=new PlaPointFloat(second_point_y,-second_point_x);
  }
 else {
    result[0]=new PlaPointFloat(first_point_x,first_point_y);
    result[1]=new PlaPointFloat(second_point_x,second_point_y);
  }
  return result;
}

public PlaPointFloat [ ] tangential_points ( PlaPointFloat p_to_point , double p_distance ) { double dx = Math . abs ( v_x - p_to_point . v_x ) ; double dy = Math . abs ( v_y - p_to_point . v_y ) ; boolean situation_turned = ( dy > dx ) ; PlaPointFloat pole ; PlaPointFloat circle_center ; if ( situation_turned ) { pole = new PlaPointFloat ( - v_y , v_x ) ; circle_center = new PlaPointFloat ( - p_to_point . v_y , p_to_point . v_x ) ; } else { pole = this ; circle_center = p_to_point ; } dx = pole . v_x - circle_center . v_x ; dy = pole . v_y - circle_center . v_y ; double dx_square = dx * dx ; double dy_square = dy * dy ; double dist_square = dx_square + dy_square ; double radius_square = p_distance * p_distance ; double discriminant = radius_square * dy_square - ( radius_square - dx_square ) * dist_square ; if ( discriminant <= 0 ) { return new PlaPointFloat [ 0 ] ; } double square_root = Math . sqrt ( discriminant ) ; PlaPointFloat [ ] result = new PlaPointFloat [ 2 ] ; double a1 = radius_square * dy ; double dy1 = ( a1 + p_distance * square_root ) / dist_square ; double dy2 = ( a1 - p_distance * square_root ) / dist_square ; double first_point_y = dy1 + circle_center . v_y ; double first_point_x = ( radius_square - dy * dy1 ) / dx + circle_center . v_x ; double second_point_y = dy2 + circle_center . v_y ; double second_point_x = ( radius_square - dy * dy2 ) / dx + circle_center . v_x ; if ( situation_turned ) { result [ 0 ] = new PlaPointFloat ( first_point_y , - first_point_x ) ; result [ 1 ] = new PlaPointFloat ( second_point_y , - second_point_x ) ; } else { result [ 0 ] = new PlaPointFloat ( first_point_x , first_point_y ) ; result [ 1 ] = new PlaPointFloat ( second_point_x , second_point_y ) ; } return result ; }
calculates the touching points of the tangents from this point to a circle around p_to_point with radius p_distance . solves the quadratic equation , which results by substituting x by the term in y from the equation of the polar line of a circle with center p_to_point and radius p_distance and putting it into the circle equation . the polar line is the line through the 2 tangential points of the circle looked at from from this point and has the equation ( this . x - p_to_point . x ) * ( x - p_to_point . x ) + ( this . y - p_to_point . y ) * ( y - p_to_point . y ) = p_distance * * 2
