Affine Mess

From programming_contest
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.

  1. select a rotation
  2. perform rotation and snap to grid
  3. select a mapping between the points
  4. scale so that one of the edges is the same length between the known and trial image
  5. translate so that some point between both images that we selected as mapping to eachother are in the same place
  6. 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