ExecutionReport.setIntersections(toIntersections.size());
ExecutionReport.setCombinations(fromIntersections.size(), toIntersections.size());
// Point pairing tester allows detection of unpaired poins upon transformation
PointPairingTester pairTester = new PointPairingTester(subShape, shape);
ShapeModel lastFound = null;
boolean markerFound, exclusionFound;
/* create all non identical permutations of points
1. Take first transformation from subShape (has smallest angle)
2. Create second triplets
3. For each combination of points create transformation and test
*/
Matrix A = new Matrix(6, 6);
Matrix b = new Matrix(6, 1);
Matrix solution;
Matrix subsolution = new Matrix(2, 2);
Point2D transformedPoint = new Point2D.Double();
// output transform
AffineTransform outTransform = new AffineTransform();
int[] fromIndexes = new int[3];
// TODO: REDO
fromIndexes[0] = 0;
fromIndexes[1] = 1;
fromIndexes[2] = 2;
// create left matrix
// 1st row
IntersectionTriplet fromTriplet = from.getTriplet();
A.set(0, 0, from.getIntersection().getX());
A.set(0, 1, from.getIntersection().getY());
A.set(0, 2, 1);
// 2nd
A.set(1, 3, from.getIntersection().getX());
A.set(1, 4, from.getIntersection().getY());
A.set(1, 5, 1);
// 3rd
A.set(2, 0, fromTriplet.getPointA().getX());
A.set(2, 1, fromTriplet.getPointA().getY());
A.set(2, 2, 1);
// 4th
A.set(3, 3, fromTriplet.getPointA().getX());
A.set(3, 4, fromTriplet.getPointA().getY());
A.set(3, 5, 1);
// 5th
A.set(4, 0, fromTriplet.getPointB().getX());
A.set(4, 1, fromTriplet.getPointB().getY());
A.set(4, 2, 1);
// 6th
A.set(5, 3, fromTriplet.getPointB().getX());
A.set(5, 4, fromTriplet.getPointB().getY());
A.set(5, 5, 1);
// now find all intersection points in shape with same angle and ratio as original intersection
IntersectionModel to;
ArrayList<IntersectionTriplet> intersectionPairs;
IntersectionTriplet currentPair;
//Debugger.getInstance().addMessage("Init pair: " + from.getIntersection().toString() + fromTriplet.toString());
// show markers
//System.out.println("MARKERS");
for (MarkerModel model : shape.getMarkers()) {
Debugger.getInstance().addMessage(model.getLocation().toString());
}
// get itersections with the same angle
toIntersections = shape.getIntersections(from.getAngle());
ExecutionReport.setGoodIntersections(toIntersections.size());
long triplets = 0;
for (IntersectionModel intr : toIntersections) {
ArrayList<IntersectionTriplet> arr = intr.getTriplets(fromTriplet.getRatio());
if (arr != null) {
triplets += arr.size();
}
}
ExecutionReport.setTriplets(triplets);
// intersections are ordered by the angle
// we start with the smallest angle and continue to the top limit
for (int tos = 0; tos < toIntersections.size(); tos++) {
ExecutionReport.intersectionTested();
//monitor.setTaskName("Checking " + (tos + 1) + ". intersection");
if (monitor.isCanceled()) {
return subShapes;
}
// initial validation
to = toIntersections.get(tos);
Debugger.getInstance().addMessage("=================================");
Debugger.getInstance().addMessage("Intersection: " + to.getIntersection());
// // we stop if we've reached bigger angle
// if (to.getAngle() > from.getAngle()) {
// break;
// }
//
// // we continue to search for the exact angle and ratio
// if (to.getAngle() < from.getAngle()) {
// continue;
// }
// now we have an intersection with the good angle
// we will search for all points on carriers that have the same ratio as the
// initial intersection triplet
// intersection is defined by point and two carriers
intersectionPairs = to.getTriplets(fromTriplet.getRatio());
// there exist no triplets on carriers with given ratio
if (intersectionPairs == null)
continue;
// iterate for all found pairs
for (int pair = 0; pair < intersectionPairs.size(); pair++) {
ExecutionReport.tripletTested();
//monitor.subTask("Checking intersection triplets");
if (monitor.isCanceled()) {
return subShapes;
}
// get current pair
currentPair = intersectionPairs.get(pair);
Debugger.getInstance().addMessage("Pair: " + currentPair);
Debugger.getInstance().addMessage("TESTING: " + to.getIntersection().toString() + currentPair.toString());
// we test this 2 times (once when we flip pointA and pointB (symmetry))
// TODO: Test ratio .. if by flip does not change continue
for (int j = 0; j < 1; j++) {
// if (monitor.isCanceled()) {
// return subShapes;
// }
// this counter is to see how much transformations were tested
b.set(0, 0, to.getIntersection().getX());
b.set(1, 0, to.getIntersection().getY());
b.set(2, 0, j == 0 ? currentPair.getPointA().getX() : currentPair.getPointB().getX());
b.set(3, 0, j == 0 ? currentPair.getPointA().getY() : currentPair.getPointB().getY());
b.set(4, 0, j == 0 ? currentPair.getPointB().getX() : currentPair.getPointA().getX());
b.set(5, 0, j == 0 ? currentPair.getPointB().getY() : currentPair.getPointA().getY());
// create transformation by solving equation of 6 unknowns
try {
solution = A.solve(b);
}
catch (Exception ex) {
Debugger.getInstance().addMessage("Solution exception");
continue;
}
// check if it's symmetry
// first check determinant .. must be -1
subsolution.set(0, 0, solution.get(0, 0));
subsolution.set(0, 1, solution.get(1, 0));
subsolution.set(1, 0, solution.get(3, 0));
subsolution.set(1, 1, solution.get(4, 0));
// Symmetry: MathUtils.round(subsolution.det()) == -1)
// Inverse: MathUtils.isIdentity(subsolution.times(subsolution.transpose()))
if (MathUtils.round(subsolution.det()) == 0)
continue;
// we round transformations to 3 decimal places
outTransform.setTransform(
solution.get(0, 0),
solution.get(3, 0),
solution.get(1, 0),
solution.get(4, 0),
solution.get(2, 0),
solution.get(5, 0)
// MathUtils.round(solution.get(0, 0), 6),
// MathUtils.round(solution.get(3, 0), 6),
// MathUtils.round(solution.get(1, 0), 6),
// MathUtils.round(solution.get(4, 0), 6),
// MathUtils.round(solution.get(2, 0), 6),
// MathUtils.round(solution.get(5, 0), 6)
);
//Debugger.getInstance().addMessage(outTransform.toString());
// TODO : Think how can i know which other intersection points are paired
// that means .. how to pair info about information point of:
// from.pointA with to.PointA and get index in original intersection collection
// We can decide if to use to use not markers
if (useMarkers) {
//monitor.subTask("Checking marker images");
markerFound = true;
if (subShape.getMarkers().size() > 0) {
markerFound = false;
for (MarkerModel subMarker : subShape.getMarkers()) {
// first transform this marker
MarkerModel transformedMarker = new MarkerModel(subMarker.getLocation());
transformedMarker.transform(outTransform);
Debugger.getInstance().addMessage("M:" + transformedMarker.getLocation());
// now try to find this marker
for (MarkerModel marker : shape.getMarkers()) {
if (marker.compareTo(transformedMarker) == 0) {
markerFound = true;
}
}
}
}
if (!markerFound) {
Debugger.getInstance().addMessage("Marker not found");
break;
}
}
// Test remaining points
pairTester.reset();
pairTester.setPair(0, tos);
Point2D testPoint;
int testPointIndex;
boolean imageMissing = false;
// now start pairing all other intersection points to see if their images exist
//monitor.subTask("Checking point images");
while ((testPointIndex = pairTester.getFirstUnpaired()) != -1) {
// get image of point according to tranformation
testPoint = fromIntersections.get(testPointIndex).getIntersection();
// transform point and try to set pair
transformedPoint.setLocation(testPoint.getX(), testPoint.getY());
outTransform.transform(transformedPoint, transformedPoint);
if (!pairTester.setPair(testPointIndex, transformedPoint.getX(), transformedPoint.getY())) {
Debugger.getInstance().addMessage("Image not found");
imageMissing = true;
break;
}
}
if (imageMissing || !pairTester.isPaired()) {
Debugger.getInstance().addMessage("Continuing");
continue;
}
// now check this transform
//monitor.subTask("Checking line images");
ShapeModel testShape = checkTransformation(shape, subShape, new AffineTransform(outTransform));
// check if this shape can be returned and return this shape
//monitor.subTask("Checking duplicate subshape");
if (testShape == null) {
Debugger.getInstance().addMessage("Boundary not found: " + testShape);
}
if (testShape != null) {
// check if we want to exclude this transformation
if (excludeShapeList != null) {
exclusionFound = false;
for (ShapeModel excludedShape : excludeShapeList) {
if (ShapeTools.compareTransformations(excludedShape.getInitialTransform(), testShape.getInitialTransform())) {
exclusionFound = true;
break;
}
}
if (exclusionFound) {