Vector3D implements Serializable, Vector<Euclidean3D> { public Vector3D orthogonal() throws MathArithmeticException { double threshold = 0.6 * getNorm(); if (threshold == 0) { throw new MathArithmeticException(LocalizedFormats.ZERO_NORM); } if (FastMath.abs(x) <= threshold) { double inverse = 1 / FastMath.sqrt(y * y + z * z); return new Vector3D(0, inverse * z, -inverse * y); } else if (FastMath.abs(y) <= threshold) { double inverse = 1 / FastMath.sqrt(x * x + z * z); return new Vector3D(-inverse * z, 0, inverse * x); } double inverse = 1 / FastMath.sqrt(x * x + y * y); return new Vector3D(inverse * y, -inverse * x, 0); } Vector3D(double x, double y, double z);  Vector3D(double[] v);  Vector3D(double alpha, double delta);  Vector3D(double a, Vector3D u);  Vector3D(double a1, Vector3D u1, double a2, Vector3D u2);  Vector3D(double a1, Vector3D u1, double a2, Vector3D u2,
                    double a3, Vector3D u3);  Vector3D(double a1, Vector3D u1, double a2, Vector3D u2,
                    double a3, Vector3D u3, double a4, Vector3D u4); double getX(); double getY(); double getZ(); double[] toArray(); Space getSpace(); Vector3D getZero(); double getNorm1(); double getNorm(); double getNormSq(); double getNormInf(); double getAlpha(); double getDelta(); Vector3D add(final Vector<Euclidean3D> v); Vector3D add(double factor, final Vector<Euclidean3D> v); Vector3D subtract(final Vector<Euclidean3D> v); Vector3D subtract(final double factor, final Vector<Euclidean3D> v); Vector3D normalize(); Vector3D orthogonal(); static double angle(Vector3D v1, Vector3D v2); Vector3D negate(); Vector3D scalarMultiply(double a); boolean isNaN(); boolean isInfinite(); @Override boolean equals(Object other); @Override int hashCode(); double dotProduct(final Vector<Euclidean3D> v); Vector3D crossProduct(final Vector<Euclidean3D> v); double distance1(Vector<Euclidean3D> v); double distance(Vector<Euclidean3D> v); double distance(Point<Euclidean3D> v); double distanceInf(Vector<Euclidean3D> v); double distanceSq(Vector<Euclidean3D> v); static double dotProduct(Vector3D v1, Vector3D v2); static Vector3D crossProduct(final Vector3D v1, final Vector3D v2); static double distance1(Vector3D v1, Vector3D v2); static double distance(Vector3D v1, Vector3D v2); static double distanceInf(Vector3D v1, Vector3D v2); static double distanceSq(Vector3D v1, Vector3D v2); @Override String toString(); String toString(final NumberFormat format); static final Vector3D ZERO; static final Vector3D PLUS_I; static final Vector3D MINUS_I; static final Vector3D PLUS_J; static final Vector3D MINUS_J; static final Vector3D PLUS_K; static final Vector3D MINUS_K; static final Vector3D NaN; static final Vector3D POSITIVE_INFINITY; static final Vector3D NEGATIVE_INFINITY; }
@Test public void testOrthogonal() throws MathArithmeticException { Vector3D v1 = new Vector3D(0.1, 2.5, 1.3); Assert.assertEquals(0.0, Vector3D.dotProduct(v1, v1.orthogonal()), 1.0e-12); Vector3D v2 = new Vector3D(2.3, -0.003, 7.6); Assert.assertEquals(0.0, Vector3D.dotProduct(v2, v2.orthogonal()), 1.0e-12); Vector3D v3 = new Vector3D(-1.7, 1.4, 0.2); Assert.assertEquals(0.0, Vector3D.dotProduct(v3, v3.orthogonal()), 1.0e-12); Vector3D v4 = new Vector3D(4.2, 0.1, -1.8); Assert.assertEquals(0.0, Vector3D.dotProduct(v4, v4.orthogonal()), 1.0e-12); try { new Vector3D(0, 0, 0).orthogonal(); Assert.fail("an exception should have been thrown"); } catch (MathArithmeticException ae) { } }