LinePointOrdinate implements Scalar<T> { @Override public T value(final Field<T> field) { final boolean inline = field.equals( this.line.point().coords()[0], this.abscissa ); final boolean vertical = new Vertical<>(this.line).resolve(field); if (vertical && !inline) { throw new IllegalStateException( "Vertical line could not pass by a point with this abscissa" ); } final T result; if (vertical && inline) { result = field.actual(new Random<T>()); } else { result = field.actual( new Add<>( new Multiplication<T>( new Slope<T>(this.line), this.abscissa ), new Intercept<T>(this.line) ) ); } return result; } LinePointOrdinate(final Line<T> line, final Scalar<T> abscissa); @Override T value(final Field<T> field);  }
@Test public void calculatesOrdinate() { final Line<Double> line = new RandomLine<>(); final double error = 1.e-6; final Decimal dec = new Decimal(); final Scalar<Double> abscissa = new RandomPoint<Double>().xcoor(); final Double startx = line.point().coords()[0].value(dec); final Double starty = line.point().coords()[1].value(dec); final Double dirx = line.direction().coords()[0].value(dec); final Double diry = line.direction().coords()[1].value(dec); MatcherAssert.assertThat( new LinePointOrdinate<Double>(line, abscissa).value(dec), Matchers.closeTo( diry / dirx * abscissa.value(dec) + starty - startx * diry / dirx, error ) ); }
@Test public void errorsWhenVerticalLineAndOutsideAbscissa() { this.thrown.expect(IllegalStateException.class); final RandomPoint<Double> point = new RandomPoint<>(); final Line<Double> line = new VerticalLine<>(point); new LinePointOrdinate<>( line, new DifferentPoint<>(point).xcoor() ).value(new Decimal()); }
@Test public void evaluatesWhenVerticalLineAndInsideAbscissa() { final RandomPoint<Double> point = new RandomPoint<>(); final Line<Double> line = new VerticalLine<>(point); new LinePointOrdinate<>(line, point.xcoor()).value(new Decimal()); }