/*
* Copyright (C) 2011-2015, Peter Abeles. All Rights Reserved.
*
* This file is part of Geometric Regression Library (GeoRegression).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package georegression.fitting.ellipse;
import georegression.geometry.UtilEllipse_F32;
import georegression.misc.GrlConstants;
import georegression.struct.point.Point2D_F32;
import georegression.struct.shapes.EllipseRotated_F32;
import org.junit.Test;
import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Peter Abeles
*/
public class TestClosestPointEllipseAngle_F32 {
Random rand = new Random(234);
@Test
public void easyTest() {
checkSolution(0,0,3,1.5f,0,5,6);
checkSolution(1,2,3,1.5f,0.2f,5,6);
checkSolution(1,2,3,1.5f,0.2f,1,2);
}
@Test
public void random() {
for( int i = 0; i < 100; i++ ) {
float x0 = (rand.nextFloat()-0.5f)*5;
float y0 = (rand.nextFloat()-0.5f)*5;
float b = rand.nextFloat()*3+0.1f;
float a = b + rand.nextFloat();
float phi = rand.nextFloat()*(float)Math.PI*2;
float x = (rand.nextFloat()-0.5f)*10;
float y = (rand.nextFloat()-0.5f)*10;
checkSolution(x0,y0,a,b,phi,x,y);
}
}
public void checkSolution( float x0 , float y0, float a, float b, float phi , float x , float y ) {
EllipseRotated_F32 ellipse = new EllipseRotated_F32(x0,y0,a,b,phi);
ClosestPointEllipseAngle_F32 alg = new ClosestPointEllipseAngle_F32(GrlConstants.FLOAT_TEST_TOL,200);
Point2D_F32 p = new Point2D_F32(x,y);
alg.setEllipse(ellipse);
alg.process(p);
Point2D_F32 found = alg.getClosest();
// is it on the ellipse?
assertEquals(1, UtilEllipse_F32.evaluate(found.x,found.y,ellipse),GrlConstants.FLOAT_TEST_TOL);
// skip local test for center
if( x0 == x && y0 == y )
return;
float dist = found.distance(p);
float dist0 = p.distance(UtilEllipse_F32.computePoint(alg.getTheta()+0.05f,ellipse,null));
float dist1 = p.distance(UtilEllipse_F32.computePoint(alg.getTheta()-0.05f,ellipse,null));
// is it a local optimal?
// inflate slightly to take in account floating point precision
assertTrue( dist < dist0*1.001f );
assertTrue( dist < dist1*1.001f );
}
}