/*
* 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.metric;
import georegression.geometry.UtilLine2D_F32;
import georegression.geometry.UtilTrig_F32;
import georegression.misc.GrlConstants;
import georegression.struct.line.LineGeneral2D_F32;
import georegression.struct.line.LineParametric2D_F32;
import georegression.struct.line.LineSegment2D_F32;
import georegression.struct.point.Point2D_F32;
import georegression.struct.shapes.EllipseRotated_F32;
import georegression.struct.shapes.Polygon2D_F32;
import georegression.struct.shapes.Quadrilateral_F32;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Peter Abeles
*/
public class TestDistance2D_F32 {
@Test
public void distance_parametric_line() {
float found = Distance2D_F32.distance( new LineParametric2D_F32( -2, 0, 1, 1 ), new Point2D_F32( 4, -2 ) );
float expected = (float) UtilTrig_F32.distance( 0, 2, 4, -2 );
assertEquals( expected, found, GrlConstants.FLOAT_TEST_TOL );
}
@Test
public void distanceSq_parametric_line() {
float found = Distance2D_F32.distanceSq(new LineParametric2D_F32(-2, 0, 1, 1), new Point2D_F32(4, -2));
float expected = (float) UtilTrig_F32.distanceSq(0, 2, 4, -2);
assertEquals( expected, found, GrlConstants.FLOAT_TEST_TOL );
}
@Test
public void distance_line_segment() {
// test inside the line
float found = Distance2D_F32.distance( new LineSegment2D_F32( -2, 0, 3, 5 ), new Point2D_F32( 2, 0 ) );
float expected = (float) UtilTrig_F32.distance( 0, 2, 2, 0 );
assertEquals( expected, found, GrlConstants.FLOAT_TEST_TOL );
// test before the first end point
found = Distance2D_F32.distance( new LineSegment2D_F32( -2, 0, 3, 5 ), new Point2D_F32( -5, -5 ) );
expected = UtilTrig_F32.distance( -2, 0, -5, -5 );
assertEquals( expected, found, GrlConstants.FLOAT_TEST_TOL );
// test after the second end point
found = Distance2D_F32.distance( new LineSegment2D_F32( -2, 0, 3, 5 ), new Point2D_F32( 10, 0 ) );
expected = UtilTrig_F32.distance( 3, 5, 10, 0 );
assertEquals( expected, found, GrlConstants.FLOAT_TEST_TOL );
}
@Test
public void distance_general_line() {
// easier to cherry pick points in parametric notation
LineParametric2D_F32 parametric = new LineParametric2D_F32( -2, 0, 1, 1 );
// convert into general format
LineGeneral2D_F32 general = UtilLine2D_F32.convert(parametric,(LineGeneral2D_F32)null);
float found = Distance2D_F32.distance( general , new Point2D_F32( 4, -2 ) );
float expected = (float) UtilTrig_F32.distance( 0, 2, 4, -2 );
assertEquals(expected, found, GrlConstants.FLOAT_TEST_TOL);
}
@Test
public void distance_generalNorm_line() {
// easier to cherry pick points in parametric notation
LineParametric2D_F32 parametric = new LineParametric2D_F32( -2, 0, 1, 1 );
// convert into general format
LineGeneral2D_F32 general = UtilLine2D_F32.convert(parametric,(LineGeneral2D_F32)null);
general.normalize();
// test a point and its reflection. Should be same distance and positive
float found = Distance2D_F32.distanceNorm(general, new Point2D_F32(4, -2));
float expected = (float) UtilTrig_F32.distance( 0, 2, 4, -2 );
assertEquals(expected, found, GrlConstants.FLOAT_TEST_TOL);
// the reflection should also be positive
found = Distance2D_F32.distanceNorm(general, new Point2D_F32(-4, 6));
assertEquals(expected, found, GrlConstants.FLOAT_TEST_TOL);
}
@Test
public void distance_lineSegment_lineSegment() {
// case of no intersection but one of the lines intersects inside
LineSegment2D_F32 a = new LineSegment2D_F32(0,0,10,0);
LineSegment2D_F32 b = new LineSegment2D_F32(5,2,5,10);
assertEquals(2,Distance2D_F32.distance(a,b),GrlConstants.FLOAT_TEST_TOL);
assertEquals(2,Distance2D_F32.distance(b,a),GrlConstants.FLOAT_TEST_TOL);
// the two lines intersect
b.set(5, -1, 5, 1);
assertEquals(0, Distance2D_F32.distance(a, b), GrlConstants.FLOAT_TEST_TOL);
assertEquals(0, Distance2D_F32.distance(b, a), GrlConstants.FLOAT_TEST_TOL);
// two lines are parallel but don't intersect
b.set(12, 2, 2, 20);
float expected = (float)Math.sqrt(2*2*2);
assertEquals(expected, Distance2D_F32.distance(a, b), GrlConstants.FLOAT_TEST_TOL);
assertEquals(expected, Distance2D_F32.distance(b, a), GrlConstants.FLOAT_TEST_TOL);
// general case where the end points are the closest
// one of these cases was tested above already
b.set(5,-2,5,-10);
assertEquals(2,Distance2D_F32.distance(a,b),GrlConstants.FLOAT_TEST_TOL);
assertEquals(2,Distance2D_F32.distance(b,a),GrlConstants.FLOAT_TEST_TOL);
}
@Test
public void distance_quadrilateral_point() {
Quadrilateral_F32 quad = new Quadrilateral_F32(2,0, 2,10, 10,10, 10,0);
// test a point to the left and right of a side. should be the same
assertEquals(3,Distance2D_F32.distance(quad,new Point2D_F32(-1,3)),GrlConstants.FLOAT_TEST_TOL);
assertEquals(3,Distance2D_F32.distance(quad,new Point2D_F32(5,3)),GrlConstants.FLOAT_TEST_TOL);
// try the other sides
assertEquals(4,Distance2D_F32.distance(quad,new Point2D_F32(5,14)),GrlConstants.FLOAT_TEST_TOL);
assertEquals(5,Distance2D_F32.distance(quad,new Point2D_F32(15,5)),GrlConstants.FLOAT_TEST_TOL);
assertEquals(6,Distance2D_F32.distance(quad,new Point2D_F32(6,-6)),GrlConstants.FLOAT_TEST_TOL);
}
@Test
public void distance_polygon_point() {
Polygon2D_F32 poly = new Polygon2D_F32(2,0, 2,10, 10,10, 10,0);
// test a point to the left and right of a side. should be the same
assertEquals(3,Distance2D_F32.distance(poly,new Point2D_F32(-1,3)),GrlConstants.FLOAT_TEST_TOL);
assertEquals(3,Distance2D_F32.distance(poly,new Point2D_F32(5,3)),GrlConstants.FLOAT_TEST_TOL);
// try the other sides
assertEquals(4,Distance2D_F32.distance(poly,new Point2D_F32(5,14)),GrlConstants.FLOAT_TEST_TOL);
assertEquals(5,Distance2D_F32.distance(poly,new Point2D_F32(15,5)),GrlConstants.FLOAT_TEST_TOL);
assertEquals(6,Distance2D_F32.distance(poly,new Point2D_F32(6,-6)),GrlConstants.FLOAT_TEST_TOL);
}
@Test
public void distanceOrigin_LineParametric() {
LineParametric2D_F32 line = new LineParametric2D_F32(2.3f,-9.5f,2,-3.1f);
float expected = Distance2D_F32.distance(line,new Point2D_F32());
float found = Distance2D_F32.distanceOrigin(line);
assertEquals(expected,found,GrlConstants.FLOAT_TEST_TOL);
}
@Test
public void distance_ellipserotated_point() {
EllipseRotated_F32 ellipse = new EllipseRotated_F32(4,5,4,3, GrlConstants.F_PId2);
assertEquals(0, Distance2D_F32.distance(ellipse,new Point2D_F32(4+3,5)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(0, Distance2D_F32.distance(ellipse,new Point2D_F32(4-3,5)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(0, Distance2D_F32.distance(ellipse,new Point2D_F32(4,5-4)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(0, Distance2D_F32.distance(ellipse,new Point2D_F32(4,5+4)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(1, Distance2D_F32.distance(ellipse,new Point2D_F32(4+2,5)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(1, Distance2D_F32.distance(ellipse,new Point2D_F32(4-2,5)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(1.1f, Distance2D_F32.distance(ellipse,new Point2D_F32(4+4.1f,5)), GrlConstants.FLOAT_TEST_TOL);
assertEquals(1.1f, Distance2D_F32.distance(ellipse,new Point2D_F32(4-4.1f,5)), GrlConstants.FLOAT_TEST_TOL);
}
}