Affine Mess
		
		
		
		Jump to navigation
		Jump to search
		
Only 6 ways the two points could map to each other and only 44 possible rotations, So we'll try all of them and see if we can find a mapping.
- select a rotation
- perform rotation and snap to grid
- select a mapping between the points
- scale so that one of the edges is the same length between the known and trial image
- translate so that some point between both images that we selected as mapping to eachother are in the same place
- check whether all the points are the same between the two images
- consistent if all matches use the same mapping between points
- inconsistent if there are matches using distinct mappings
import java.awt.Point;
import java.util.*;
public class b {
	Scanner in=new Scanner(System.in);
	public static void main(String[] args) {
		new b().go();
	}
	Point found;
	boolean any=false,cons=true;
	private void go() {
		int cnum=0;
		while(true){
			cnum++;
			any=false;
			cons=true;
			found=null;
			ArrayList<Point> a=new ArrayList<Point>();
			for(int i=0;i<3;i++)a.add(new Point(in.nextInt(),in.nextInt()));
			ArrayList<Point> master=new ArrayList<Point>(a);
			if(a.get(1).equals(new Point(0,0))&&a.get(0).equals(new Point(0,0)))break;
			ArrayList<Point> b=new ArrayList<Point>();
			for(int i=0;i<3;i++)b.add(new Point(in.nextInt(),in.nextInt()));
			for(int yrot=-10;yrot<=10;yrot++){//all 44 rotations
				doit(a, master, b, 10, yrot);
				if(Math.abs(yrot)!=10)doit(a, master, b, yrot, 10);
			}
			System.out.printf("Case %d: ", cnum);
			if(any&&cons)System.out.println("equivalent solutions");
			if(any&&!cons)System.out.println("inconsistent solutions");
			if(!any)System.out.println("no solution");
		}
	}
	private void doit(ArrayList<Point> a, ArrayList<Point> master,ArrayList<Point> b, int xrot, int yrot) {
		for(int i=0;i<3;i++){
			double theta=Math.atan2(yrot, xrot)+Math.atan2(master.get(i).y, master.get(i).x);
			double dist=Math.sqrt(Math.pow(master.get(i).x, 2)+Math.pow(master.get(i).y, 2));
			a.set(i, new Point((int)Math.round(dist*Math.cos(theta)+Math.signum(dist*Math.cos(theta))*.00000001),(int)Math.round(dist*Math.sin(theta)+Math.signum(dist*Math.sin(theta))*.0000001)));
		}
		boolean foundprev=false;
		for(int i=0;i<6;i++){
			ArrayList<Point> c=new ArrayList<Point>();
			for(Point p:a)c.add(new Point(p));
			for(Point p:c){
				p.x+=b.get(0).x-a.get(0).x;
				p.y+=b.get(0).y-a.get(0).y;
			}
			int xscale,yscale;
			if(c.get(1).x!=c.get(0).x){
				xscale=(b.get(1).x-b.get(0).x)/(c.get(1).x-c.get(0).x);
			}else{
				if(c.get(2).x!=c.get(0).x){
					xscale=(b.get(2).x-b.get(0).x)/(c.get(2).x-c.get(0).x);
				}
				else xscale=Integer.MAX_VALUE;
			}
			if(c.get(1).y!=c.get(0).y){
				yscale=(b.get(1).y-b.get(0).y)/(c.get(1).y-c.get(0).y);
			}else{
				if(c.get(2).y!=c.get(0).y){
					yscale=(b.get(2).y-b.get(0).y)/(c.get(2).y-c.get(0).y);
				}
				else yscale=Integer.MAX_VALUE;
			}
			if(!(xscale==0||yscale==0||c.get(0).x+(c.get(1).x-c.get(0).x)*xscale!=b.get(1).x||c.get(0).x+(c.get(2).x-c.get(0).x)*xscale!=b.get(2).x||c.get(0).y+(c.get(1).y-c.get(0).y)*yscale!=b.get(1).y||c.get(0).y+(c.get(2).y-c.get(0).y)*yscale!=b.get(2).y)){//match found
				any=true;
				if(found==null)found=new Point(xrot,yrot);
				if(foundprev||xscale==Integer.MAX_VALUE||yscale==Integer.MAX_VALUE||!(new Point(xrot,yrot).equals(found)))cons=false;
				foundprev=true;
			}
			Point temp=a.get(2);
			a.set(2,a.get((i+1)%2));
			a.set((i+1)%2,temp);
		}
	}
}
//Affine Mess
//rotation
//scaling
//translation
//angles
//brute force