private PlaLineInt smoothen_corner(PlaLineIntAlist p_line_arr,int p_start_no){
  if (p_line_arr.size() - p_start_no < 4)   return null;
  PlaLineInt cur_line=p_line_arr.get(p_start_no);
  PlaLineInt a_line=p_line_arr.get(p_start_no + 1);
  PlaLineInt b_line=p_line_arr.get(p_start_no + 2);
  PlaLineInt d_line=p_line_arr.get(p_start_no + 3);
  PlaPointFloat curr_corner=a_line.intersection_approx(b_line);
  if (curr_corner.is_NaN())   return null;
  double cosinus_angle=a_line.cos_angle(b_line);
  if (cosinus_angle > COS_ANGLE_MAX)   return null;
  PlaPointFloat prev_corner=cur_line.intersection_approx(a_line);
  if (prev_corner.is_NaN())   return null;
  PlaPointFloat next_corner=b_line.intersection_approx(d_line);
  if (next_corner.is_NaN())   return null;
  PlaDirection prev_dir=a_line.direction();
  PlaDirection next_dir=b_line.direction();
  PlaDirection middle_dir=prev_dir.middle_approx(next_dir);
  PlaLineInt translate_line=new PlaLineInt(curr_corner.round(),middle_dir);
  double prev_dist=translate_line.distance_signed(prev_corner);
  double next_dist=translate_line.distance_signed(next_corner);
  PlaPointFloat nearest_point;
  double max_translate_dist;
  if (Math.abs(prev_dist) < Math.abs(next_dist)) {
    nearest_point=prev_corner;
    max_translate_dist=prev_dist;
  }
 else {
    nearest_point=next_corner;
    max_translate_dist=next_dist;
  }
  if (Math.abs(max_translate_dist) < 1)   return null;
  PlaLineIntAlist curr_lines=new PlaLineIntAlist(p_line_arr.size(1));
  p_line_arr.append_to(curr_lines,0);
  curr_lines.add_null(p_start_no + 2);
  double translate_dist=max_translate_dist;
  double delta_dist=max_translate_dist;
  PlaSide side_of_nearest_point=translate_line.side_of(nearest_point);
  int sign=Signum.as_int(max_translate_dist);
  PlaLineInt result=null;
  while (Math.abs(delta_dist) > min_move_dist) {
    boolean check_ok=false;
    PlaLineInt new_line=translate_line.translate(-translate_dist);
    PlaSide new_line_side_of_nearest_point=new_line.side_of(nearest_point);
    if (new_line_side_of_nearest_point == side_of_nearest_point || new_line_side_of_nearest_point == PlaSide.COLLINEAR) {
      curr_lines.set(p_start_no + 2,new_line);
      Polyline tmp=new Polyline(curr_lines);
      if (tmp.plaline_len() == curr_lines.size()) {
        ShapeTile shape_to_check=tmp.offset_shape(curr_half_width,p_start_no + 1);
        check_ok=r_board.check_trace(shape_to_check,curr_layer,curr_net_no_arr,curr_cl_type,contact_pins);
      }
      delta_dist/=2;
      if (check_ok) {
        result=new_line;
        if (translate_dist == max_translate_dist) {
          break;
        }
        translate_dist+=delta_dist;
      }
 else {
        translate_dist-=delta_dist;
      }
    }
 else {
      double shorten_value=sign * 0.5;
      max_translate_dist-=shorten_value;
      translate_dist-=shorten_value;
      delta_dist-=shorten_value;
    }
  }
  if (result == null)   return null;
  curr_lines.changed_area_join_corner(r_board.changed_area,p_start_no,curr_layer);
  curr_lines.changed_area_join_corner(r_board.changed_area,p_start_no + 3,curr_layer);
  return result;
}

private PlaLineInt smoothen_corner ( PlaLineIntAlist p_line_arr , int p_start_no ) { if ( p_line_arr . size ( ) - p_start_no < 4 ) return null ; PlaLineInt cur_line = p_line_arr . get ( p_start_no ) ; PlaLineInt a_line = p_line_arr . get ( p_start_no + 1 ) ; PlaLineInt b_line = p_line_arr . get ( p_start_no + 2 ) ; PlaLineInt d_line = p_line_arr . get ( p_start_no + 3 ) ; PlaPointFloat curr_corner = a_line . intersection_approx ( b_line ) ; if ( curr_corner . is_NaN ( ) ) return null ; double cosinus_angle = a_line . cos_angle ( b_line ) ; if ( cosinus_angle > COS_ANGLE_MAX ) return null ; PlaPointFloat prev_corner = cur_line . intersection_approx ( a_line ) ; if ( prev_corner . is_NaN ( ) ) return null ; PlaPointFloat next_corner = b_line . intersection_approx ( d_line ) ; if ( next_corner . is_NaN ( ) ) return null ; PlaDirection prev_dir = a_line . direction ( ) ; PlaDirection next_dir = b_line . direction ( ) ; PlaDirection middle_dir = prev_dir . middle_approx ( next_dir ) ; PlaLineInt translate_line = new PlaLineInt ( curr_corner . round ( ) , middle_dir ) ; double prev_dist = translate_line . distance_signed ( prev_corner ) ; double next_dist = translate_line . distance_signed ( next_corner ) ; PlaPointFloat nearest_point ; double max_translate_dist ; if ( Math . abs ( prev_dist ) < Math . abs ( next_dist ) ) { nearest_point = prev_corner ; max_translate_dist = prev_dist ; } else { nearest_point = next_corner ; max_translate_dist = next_dist ; } if ( Math . abs ( max_translate_dist ) < 1 ) return null ; PlaLineIntAlist curr_lines = new PlaLineIntAlist ( p_line_arr . size ( 1 ) ) ; p_line_arr . append_to ( curr_lines , 0 ) ; curr_lines . add_null ( p_start_no + 2 ) ; double translate_dist = max_translate_dist ; double delta_dist = max_translate_dist ; PlaSide side_of_nearest_point = translate_line . side_of ( nearest_point ) ; int sign = Signum . as_int ( max_translate_dist ) ; PlaLineInt result = null ; while ( Math . abs ( delta_dist ) > min_move_dist ) { boolean check_ok = false ; PlaLineInt new_line = translate_line . translate ( - translate_dist ) ; PlaSide new_line_side_of_nearest_point = new_line . side_of ( nearest_point ) ; if ( new_line_side_of_nearest_point == side_of_nearest_point || new_line_side_of_nearest_point == PlaSide . COLLINEAR ) { curr_lines . set ( p_start_no + 2 , new_line ) ; Polyline tmp = new Polyline ( curr_lines ) ; if ( tmp . plaline_len ( ) == curr_lines . size ( ) ) { ShapeTile shape_to_check = tmp . offset_shape ( curr_half_width , p_start_no + 1 ) ; check_ok = r_board . check_trace ( shape_to_check , curr_layer , curr_net_no_arr , curr_cl_type , contact_pins ) ; } delta_dist /= 2 ; if ( check_ok ) { result = new_line ; if ( translate_dist == max_translate_dist ) { break ; } translate_dist += delta_dist ; } else { translate_dist -= delta_dist ; } } else { double shorten_value = sign * 0.5 ; max_translate_dist -= shorten_value ; translate_dist -= shorten_value ; delta_dist -= shorten_value ; } } if ( result == null ) return null ; curr_lines . changed_area_join_corner ( r_board . changed_area , p_start_no , curr_layer ) ; curr_lines . changed_area_join_corner ( r_board . changed_area , p_start_no + 3 , curr_layer ) ; return result ; }
try to smothen the corner by adding an extra line and check if it is ok
