/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.commons.geometry.euclidean.twod;

import org.apache.commons.numbers.angle.PlaneAngleRadians;
import org.apache.commons.geometry.core.GeometryTestUtils;
import org.apache.commons.geometry.core.exception.GeometryValueException;
import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
import org.apache.commons.geometry.euclidean.oned.AffineTransformMatrix1D;
import org.apache.commons.geometry.euclidean.oned.Interval;
import org.apache.commons.geometry.euclidean.oned.Vector1D;
import org.apache.commons.geometry.euclidean.twod.Line.SubspaceTransform;
import org.apache.commons.numbers.angle.PlaneAngleRadians;
import org.junit.Assert;
import org.junit.Test;

public class LineTest {

    private static final double TEST_EPS = 1e-10;

    private static final DoublePrecisionContext TEST_PRECISION =
            new EpsilonDoublePrecisionContext(TEST_EPS);

    @Test
    public void testFromPoints() {
        // act/assert
        checkLine(Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);
        checkLine(Line.fromPoints(Vector2D.ZERO, Vector2D.of(100, 0), TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);
        checkLine(Line.fromPoints(Vector2D.of(100, 0), Vector2D.ZERO, TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.MINUS_X);
        checkLine(Line.fromPoints(Vector2D.of(-100, 0), Vector2D.of(100, 0), TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);

        checkLine(Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 2), TEST_PRECISION),
                Vector2D.of(-1, 1), Vector2D.of(1, 1).normalize());
        checkLine(Line.fromPoints(Vector2D.of(0, 2), Vector2D.of(-2, 0), TEST_PRECISION),
                Vector2D.of(-1, 1), Vector2D.of(-1, -1).normalize());
    }

    @Test
    public void testFromPoints_pointsTooClose() {
        // act/assert
        GeometryTestUtils.assertThrows(() -> Line.fromPoints(Vector2D.Unit.PLUS_X, Vector2D.Unit.PLUS_X, TEST_PRECISION),
                GeometryValueException.class, "Line direction cannot be zero");
        GeometryTestUtils.assertThrows(() -> Line.fromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1 + 1e-11, 1e-11), TEST_PRECISION),
                GeometryValueException.class, "Line direction cannot be zero");
    }

    @Test
    public void testFromPointAndDirection() {
        // act/assert
        checkLine(Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);
        checkLine(Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(100, 0), TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);
        checkLine(Line.fromPointAndDirection(Vector2D.of(-100, 0), Vector2D.of(100, 0), TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);

        checkLine(Line.fromPointAndDirection(Vector2D.of(-2, 0), Vector2D.of(1, 1), TEST_PRECISION),
                Vector2D.of(-1, 1), Vector2D.of(1, 1).normalize());
        checkLine(Line.fromPointAndDirection(Vector2D.of(0, 2), Vector2D.of(-1, -1), TEST_PRECISION),
                Vector2D.of(-1, 1), Vector2D.of(-1, -1).normalize());
    }

    @Test
    public void testFromPointAndDirection_directionIsZero() {
        // act/assert
        GeometryTestUtils.assertThrows(() -> Line.fromPointAndDirection(Vector2D.Unit.PLUS_X, Vector2D.ZERO, TEST_PRECISION),
                GeometryValueException.class, "Line direction cannot be zero");
        GeometryTestUtils.assertThrows(() -> Line.fromPointAndDirection(Vector2D.Unit.PLUS_X, Vector2D.of(1e-11, -1e-12), TEST_PRECISION),
                GeometryValueException.class, "Line direction cannot be zero");
    }

    @Test
    public void testFromPointAndAngle() {
        // act/assert
        checkLine(Line.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION),
                Vector2D.ZERO, Vector2D.Unit.PLUS_X);
        checkLine(Line.fromPointAndAngle(Vector2D.of(1, 1), PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION),
                Vector2D.of(1, 0), Vector2D.Unit.PLUS_Y);
        checkLine(Line.fromPointAndAngle(Vector2D.of(-1, -1), PlaneAngleRadians.PI, TEST_PRECISION),
                Vector2D.of(0, -1), Vector2D.Unit.MINUS_X);
        checkLine(Line.fromPointAndAngle(Vector2D.of(1, -1), -PlaneAngleRadians.PI_OVER_TWO, TEST_PRECISION),
                Vector2D.of(1, 0), Vector2D.Unit.MINUS_Y);
        checkLine(Line.fromPointAndAngle(Vector2D.of(-1, 1), PlaneAngleRadians.TWO_PI, TEST_PRECISION),
                Vector2D.of(0, 1), Vector2D.Unit.PLUS_X);
    }

    @Test
    public void testGetAngle() {
        // arrange
        Vector2D vec = Vector2D.of(1, 2);

        for (double theta = -4 * PlaneAngleRadians.PI; theta < 2 * PlaneAngleRadians.PI; theta += 0.1) {
            Line line = Line.fromPointAndAngle(vec, theta, TEST_PRECISION);

            // act/assert
            Assert.assertEquals(PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(theta),
                    line.getAngle(), TEST_EPS);
        }
    }

    @Test
    public void testGetAngle_multiplesOfPi() {
        // arrange
        Vector2D vec = Vector2D.of(-1, -2);

        // act/assert
        Assert.assertEquals(0, Line.fromPointAndAngle(vec, 0.0, TEST_PRECISION).getAngle(), TEST_EPS);
        Assert.assertEquals(PlaneAngleRadians.PI, Line.fromPointAndAngle(vec, PlaneAngleRadians.PI, TEST_PRECISION).getAngle(), TEST_EPS);
        Assert.assertEquals(0, Line.fromPointAndAngle(vec, PlaneAngleRadians.TWO_PI, TEST_PRECISION).getAngle(), TEST_EPS);

        Assert.assertEquals(0, Line.fromPointAndAngle(vec, -2 * PlaneAngleRadians.PI, TEST_PRECISION).getAngle(), TEST_EPS);
        Assert.assertEquals(PlaneAngleRadians.PI, Line.fromPointAndAngle(vec, -3 * PlaneAngleRadians.PI, TEST_PRECISION).getAngle(), TEST_EPS);
        Assert.assertEquals(0, Line.fromPointAndAngle(vec, -4 * PlaneAngleRadians.TWO_PI, TEST_PRECISION).getAngle(), TEST_EPS);
    }

    @Test
    public void testGetDirection() {
        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.PLUS_X,
                Line.fromPoints(Vector2D.of(0, 0), Vector2D.of(1, 0), TEST_PRECISION).getDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_Y,
                Line.fromPoints(Vector2D.of(0, 1), Vector2D.of(0, -1), TEST_PRECISION).getDirection(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_X,
                Line.fromPoints(Vector2D.of(2, 2), Vector2D.of(1, 2), TEST_PRECISION).getDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.PLUS_X,
                Line.fromPoints(Vector2D.of(10, -2), Vector2D.of(10.1, -2), TEST_PRECISION).getDirection(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_Y,
                Line.fromPoints(Vector2D.of(3, 2), Vector2D.of(3, 1), TEST_PRECISION).getDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.PLUS_Y,
                Line.fromPoints(Vector2D.of(-3, 10), Vector2D.of(-3, 10.1), TEST_PRECISION).getDirection(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, -1).normalize(),
                Line.fromPoints(Vector2D.of(0, 2), Vector2D.of(2, 0), TEST_PRECISION).getDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, 1).normalize(),
                Line.fromPoints(Vector2D.of(2, 0), Vector2D.of(0, 2), TEST_PRECISION).getDirection(), TEST_EPS);
    }

    @Test
    public void testGetOffsetDirection() {
        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_Y,
                Line.fromPoints(Vector2D.of(0, 0), Vector2D.of(1, 0), TEST_PRECISION).getOffsetDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_X,
                Line.fromPoints(Vector2D.of(0, 1), Vector2D.of(0, -1), TEST_PRECISION).getOffsetDirection(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.PLUS_Y,
                Line.fromPoints(Vector2D.of(2, 2), Vector2D.of(1, 2), TEST_PRECISION).getOffsetDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_Y,
                Line.fromPoints(Vector2D.of(10, -2), Vector2D.of(10.1, -2), TEST_PRECISION).getOffsetDirection(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_X,
                Line.fromPoints(Vector2D.of(3, 2), Vector2D.of(3, 1), TEST_PRECISION).getOffsetDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.PLUS_X,
                Line.fromPoints(Vector2D.of(-3, 10), Vector2D.of(-3, 10.1), TEST_PRECISION).getOffsetDirection(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-1, -1).normalize(),
                Line.fromPoints(Vector2D.of(0, 2), Vector2D.of(2, 0), TEST_PRECISION).getOffsetDirection(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1).normalize(),
                Line.fromPoints(Vector2D.of(2, 0), Vector2D.of(0, 2), TEST_PRECISION).getOffsetDirection(), TEST_EPS);
    }

    @Test
    public void testGetOrigin() {
        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO,
                Line.fromPoints(Vector2D.of(0, 0), Vector2D.of(1, 0), TEST_PRECISION).getOrigin(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO,
                Line.fromPoints(Vector2D.of(0, 1), Vector2D.of(0, -1), TEST_PRECISION).getOrigin(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2),
                Line.fromPoints(Vector2D.of(2, 2), Vector2D.of(3, 2), TEST_PRECISION).getOrigin(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -2),
                Line.fromPoints(Vector2D.of(10, -2), Vector2D.of(10.1, -2), TEST_PRECISION).getOrigin(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 0),
                Line.fromPoints(Vector2D.of(3, 2), Vector2D.of(3, 1), TEST_PRECISION).getOrigin(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 0),
                Line.fromPoints(Vector2D.of(-3, 10), Vector2D.of(-3, 10.1), TEST_PRECISION).getOrigin(), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1),
                Line.fromPoints(Vector2D.of(0, 2), Vector2D.of(2, 0), TEST_PRECISION).getOrigin(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1),
                Line.fromPoints(Vector2D.of(2, 0), Vector2D.of(0, 2), TEST_PRECISION).getOrigin(), TEST_EPS);
    }

    @Test
    public void testGetOriginOffset() {
        // arrange
        double sqrt2 = Math.sqrt(2);

        // act/assert
        Assert.assertEquals(0.0,
                Line.fromPoints(Vector2D.of(0, 0), Vector2D.of(1, 1), TEST_PRECISION).getOriginOffset(), TEST_EPS);
        Assert.assertEquals(0.0,
                Line.fromPoints(Vector2D.of(0, 0), Vector2D.of(-1, -1), TEST_PRECISION).getOriginOffset(), TEST_EPS);

        Assert.assertEquals(sqrt2,
                Line.fromPoints(Vector2D.of(-1, 1), Vector2D.of(0, 2), TEST_PRECISION).getOriginOffset(), TEST_EPS);
        Assert.assertEquals(-sqrt2,
                Line.fromPoints(Vector2D.of(0, -2), Vector2D.of(1, -1), TEST_PRECISION).getOriginOffset(), TEST_EPS);

        Assert.assertEquals(-sqrt2,
                Line.fromPoints(Vector2D.of(0, 2), Vector2D.of(-1, 1), TEST_PRECISION).getOriginOffset(), TEST_EPS);
        Assert.assertEquals(sqrt2,
                Line.fromPoints(Vector2D.of(1, -1), Vector2D.of(0, -2), TEST_PRECISION).getOriginOffset(), TEST_EPS);
    }

    @Test
    public void testGetPrecision() {
        // act/assert
        Assert.assertSame(TEST_PRECISION, Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION).getPrecision());
        Assert.assertSame(TEST_PRECISION, Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION).getPrecision());
        Assert.assertSame(TEST_PRECISION, Line.fromPointAndAngle(Vector2D.ZERO, 0, TEST_PRECISION).getPrecision());
    }

    @Test
    public void testReverse() {
        // arrange
        Vector2D pt = Vector2D.of(0, 1);
        Vector2D dir = Vector2D.Unit.PLUS_X;
        Line line = Line.fromPointAndDirection(pt, dir, TEST_PRECISION);

        // act
        Line reversed = line.reverse();
        Line doubleReversed = reversed.reverse();

        // assert
        checkLine(reversed, pt, dir.negate());
        Assert.assertEquals(-1, reversed.getOriginOffset(), TEST_EPS);

        checkLine(doubleReversed, pt, dir);
        Assert.assertEquals(1, doubleReversed.getOriginOffset(), TEST_EPS);
    }

    @Test
    public void testAbscissa() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(-2, -2), Vector2D.of(2, 1), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(0.0, line.abscissa(Vector2D.of(-3,  4)), TEST_EPS);
        Assert.assertEquals(0.0, line.abscissa(Vector2D.of( 3, -4)), TEST_EPS);
        Assert.assertEquals(5.0, line.abscissa(Vector2D.of(7, -1)), TEST_EPS);
        Assert.assertEquals(-5.0, line.abscissa(Vector2D.of(-1, -7)), TEST_EPS);
    }

    @Test
    public void testToSubspace() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(2, 1), Vector2D.of(-2, -2), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(0.0, line.toSubspace(Vector2D.of(-3,  4)).getX(), TEST_EPS);
        Assert.assertEquals(0.0, line.toSubspace(Vector2D.of( 3, -4)).getX(), TEST_EPS);
        Assert.assertEquals(-5.0, line.toSubspace(Vector2D.of(7, -1)).getX(), TEST_EPS);
        Assert.assertEquals(5.0, line.toSubspace(Vector2D.of(-1, -7)).getX(), TEST_EPS);
    }

    @Test
    public void testToSpace_throughOrigin() {
        // arrange
        double invSqrt2 = 1 / Math.sqrt(2);
        Vector2D dir = Vector2D.of(invSqrt2, invSqrt2);

        Line line = Line.fromPoints(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);

        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, line.toSpace(Vector1D.of(0)), TEST_EPS);

        for (int i=0; i<100; ++i) {
            EuclideanTestUtils.assertCoordinatesEqual(dir.multiply(i), line.toSpace(Vector1D.of(i)), TEST_EPS);
            EuclideanTestUtils.assertCoordinatesEqual(dir.multiply(-i), line.toSpace(Vector1D.of(-i)), TEST_EPS);
        }
    }

    @Test
    public void testToSpace_offsetFromOrigin() {
        // arrange
        double angle = PlaneAngleRadians.PI / 6;
        double cos = Math.cos(angle);
        double sin = Math.sin(angle);
        Vector2D pt = Vector2D.of(-5, 0);

        double h = Math.abs(pt.getX()) * cos;
        double d = h * cos;
        Vector2D origin = Vector2D.of(
                    pt.getX() + d,
                    h * sin
                );
        Vector2D dir = Vector2D.of(cos, sin);

        Line line = Line.fromPointAndAngle(pt, angle, TEST_PRECISION);

        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(origin, line.toSpace(Vector1D.of(0)), TEST_EPS);

        for (int i=0; i<100; ++i) {
            EuclideanTestUtils.assertCoordinatesEqual(origin.add(dir.multiply(i)), line.toSpace(Vector1D.of(i)), TEST_EPS);
            EuclideanTestUtils.assertCoordinatesEqual(origin.add(dir.multiply(-i)), line.toSpace(Vector1D.of(-i)), TEST_EPS);
        }
    }

    @Test
    public void testIntersection() {
        // arrange
        Line a = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line b = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_Y, TEST_PRECISION);
        Line c = Line.fromPointAndDirection(Vector2D.of(0, 2), Vector2D.of(2, 1), TEST_PRECISION);
        Line d = Line.fromPointAndDirection(Vector2D.of(0, -1), Vector2D.of(2, -1), TEST_PRECISION);

        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, a.intersection(b), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, b.intersection(a), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-4, 0), a.intersection(c), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-4, 0), c.intersection(a), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, 0), a.intersection(d), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, 0), d.intersection(a), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2), b.intersection(c), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2), c.intersection(b), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -1), b.intersection(d), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -1), d.intersection(b), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 0.5), c.intersection(d), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 0.5), d.intersection(c), TEST_EPS);
    }

    @Test
    public void testIntersection_parallel() {
        // arrange
        Line a = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line b = Line.fromPointAndDirection(Vector2D.of(0, 1), Vector2D.Unit.PLUS_X, TEST_PRECISION);

        Line c = Line.fromPointAndDirection(Vector2D.of(0, 2), Vector2D.of(2, 1), TEST_PRECISION);
        Line d = Line.fromPointAndDirection(Vector2D.of(0, -1), Vector2D.of(2, 1), TEST_PRECISION);

        // act/assert
        Assert.assertNull(a.intersection(b));
        Assert.assertNull(b.intersection(a));

        Assert.assertNull(c.intersection(d));
        Assert.assertNull(d.intersection(c));
    }

    @Test
    public void testIntersection_coincident() {
        // arrange
        Line a = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line b = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);

        Line c = Line.fromPointAndDirection(Vector2D.of(0, 2), Vector2D.of(2, 1), TEST_PRECISION);
        Line d = Line.fromPointAndDirection(Vector2D.of(0, 2), Vector2D.of(2, 1), TEST_PRECISION);

        // act/assert
        Assert.assertNull(a.intersection(b));
        Assert.assertNull(b.intersection(a));

        Assert.assertNull(c.intersection(d));
        Assert.assertNull(d.intersection(c));
    }

    @Test
    public void testAngle() {
        // arrange
        Line a = Line.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
        Line b = Line.fromPointAndAngle(Vector2D.of(1, 4), PlaneAngleRadians.PI, TEST_PRECISION);
        Line c = Line.fromPointAndDirection(Vector2D.of(1, 1), Vector2D.of(2, 2), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(0.0, a.angle(a), TEST_EPS);
        Assert.assertEquals(-PlaneAngleRadians.PI, a.angle(b), TEST_EPS);
        Assert.assertEquals(0.25 * PlaneAngleRadians.PI, a.angle(c), TEST_EPS);

        Assert.assertEquals(0.0, b.angle(b), TEST_EPS);
        Assert.assertEquals(-PlaneAngleRadians.PI, b.angle(a), TEST_EPS);
        Assert.assertEquals(-0.75 * PlaneAngleRadians.PI, b.angle(c), TEST_EPS);

        Assert.assertEquals(0.0, c.angle(c), TEST_EPS);
        Assert.assertEquals(-0.25 * PlaneAngleRadians.PI, c.angle(a), TEST_EPS);
        Assert.assertEquals(0.75 * PlaneAngleRadians.PI, c.angle(b), TEST_EPS);
    }

    @Test
    public void testProject() {
        // --- arrange
        Line xAxis = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line yAxis = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_Y, TEST_PRECISION);

        double diagonalYIntercept = 1;
        Vector2D diagonalDir = Vector2D.of(1, 2);
        Line diagonal = Line.fromPointAndDirection(Vector2D.of(0, diagonalYIntercept), diagonalDir, TEST_PRECISION);

        EuclideanTestUtils.permute(-5, 5, 0.5, (x, y) -> {
            Vector2D pt = Vector2D.of(x, y);

            // --- act/assert
            EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(x, 0), xAxis.project(pt), TEST_EPS);
            EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, y), yAxis.project(pt), TEST_EPS);

            Vector2D diagonalPt = diagonal.project(pt);
            Assert.assertTrue(diagonal.contains(diagonalPt));
            Assert.assertEquals(diagonal.distance(pt), pt.distance(diagonalPt), TEST_EPS);

            // check that y = mx + b is true
            Assert.assertEquals(diagonalPt.getY(),
                    (diagonalDir.getY() * diagonalPt.getX() / diagonalDir.getX()) + diagonalYIntercept, TEST_EPS);
        });
    }

    @Test
    public void testSpan() {
        // arrange
        Line line = Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);

        // act
        Segment result = line.span();

        // assert
        Assert.assertSame(line, result.getHyperplane());
        GeometryTestUtils.assertPositiveInfinity(result.getSize());
    }

    @Test
    public void testSegment_interval() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);
        Interval interval = Interval.of(1, 2, TEST_PRECISION);

        // act
        Segment segment = line.segment(interval);

        // assert
        Assert.assertSame(line, segment.getLine());
        Assert.assertSame(interval, segment.getSubspaceRegion());
    }

    @Test
    public void testSegment_doubles() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);

        // act
        Segment segment = line.segment(1, 2);

        // assert
        Assert.assertSame(line, segment.getLine());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), segment.getStartPoint(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 1), segment.getEndPoint(), TEST_EPS);
    }

    @Test
    public void testSegment_pointsOnLine() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);

        // act
        Segment segment = line.segment(Vector2D.of(3, 1), Vector2D.of(2, 1));

        // assert
        Assert.assertSame(line, segment.getLine());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 1), segment.getStartPoint(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 1), segment.getEndPoint(), TEST_EPS);
    }

    @Test
    public void testSegment_pointsProjectedOnLine() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);

        // act
        Segment segment = line.segment(Vector2D.of(-3, 2), Vector2D.of(2, -1));

        // assert
        Assert.assertSame(line, segment.getLine());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), segment.getStartPoint(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 1), segment.getEndPoint(), TEST_EPS);
    }

    @Test
    public void testSegmentTo_pointOnLine() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), PlaneAngleRadians.PI, TEST_PRECISION);

        // act
        Segment segment = line.segmentTo(Vector2D.of(-3, 1));

        // assert
        Assert.assertSame(line, segment.getLine());
        Assert.assertTrue(segment.isInfinite());
        Assert.assertNull(segment.getStartPoint());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), segment.getEndPoint(), TEST_EPS);

        Assert.assertTrue(segment.contains(Vector2D.of(1, 1)));
        Assert.assertFalse(segment.contains(Vector2D.of(-4, 1)));
    }

    @Test
    public void testSegmentTo_pointProjectedOnLine() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), PlaneAngleRadians.PI, TEST_PRECISION);

        // act
        Segment segment = line.segmentTo(Vector2D.of(-3, 5));

        // assert
        Assert.assertSame(line, segment.getLine());
        Assert.assertTrue(segment.isInfinite());
        Assert.assertNull(segment.getStartPoint());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), segment.getEndPoint(), TEST_EPS);

        Assert.assertTrue(segment.contains(Vector2D.of(1, 1)));
        Assert.assertFalse(segment.contains(Vector2D.of(-4, 1)));
    }

    @Test
    public void testSegmentFrom_pointOnLine() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), PlaneAngleRadians.PI, TEST_PRECISION);

        // act
        Segment segment = line.segmentFrom(Vector2D.of(-3, 1));

        // assert
        Assert.assertSame(line, segment.getLine());
        Assert.assertTrue(segment.isInfinite());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), segment.getStartPoint(), TEST_EPS);
        Assert.assertNull(segment.getEndPoint());

        Assert.assertFalse(segment.contains(Vector2D.of(1, 1)));
        Assert.assertTrue(segment.contains(Vector2D.of(-4, 1)));
    }

    @Test
    public void testSegmentFrom_pointProjectedOnLine() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), PlaneAngleRadians.PI, TEST_PRECISION);

        // act
        Segment segment = line.segmentFrom(Vector2D.of(-3, 5));

        // assert
        Assert.assertSame(line, segment.getLine());
        Assert.assertTrue(segment.isInfinite());
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), segment.getStartPoint(), TEST_EPS);
        Assert.assertNull(segment.getEndPoint());

        Assert.assertFalse(segment.contains(Vector2D.of(1, 1)));
        Assert.assertTrue(segment.contains(Vector2D.of(-4, 1)));
    }

    @Test
    public void testSubline() {
        // arrange
        Line line = Line.fromPointAndAngle(Vector2D.of(0, 1), 0.0, TEST_PRECISION);

        // act
        SubLine subline = line.subline();

        // assert
        Assert.assertSame(line, subline.getLine());
        Assert.assertTrue(subline.isEmpty());
    }

    @Test
    public void testOffset_parallelLines() {
        // arrange
        double dist = Math.sin(Math.atan2(2, 1));

        Line a = Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 4), TEST_PRECISION);
        Line b = Line.fromPoints(Vector2D.of(-3, 0), Vector2D.of(0, 6), TEST_PRECISION);
        Line c = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Line d = Line.fromPoints(Vector2D.of(1, 0), Vector2D.of(0, -2), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(-dist, a.offset(b), TEST_EPS);
        Assert.assertEquals(dist, b.offset(a), TEST_EPS);

        Assert.assertEquals(dist, a.offset(c), TEST_EPS);
        Assert.assertEquals(-dist, c.offset(a), TEST_EPS);

        Assert.assertEquals(3 * dist, a.offset(d), TEST_EPS);
        Assert.assertEquals(3 * dist, d.offset(a), TEST_EPS);
    }

    @Test
    public void testOffset_coincidentLines() {
        // arrange
        Line a = Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 4), TEST_PRECISION);
        Line b = Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 4), TEST_PRECISION);
        Line c = b.reverse();

        // act/assert
        Assert.assertEquals(0, a.offset(a), TEST_EPS);

        Assert.assertEquals(0, a.offset(b), TEST_EPS);
        Assert.assertEquals(0, b.offset(a), TEST_EPS);

        Assert.assertEquals(0, a.offset(c), TEST_EPS);
        Assert.assertEquals(0, c.offset(a), TEST_EPS);
    }

    @Test
    public void testOffset_nonParallelLines() {
        // arrange
        Line a = Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line b = Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_Y, TEST_PRECISION);
        Line c = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Line d = Line.fromPoints(Vector2D.of(1, 0), Vector2D.of(0, 4), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(0, a.offset(b), TEST_EPS);
        Assert.assertEquals(0, b.offset(a), TEST_EPS);

        Assert.assertEquals(0, a.offset(c), TEST_EPS);
        Assert.assertEquals(0, c.offset(a), TEST_EPS);

        Assert.assertEquals(0, a.offset(d), TEST_EPS);
        Assert.assertEquals(0, d.offset(a), TEST_EPS);
    }

    @Test
    public void testOffset_point() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Line reversed = line.reverse();

        // act/assert
        Assert.assertEquals(0.0, line.offset(Vector2D.of(-0.5, 1)), TEST_EPS);
        Assert.assertEquals(0.0, line.offset(Vector2D.of(-1.5, -1)), TEST_EPS);
        Assert.assertEquals(0.0, line.offset(Vector2D.of(0.5, 3)), TEST_EPS);

        double d = Math.sin(Math.atan2(2, 1));

        Assert.assertEquals(d, line.offset(Vector2D.ZERO), TEST_EPS);
        Assert.assertEquals(-d, line.offset(Vector2D.of(-1, 2)), TEST_EPS);

        Assert.assertEquals(-d, reversed.offset(Vector2D.ZERO), TEST_EPS);
        Assert.assertEquals(d, reversed.offset(Vector2D.of(-1, 2)), TEST_EPS);
    }

    @Test
    public void testOffset_point_permute() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Vector2D lineOrigin = line.getOrigin();

        EuclideanTestUtils.permute(-5, 5, 0.5, (x, y) -> {
            Vector2D pt = Vector2D.of(x, y);

            // act
            double offset = line.offset(pt);

            // arrange
            Vector2D vec = lineOrigin.vectorTo(pt).reject(line.getDirection());
            double dot = vec.dot(line.getOffsetDirection());
            double expected = Math.signum(dot) * vec.norm();

            Assert.assertEquals(expected, offset, TEST_EPS);
        });
    }

    @Test
    public void testSimilarOrientation() {
        // arrange
        Line a = Line.fromPointAndAngle(Vector2D.ZERO, 0.0, TEST_PRECISION);
        Line b = Line.fromPointAndAngle(Vector2D.of(4, 5), 0.0, TEST_PRECISION);
        Line c = Line.fromPointAndAngle(Vector2D.of(-1, -3), 0.4 * PlaneAngleRadians.PI, TEST_PRECISION);
        Line d = Line.fromPointAndAngle(Vector2D.of(1, 0), -0.4 * PlaneAngleRadians.PI, TEST_PRECISION);

        Line e = Line.fromPointAndAngle(Vector2D.of(6, -3), PlaneAngleRadians.PI, TEST_PRECISION);
        Line f = Line.fromPointAndAngle(Vector2D.of(8, 5), 0.8 * PlaneAngleRadians.PI, TEST_PRECISION);
        Line g = Line.fromPointAndAngle(Vector2D.of(6, -3), -0.8 * PlaneAngleRadians.PI, TEST_PRECISION);

        // act/assert
        Assert.assertTrue(a.similarOrientation(a));
        Assert.assertTrue(a.similarOrientation(b));
        Assert.assertTrue(b.similarOrientation(a));
        Assert.assertTrue(a.similarOrientation(c));
        Assert.assertTrue(c.similarOrientation(a));
        Assert.assertTrue(a.similarOrientation(d));
        Assert.assertTrue(d.similarOrientation(a));

        Assert.assertFalse(c.similarOrientation(d));
        Assert.assertFalse(d.similarOrientation(c));

        Assert.assertTrue(e.similarOrientation(f));
        Assert.assertTrue(f.similarOrientation(e));
        Assert.assertTrue(e.similarOrientation(g));
        Assert.assertTrue(g.similarOrientation(e));

        Assert.assertFalse(a.similarOrientation(e));
        Assert.assertFalse(e.similarOrientation(a));
    }

    @Test
    public void testSimilarOrientation_orthogonal() {
        // arrange
        Line a = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line b = Line.fromPointAndDirection(Vector2D.of(4, 5), Vector2D.Unit.PLUS_Y, TEST_PRECISION);
        Line c = Line.fromPointAndDirection(Vector2D.of(-4, -5), Vector2D.Unit.MINUS_Y, TEST_PRECISION);

        // act/assert
        Assert.assertTrue(a.similarOrientation(b));
        Assert.assertTrue(b.similarOrientation(a));
        Assert.assertTrue(a.similarOrientation(c));
        Assert.assertTrue(c.similarOrientation(a));
    }

    @Test
    public void testDistance_parallelLines() {
        // arrange
        double dist = Math.sin(Math.atan2(2, 1));

        Line a = Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 4), TEST_PRECISION);
        Line b = Line.fromPoints(Vector2D.of(-3, 0), Vector2D.of(0, 6), TEST_PRECISION);
        Line c = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Line d = Line.fromPoints(Vector2D.of(1, 0), Vector2D.of(0, -2), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(dist, a.distance(b), TEST_EPS);
        Assert.assertEquals(dist, b.distance(a), TEST_EPS);

        Assert.assertEquals(dist, a.distance(c), TEST_EPS);
        Assert.assertEquals(dist, c.distance(a), TEST_EPS);

        Assert.assertEquals(3 * dist, a.distance(d), TEST_EPS);
        Assert.assertEquals(3 * dist, d.distance(a), TEST_EPS);
    }

    @Test
    public void testDistance_coincidentLines() {
        // arrange
        Line a = Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 4), TEST_PRECISION);
        Line b = Line.fromPoints(Vector2D.of(-2, 0), Vector2D.of(0, 4), TEST_PRECISION);
        Line c = b.reverse();

        // act/assert
        Assert.assertEquals(0, a.distance(a), TEST_EPS);

        Assert.assertEquals(0, a.distance(b), TEST_EPS);
        Assert.assertEquals(0, b.distance(a), TEST_EPS);

        Assert.assertEquals(0, a.distance(c), TEST_EPS);
        Assert.assertEquals(0, c.distance(a), TEST_EPS);
    }

    @Test
    public void testDistance_nonParallelLines() {
        // arrange
        Line a = Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line b = Line.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_Y, TEST_PRECISION);
        Line c = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Line d = Line.fromPoints(Vector2D.of(1, 0), Vector2D.of(0, 4), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(0, a.distance(b), TEST_EPS);
        Assert.assertEquals(0, b.distance(a), TEST_EPS);

        Assert.assertEquals(0, a.distance(c), TEST_EPS);
        Assert.assertEquals(0, c.distance(a), TEST_EPS);

        Assert.assertEquals(0, a.distance(d), TEST_EPS);
        Assert.assertEquals(0, d.distance(a), TEST_EPS);
    }

    @Test
    public void testDistance() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(2, 1), Vector2D.of(-2, -2), TEST_PRECISION);

        // act/assert
        Assert.assertEquals(0, line.distance(line.getOrigin()), TEST_EPS);
        Assert.assertEquals(+5.0, line.distance(Vector2D.of(5, -3)), TEST_EPS);
        Assert.assertEquals(+5.0, line.distance(Vector2D.of(-5, 2)), TEST_EPS);
    }

    @Test
    public void testPointAt() {
        // arrange
        Vector2D origin = Vector2D.of(-1, 1);
        double d = Math.sqrt(2);
        Line line = Line.fromPointAndDirection(origin, Vector2D.of(1, 1), TEST_PRECISION);

        // act/assert
        EuclideanTestUtils.assertCoordinatesEqual(origin, line.pointAt(0, 0), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, line.pointAt(0, d), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, 2), line.pointAt(0, -d), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-2, 0), line.pointAt(-d, 0), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2), line.pointAt(d, 0), TEST_EPS);

        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 1), line.pointAt(d, d), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(-3, 1), line.pointAt(-d, -d), TEST_EPS);
    }

    @Test
    public void testPointAt_abscissaOffsetRoundtrip() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(2, 1), Vector2D.of(-2, -2), TEST_PRECISION);

        for (double abscissa = -2.0; abscissa < 2.0; abscissa += 0.2) {
            for (double offset = -2.0; offset < 2.0; offset += 0.2) {

                // act
                Vector2D point = line.pointAt(abscissa, offset);

                // assert
                Assert.assertEquals(abscissa, line.toSubspace(point).getX(), TEST_EPS);
                Assert.assertEquals(offset, line.offset(point), TEST_EPS);
            }
        }
    }

    @Test
    public void testContains_line() {
        // arrange
        Vector2D pt = Vector2D.of(1, 2);
        Vector2D dir = Vector2D.of(3, 7);
        Line a = Line.fromPointAndDirection(pt, dir, TEST_PRECISION);
        Line b = Line.fromPointAndDirection(Vector2D.of(0, -4), dir, TEST_PRECISION);
        Line c = Line.fromPointAndDirection(Vector2D.of(-2, -2), dir.negate(), TEST_PRECISION);
        Line d = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);

        Line e = Line.fromPointAndDirection(pt, dir, TEST_PRECISION);
        Line f = Line.fromPointAndDirection(pt, dir.negate(), TEST_PRECISION);

        // act/assert
        Assert.assertTrue(a.contains(a));

        Assert.assertTrue(a.contains(e));
        Assert.assertTrue(e.contains(a));

        Assert.assertTrue(a.contains(f));
        Assert.assertTrue(f.contains(a));

        Assert.assertFalse(a.contains(b));
        Assert.assertFalse(a.contains(c));
        Assert.assertFalse(a.contains(d));
    }

    @Test
    public void testIsParallel_closeToEpsilon() {
        // arrange
        double eps = 1e-3;
        DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(eps);

        Vector2D p = Vector2D.of(1, 2);

        Line line = Line.fromPointAndAngle(p, 0.0, precision);

        // act/assert
        Vector2D offset1 = Vector2D.of(0, 1e-4);
        Vector2D offset2 = Vector2D.of(0, 2e-3);

        Assert.assertTrue(line.contains(Line.fromPointAndAngle(p.add(offset1), 0.0, precision)));
        Assert.assertTrue(line.contains(Line.fromPointAndAngle(p.subtract(offset1), 0.0, precision)));

        Assert.assertFalse(line.contains(Line.fromPointAndAngle(p.add(offset2), 0.0, precision)));
        Assert.assertFalse(line.contains(Line.fromPointAndAngle(p.subtract(offset2), 0.0, precision)));

        Assert.assertTrue(line.contains(Line.fromPointAndAngle(p, 1e-4, precision)));
        Assert.assertFalse(line.contains(Line.fromPointAndAngle(p, 1e-2, precision)));
    }

    @Test
    public void testContains_point() {
        // arrange
        Vector2D p1 = Vector2D.of(-1, 0);
        Vector2D p2 = Vector2D.of(0, 2);
        Line line = Line.fromPoints(p1, p2, TEST_PRECISION);

        // act/assert
        Assert.assertTrue(line.contains(p1));
        Assert.assertTrue(line.contains(p2));

        Assert.assertFalse(line.contains(Vector2D.ZERO));
        Assert.assertFalse(line.contains(Vector2D.of(100, 79)));

        Vector2D offset1 = Vector2D.of(0.1, 0);
        Vector2D offset2 = Vector2D.of(0, -0.1);
        Vector2D v;
        for (double t=-2; t<=2; t+=0.1) {
            v = p1.lerp(p2, t);

            Assert.assertTrue(line.contains(v));

            Assert.assertFalse(line.contains(v.add(offset1)));
            Assert.assertFalse(line.contains(v.add(offset2)));
        }
    }

    @Test
    public void testContains_point_closeToEpsilon() {
        // arrange
        double eps = 1e-3;
        DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(eps);

        Vector2D p1 = Vector2D.of(-1, 0);
        Vector2D p2 = Vector2D.of(0, 2);
        Vector2D mid = p1.lerp(p2, 0.5);

        Line line = Line.fromPoints(p1, p2, precision);
        Vector2D dir = line.getOffsetDirection();

        // act/assert
        Assert.assertTrue(line.contains(mid.add(dir.multiply(1e-4))));
        Assert.assertTrue(line.contains(mid.add(dir.multiply(-1e-4))));

        Assert.assertFalse(line.contains(mid.add(dir.multiply(2e-3))));
        Assert.assertFalse(line.contains(mid.add(dir.multiply(-2e-3))));
    }

    @Test
    public void testDistance_point() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Line reversed = line.reverse();

        // act/assert
        Assert.assertEquals(0.0, line.distance(Vector2D.of(-0.5, 1)), TEST_EPS);
        Assert.assertEquals(0.0, line.distance(Vector2D.of(-1.5, -1)), TEST_EPS);
        Assert.assertEquals(0.0, line.distance(Vector2D.of(0.5, 3)), TEST_EPS);

        double d = Math.sin(Math.atan2(2, 1));

        Assert.assertEquals(d, line.distance(Vector2D.ZERO), TEST_EPS);
        Assert.assertEquals(d, line.distance(Vector2D.of(-1, 2)), TEST_EPS);

        Assert.assertEquals(d, reversed.distance(Vector2D.ZERO), TEST_EPS);
        Assert.assertEquals(d, reversed.distance(Vector2D.of(-1, 2)), TEST_EPS);
    }

    @Test
    public void testDistance_point_permute() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(-1, 0), Vector2D.of(0, 2), TEST_PRECISION);
        Vector2D lineOrigin = line.getOrigin();

        EuclideanTestUtils.permute(-5, 5, 0.5, (x, y) -> {
            Vector2D pt = Vector2D.of(x, y);

            // act
            double dist = line.distance(pt);

            // arrange
            Vector2D vec = lineOrigin.vectorTo(pt).reject(line.getDirection());
            Assert.assertEquals(vec.norm(), dist, TEST_EPS);
        });
    }

    @Test
    public void testIsParallel() {
        // arrange
        Vector2D dir = Vector2D.of(3, 7);
        Line a = Line.fromPointAndDirection(Vector2D.of(1, 2), dir, TEST_PRECISION);
        Line b = Line.fromPointAndDirection(Vector2D.of(0, -4), dir, TEST_PRECISION);
        Line c = Line.fromPointAndDirection(Vector2D.of(-2, -2), dir.negate(), TEST_PRECISION);
        Line d = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);

        // act/assert
        Assert.assertTrue(a.isParallel(a));

        Assert.assertTrue(a.isParallel(b));
        Assert.assertTrue(b.isParallel(a));

        Assert.assertTrue(a.isParallel(c));
        Assert.assertTrue(c.isParallel(a));

        Assert.assertFalse(a.isParallel(d));
        Assert.assertFalse(d.isParallel(a));
    }

    @Test
    public void testIsParallel_closeToParallel() {
        // arrange
        double eps = 1e-3;
        DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(eps);

        Vector2D p1 = Vector2D.of(1, 2);
        Vector2D p2 = Vector2D.of(1, -2);

        Line line = Line.fromPointAndAngle(p1, 0.0, precision);

        // act/assert
        Assert.assertTrue(line.isParallel(Line.fromPointAndAngle(p2, 1e-4, precision)));
        Assert.assertFalse(line.isParallel(Line.fromPointAndAngle(p2, 1e-2, precision)));
    }

    @Test
    public void testTransform() {
        // arrange
        AffineTransformMatrix2D scale = AffineTransformMatrix2D.createScale(2, 3);
        AffineTransformMatrix2D reflect = AffineTransformMatrix2D.createScale(-1, 1);
        AffineTransformMatrix2D translate = AffineTransformMatrix2D.createTranslation(3, 4);
        AffineTransformMatrix2D rotate = AffineTransformMatrix2D.createRotation(PlaneAngleRadians.PI_OVER_TWO);
        AffineTransformMatrix2D rotateAroundPt = AffineTransformMatrix2D.createRotation(Vector2D.of(0, 1), PlaneAngleRadians.PI_OVER_TWO);

        Vector2D p1 = Vector2D.of(0, 1);
        Vector2D p2 = Vector2D.of(1, 0);

        Line horizontal = Line.fromPointAndDirection(p1, Vector2D.Unit.PLUS_X, TEST_PRECISION);
        Line vertical = Line.fromPointAndDirection(p2, Vector2D.Unit.PLUS_Y, TEST_PRECISION);
        Line diagonal = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);

        // act/assert
        Assert.assertSame(TEST_PRECISION, horizontal.transform(scale).getPrecision());

        checkLine(horizontal.transform(scale), Vector2D.of(0, 3), Vector2D.Unit.PLUS_X);
        checkLine(vertical.transform(scale), Vector2D.of(2, 0), Vector2D.Unit.PLUS_Y);
        checkLine(diagonal.transform(scale), Vector2D.ZERO, Vector2D.of(2, 3).normalize());

        checkLine(horizontal.transform(reflect), p1, Vector2D.Unit.MINUS_X);
        checkLine(vertical.transform(reflect), Vector2D.of(-1, 0), Vector2D.Unit.PLUS_Y);
        checkLine(diagonal.transform(reflect), Vector2D.ZERO, Vector2D.of(-1, 1).normalize());

        checkLine(horizontal.transform(translate), Vector2D.of(0, 5), Vector2D.Unit.PLUS_X);
        checkLine(vertical.transform(translate), Vector2D.of(4, 0), Vector2D.Unit.PLUS_Y);
        checkLine(diagonal.transform(translate), Vector2D.of(-0.5, 0.5), Vector2D.of(1, 1).normalize());

        checkLine(horizontal.transform(rotate), Vector2D.of(-1, 0), Vector2D.Unit.PLUS_Y);
        checkLine(vertical.transform(rotate), Vector2D.of(0, 1), Vector2D.Unit.MINUS_X);
        checkLine(diagonal.transform(rotate), Vector2D.ZERO, Vector2D.of(-1, 1).normalize());

        checkLine(horizontal.transform(rotateAroundPt), Vector2D.ZERO, Vector2D.Unit.PLUS_Y);
        checkLine(vertical.transform(rotateAroundPt), Vector2D.of(0, 2), Vector2D.Unit.MINUS_X);
        checkLine(diagonal.transform(rotateAroundPt), Vector2D.of(1, 1), Vector2D.of(-1, 1).normalize());
    }

    @Test
    public void testTransform_collapsedPoints() {
        // arrange
        AffineTransformMatrix2D scaleCollapse = AffineTransformMatrix2D.createScale(0, 1);
        Line line = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);

        // act/assert
        GeometryTestUtils.assertThrows(() -> {
            line.transform(scaleCollapse);
        }, GeometryValueException.class, "Line direction cannot be zero");
    }

    @Test
    public void testSubspaceTransform() {
        // arrange
        Line line = Line.fromPoints(Vector2D.of(1, 0), Vector2D.of(1, 1), TEST_PRECISION);

        // act/assert
        checkSubspaceTransform(line.subspaceTransform(AffineTransformMatrix2D.createScale(2, 3)),
                Vector2D.of(2, 0), Vector2D.Unit.PLUS_Y,
                Vector2D.of(2, 0), Vector2D.of(2, 3));

        checkSubspaceTransform(line.subspaceTransform(AffineTransformMatrix2D.createTranslation(2, 3)),
                Vector2D.of(3, 0), Vector2D.Unit.PLUS_Y,
                Vector2D.of(3, 3), Vector2D.of(3, 4));

        checkSubspaceTransform(line.subspaceTransform(AffineTransformMatrix2D.createRotation(PlaneAngleRadians.PI_OVER_TWO)),
                Vector2D.of(0, 1), Vector2D.Unit.MINUS_X,
                Vector2D.of(0, 1), Vector2D.of(-1, 1));
    }

    private void checkSubspaceTransform(SubspaceTransform st, Vector2D origin, Vector2D dir, Vector2D tZero, Vector2D tOne) {

        Line line = st.getLine();
        AffineTransformMatrix1D transform = st.getTransform();

        checkLine(line, origin, dir);

        EuclideanTestUtils.assertCoordinatesEqual(tZero, line.toSpace(transform.apply(Vector1D.ZERO)), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(tOne, line.toSpace(transform.apply(Vector1D.Unit.PLUS)), TEST_EPS);
    }

    @Test
    public void testSubspaceTransform_transformsPointsCorrectly() {
        // arrange
        Line line = Line.fromPointAndDirection(Vector2D.of(1, 0), Vector2D.of(1, 1), TEST_PRECISION);

        EuclideanTestUtils.permuteSkipZero(-2, 2, 0.5, (a, b) -> {
            // create a somewhat complicate transform to try to hit all of the edge cases
            AffineTransformMatrix2D transform = AffineTransformMatrix2D.createTranslation(Vector2D.of(a, b))
                    .rotate(a * b)
                    .scale(0.1, 4);

            // act
            SubspaceTransform st = line.subspaceTransform(transform);

            // assert
            for (double x=-5.0; x<=5.0; x+=1) {
                Vector1D subPt = Vector1D.of(x);
                Vector2D expected = transform.apply(line.toSpace(subPt));
                Vector2D actual = st.getLine().toSpace(
                        st.getTransform().apply(subPt));

                EuclideanTestUtils.assertCoordinatesEqual(expected, actual, TEST_EPS);
            };
        });
    }

    @Test
    public void testEq() {
        // arrange
        DoublePrecisionContext precision1 = new EpsilonDoublePrecisionContext(1e-3);
        DoublePrecisionContext precision2 = new EpsilonDoublePrecisionContext(1e-2);

        Vector2D p = Vector2D.of(1, 2);
        double angle = 1.0;

        Line a = Line.fromPointAndAngle(p, angle, precision1);
        Line b = Line.fromPointAndAngle(Vector2D.ZERO, angle, precision1);
        Line c = Line.fromPointAndAngle(p, angle + 1.0, precision1);
        Line d = Line.fromPointAndAngle(p, angle, precision2);

        Line e = Line.fromPointAndAngle(p, angle, precision1);
        Line f = Line.fromPointAndAngle(p.add(Vector2D.of(1e-4, 1e-4)), angle, precision1);
        Line g = Line.fromPointAndAngle(p, angle + 1e-4, precision1);

        // act/assert
        Assert.assertTrue(a.eq(a));

        Assert.assertTrue(a.eq(e));
        Assert.assertTrue(e.eq(a));

        Assert.assertTrue(a.eq(f));
        Assert.assertTrue(f.eq(a));

        Assert.assertTrue(a.eq(g));
        Assert.assertTrue(g.eq(a));

        Assert.assertFalse(a.eq(b));
        Assert.assertFalse(a.eq(c));
        Assert.assertFalse(a.eq(d));
    }

    @Test
    public void testHashCode() {
        // arrange
        DoublePrecisionContext precision1 = new EpsilonDoublePrecisionContext(1e-4);
        DoublePrecisionContext precision2 = new EpsilonDoublePrecisionContext(1e-5);

        Vector2D p = Vector2D.of(1, 2);
        Vector2D v = Vector2D.of(1, 1);

        Line a = Line.fromPointAndDirection(p, v, precision1);
        Line b = Line.fromPointAndDirection(Vector2D.ZERO, v, precision1);
        Line c = Line.fromPointAndDirection(p, v.negate(), precision1);
        Line d = Line.fromPointAndDirection(p, v, precision2);
        Line e = Line.fromPointAndDirection(p, v, precision1);

        // act/assert
        int aHash = a.hashCode();

        Assert.assertEquals(aHash, a.hashCode());
        Assert.assertEquals(aHash, e.hashCode());

        Assert.assertNotEquals(aHash, b.hashCode());
        Assert.assertNotEquals(aHash, c.hashCode());
        Assert.assertNotEquals(aHash, d.hashCode());
    }

    @Test
    public void testEquals() {
     // arrange
        DoublePrecisionContext precision1 = new EpsilonDoublePrecisionContext(1e-4);
        DoublePrecisionContext precision2 = new EpsilonDoublePrecisionContext(1e-5);

        Vector2D p = Vector2D.of(1, 2);
        Vector2D v = Vector2D.of(1, 1);

        Line a = Line.fromPointAndDirection(p, v, precision1);
        Line b = Line.fromPointAndDirection(Vector2D.ZERO, v, precision1);
        Line c = Line.fromPointAndDirection(p, v.negate(), precision1);
        Line d = Line.fromPointAndDirection(p, v, precision2);
        Line e = Line.fromPointAndDirection(p, v, precision1);

        // act/assert
        Assert.assertTrue(a.equals(a));
        Assert.assertTrue(a.equals(e));
        Assert.assertTrue(e.equals(a));

        Assert.assertFalse(a.equals(null));
        Assert.assertFalse(a.equals(new Object()));

        Assert.assertFalse(a.equals(b));
        Assert.assertFalse(a.equals(c));
        Assert.assertFalse(a.equals(d));
    }

    @Test
    public void testToString() {
        // arrange
        Line line = Line.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);

        // act
        String str = line.toString();

        // assert
        Assert.assertTrue(str.contains("Line"));
        Assert.assertTrue(str.contains("origin= (0.0, 0.0)"));
        Assert.assertTrue(str.contains("direction= (1.0, 0.0)"));
    }

    /**
     * Check that the line has the given defining properties.
     * @param line
     * @param origin
     * @param dir
     */
    private void checkLine(Line line, Vector2D origin, Vector2D dir) {
        EuclideanTestUtils.assertCoordinatesEqual(origin, line.getOrigin(), TEST_EPS);
        EuclideanTestUtils.assertCoordinatesEqual(dir, line.getDirection(), TEST_EPS);
    }
}
