public static double averageOfClosestPointError ( Polygon2D_F64 model , Polygon2D_F64 target , int numberOfSamples ) { LineSegment2D_F64 line = new LineSegment2D_F64 ( ) ; double cornerLocationsB [ ] = new double [ target . size ( ) + 1 ] ; double totalLength = 0 ; for ( int i = 0 ; i < target . size ( ) ; i ++ ) { Point2D_F64 b0 = target . get ( i % target . size ( ) ) ; Point2D_F64 b1 = target . get ( ( i + 1 ) % target . size ( ) ) ; cornerLocationsB [ i ] = totalLength ; totalLength += b0 . distance ( b1 ) ; } cornerLocationsB [ target . size ( ) ] = totalLength ; Point2D_F64 pointOnB = new Point2D_F64 ( ) ; double error = 0 ; int cornerB = 0 ; for ( int k = 0 ; k < numberOfSamples ; k ++ ) { // Find the point on B to match to a point on A double location = totalLength * k / numberOfSamples ; while ( location > cornerLocationsB [ cornerB + 1 ] ) { cornerB ++ ; } Point2D_F64 b0 = target . get ( cornerB ) ; Point2D_F64 b1 = target . get ( ( cornerB + 1 ) % target . size ( ) ) ; double locationCornerB = cornerLocationsB [ cornerB ] ; double fraction = ( location - locationCornerB ) / ( cornerLocationsB [ cornerB + 1 ] - locationCornerB ) ; pointOnB . x = ( b1 . x - b0 . x ) * fraction + b0 . x ; pointOnB . y = ( b1 . y - b0 . y ) * fraction + b0 . y ; // find the best fit point on A to the point in B double best = Double . MAX_VALUE ; for ( int i = 0 ; i < model . size ( ) + 1 ; i ++ ) { line . a = model . get ( i % model . size ( ) ) ; line . b = model . get ( ( i + 1 ) % model . size ( ) ) ; double d = Distance2D_F64 . distance ( line , pointOnB ) ; if ( d < best ) { best = d ; } } error += best ; } return error / numberOfSamples ; }
Compute the error as a function of the distance between the model and target . The target is sampled at regular intervals and for each of these points the closest point on the model is found . The returned metric is the average of difference between paired points .