EllipsoidOptimisationStrategy extends AbstractBinaryFunctionOp<byte[][], Vector3d, QuickEllipsoid> { void turn(QuickEllipsoid ellipsoid, ArrayList<double[]> contactPoints, final byte[][] pixels, final int w, final int h, final int d) { findContactPoints(ellipsoid, contactPoints, pixels, w, h, d); if (!contactPoints.isEmpty()) { final double[] torque = calculateTorque(ellipsoid, contactPoints); rotateAboutAxis(ellipsoid, norm(torque)); } }  @Override QuickEllipsoid calculate(byte[][] pixels, Vector3d seedPoint);  }
@Test public void testTurnSurfacePoint() { double[] radii = {1,2,3}; double[] centre = {0,0,0}; QuickEllipsoid e = new QuickEllipsoid(radii, centre,new double[][]{{1,0,0},{0,1,0},{0,0,1}}); final EllipsoidOptimisationStrategy optimisation = (EllipsoidOptimisationStrategy) Functions.binary(ops, EllipsoidOptimisationStrategy.class, QuickEllipsoid.class, new byte[10][10], new Vector3d(),new long[]{10,10,1}, new AnchorEllipsoidConstrain());final ArrayList<double[]> contactPoints = new ArrayList<>(); contactPoints.add(new double[]{0,0,3}); final AnchorEllipsoidConstrain anchorConstrain = new AnchorEllipsoidConstrain(); anchorConstrain.preConstrain(e, new Vector3d(1,0,0)); optimisation.turn(e,contactPoints, getCuboidImage(),6,6,6); anchorConstrain.postConstrain(e); assertTrue("Bump does not preserve surface point.",onSurface(e, new double[]{1,0,0})); }