docs: boolean computeEllipseCenters() {
  		keypoints.reset();
  
  		for (int tangentIdx = 0; tangentIdx < tangents.size(); tangentIdx++) {
  //			System.out.println("tangent id "+tangentIdx);
  			Tangents t = tangents.get(tangentIdx);
  			Point2D_F64 center = keypoints.grow();
  			center.set(0,0);
  			double totalWeight = 0;
  
  			for (int i = 0; i < t.size(); i += 2) {
  				UtilLine2D_F64.convert(t.get(i),t.get(i+1),lineA);
  
  				for (int j = i+2; j < t.size(); j += 2) {
  					UtilLine2D_F64.convert(t.get(j),t.get(j+1),lineB);
  
  					// way each intersection based on the acute angle.  lines which are nearly parallel will
  					// be unstable estimates
  					double w = UtilVector2D_F64.acute(lineA.A,lineA.B,lineB.A,lineB.B);
  					if( w > Math.PI/2.0 )
  						w = Math.PI-w;
  
  					// If there is perfect data and no noise there will be duplicated lines.  With noise there will
  					// be very similar lines
  					if( w <= 0.02 )
  						continue;
  
  					if( null == Intersection2D_F64.intersection(lineA,lineB, location) ) {
  						return false;
  					}
  
  //					System.out.printf("   %4.2f loc %6.2f %6.2f\n",w,location.x,location.y);
  					center.x += location.x*w;
  					center.y += location.y*w;
  
  					totalWeight += w;
  				}
  			}
  
  			if( totalWeight == 0 )
  				return false;
  
  			center.x /= totalWeight;
  			center.y /= totalWeight;
  		}
  
  		return true;
  	}