main/src/georegression/geometry/UtilPolygons2D_F64.java
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;
	}
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;
	}
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.

NOTE: A different answer will be returned depending on which polygon is the model and which one is the target.

@param model Model polygon
@param target Target polygon
@return average of closest point error
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 .