Dot implements InnerProduct<Double> { @Override public Degrees<Double> angle(final Vect<Double> first, final Vect<Double> second) { final Double cross = Dot.val(first.coords()[0]) * Dot.val(second.coords()[1]) - Dot.val(second.coords()[0]) * Dot.val(first.coords()[1]); final Double norms = Dot.val( new Multiplication<Double>(this.norm(first), this.norm(second)) ); final Double result; if (norms == 0) { result = 0.; } else { final Double arcsin = Math.asin(cross / norms); final Double arcos = Math.acos( Dot.val(this.product(first, second)) / norms ); if (arcsin >= 0) { result = arcos; } else { result = -arcos; } } return new Degrees.Default<>(result); }  @Override Scalar<Double> product(final Vect<Double> foperand, final Vect<Double> soperand); @Override Scalar<Double> norm(final Vect<Double> vect); @Override Degrees<Double> angle(final Vect<Double> first, final Vect<Double> second); @Override Vect<Double> rot(final Vect<Double> vect, final Degrees<Double> ang);  }
@Test public void calculatesAngle() { final Vect<Double> vecta = new DblVect(1., 0.); final double pifourth = Math.PI / 4; final Dot dot = new Dot(); final double error = 1.e-6; MatcherAssert.assertThat( dot.angle(vecta, new DblVect(0., -1.)).resolve(dot).doubleValue(), Matchers.closeTo(-Math.PI / 2, error) ); MatcherAssert.assertThat( dot.angle(vecta, new DblVect(-1., 0.)).resolve(dot).doubleValue(), Matchers.closeTo(Math.PI, error) ); MatcherAssert.assertThat( dot.angle(vecta, new DblVect(0., 1.)).resolve(dot).doubleValue(), Matchers.closeTo(Math.PI / 2, error) ); MatcherAssert.assertThat( dot.angle(vecta, new DblVect(1., 1.)).resolve(dot).doubleValue(), Matchers.closeTo(pifourth, error) ); MatcherAssert.assertThat( dot.angle(vecta, new DblVect(0., 0.)).resolve(dot).doubleValue(), Matchers.closeTo(0., error) ); }