@Override protected boolean operateInternal(Set<Triangle> triangles) { Triangle winner = random.choice(triangles); float perfectness = new BigDecimal("2").divide(winner.perfectness(), MathContext.DECIMAL128).floatValue(); float myRate = Math.max(perfectness, rate); if (!random.rate(myRate)) { return false; } for (Triangle t : triangles) { if (t == winner) { continue; } Segment common = TriangleUtils.segmentInCommon(winner, t); if (common != null) { boolean swapped = swap(triangles, winner, t, common); return swapped; } } return false; }
public static boolean swap(Set<Triangle> triangles, Triangle a, Triangle b, Segment common) { Point otherOfA = otherOf(a, common); Point otherOfB = otherOf(b, common); Line ab = Line.defineByPoints(otherOfA, otherOfB); if (ab.distance(common.getP1()).doubleValue() < 0.001 || ab.distance(common.getP2()).doubleValue() < 0.001) { return false; } Triangle t1; Triangle t2; if (TriangleUtils.counterClockwise(otherOfA, otherOfB, common.getP1()) < 0) { t1 = new Triangle(otherOfA, otherOfB, common.getP1()); t2 = new Triangle(otherOfA, common.getP2(), otherOfB); } else { t1 = new Triangle(otherOfB, otherOfA, common.getP1()); t2 = new Triangle(otherOfB, common.getP2(), otherOfA); } BigDecimal oldArea = a.area().add(b.area(), DECIMAL128).setScale(MY_SCALE, MY_RND); BigDecimal newArea = t1.area().add(t2.area(), DECIMAL128).setScale(MY_SCALE, MY_RND); if (oldArea.compareTo(newArea) == 0) { triangles.remove(a); triangles.remove(b); triangles.add(t1); triangles.add(t2); return true; } return false; }