/* * 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_F64; import georegression.misc.GrlConstants; import georegression.struct.point.Point2D_F64; import georegression.struct.shapes.EllipseRotated_F64; 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_F64 { Random rand = new Random(234); @Test public void easyTest() { checkSolution(0,0,3,1.5,0,5,6); checkSolution(1,2,3,1.5,0.2,5,6); checkSolution(1,2,3,1.5,0.2,1,2); } @Test public void random() { for( int i = 0; i < 100; i++ ) { double x0 = (rand.nextDouble()-0.5)*5; double y0 = (rand.nextDouble()-0.5)*5; double b = rand.nextDouble()*3+0.1; double a = b + rand.nextDouble(); double phi = rand.nextDouble()*(double)Math.PI*2; double x = (rand.nextDouble()-0.5)*10; double y = (rand.nextDouble()-0.5)*10; checkSolution(x0,y0,a,b,phi,x,y); } } public void checkSolution( double x0 , double y0, double a, double b, double phi , double x , double y ) { EllipseRotated_F64 ellipse = new EllipseRotated_F64(x0,y0,a,b,phi); ClosestPointEllipseAngle_F64 alg = new ClosestPointEllipseAngle_F64(GrlConstants.DOUBLE_TEST_TOL,200); Point2D_F64 p = new Point2D_F64(x,y); alg.setEllipse(ellipse); alg.process(p); Point2D_F64 found = alg.getClosest(); // is it on the ellipse? assertEquals(1, UtilEllipse_F64.evaluate(found.x,found.y,ellipse),GrlConstants.DOUBLE_TEST_TOL); // skip local test for center if( x0 == x && y0 == y ) return; double dist = found.distance(p); double dist0 = p.distance(UtilEllipse_F64.computePoint(alg.getTheta()+0.05,ellipse,null)); double dist1 = p.distance(UtilEllipse_F64.computePoint(alg.getTheta()-0.05,ellipse,null)); // is it a local optimal? // inflate slightly to take in account floating point precision assertTrue( dist < dist0*1.001 ); assertTrue( dist < dist1*1.001 ); } }