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