00001 #include <math.h>
00002 #include "image.h"
00003 #include "aux.h"
00004 #include "line.h"
00005 #include "runtime.h"
00006
00007 Value * Runtime::straighten(Value * image, Value * line)
00008 {
00009
00010 if (image==NULL) return NULL;
00011 if (line==NULL) return NULL;
00012 if (typeid(*image)!=typeid(ImageValue)) return NULL;
00013 if (typeid(*line)!=typeid(LineValue)) return NULL;
00014 ImageValue * I = (ImageValue*)image;
00015 LineValue * l = (LineValue*)line;
00016
00017
00018
00019
00020
00021 DirectPoint A = I->ocsToDcs(l->a);
00022 DirectPoint B = I->ocsToDcs(l->b);
00023 double da = B.x - A.x;
00024 double db = B.y - A.y;
00025 double angle = atan2(db,da);
00026 while(angle<0) angle+=2*M_PI;
00027 while(angle>=M_PI/4) angle-=M_PI/2;
00028
00029
00030 int as = I->width_direct();
00031 int bs = I->height_direct();
00032 double cas = (double)as/2.0;
00033 double cbs = (double)bs/2.0;
00034
00035 int tl_x, tl_y;
00036 int tr_x, tr_y;
00037 int bl_x, bl_y;
00038 int br_x, br_y;
00039 rotate(0, 0, cas,cbs,tl_x,tl_y,-angle);
00040 rotate(as,0, cas,cbs,tr_x,tr_y,-angle);
00041 rotate(0, bs,cas,cbs,bl_x,bl_y,-angle);
00042 rotate(as,bs,cas,cbs,br_x,br_y,-angle);
00043 int xs = max(tr_x,br_x)-min(tl_x,bl_x);
00044 int ys = max(br_y,bl_y)-min(tl_y,tr_y);
00045
00046 ImageValue *O=new ImageValue(xs,ys,I->channelcount());
00047 O->clear(I->maxz());
00048
00049 double cxs = (double)xs/2.0;
00050 double cys = (double)ys/2.0;
00051 for(int x = 0 ; x < xs ; x++)
00052 for(int y = 0 ; y < ys ; y++)
00053 {
00054 int a,b;
00055 rotate(x-cxs,y-cys,0,0,a,b,angle);
00056 a+=cas;
00057 b+=cbs;
00058 if (a<0) continue;
00059 if (a>=as) continue;
00060 if (b<0) continue;
00061 if (b>=bs) continue;
00062 for(int c = 0 ; c < I->channelcount();c++)
00063 O->set_direct(x,y,c,I->get_direct(a,b,c));
00064 }
00065
00066
00067 PointValue new_center;
00068 rotate(I->center.x-cas,I->center.y-cbs,0,0,
00069 new_center.x,new_center.y,-angle);
00070
00071 O->center.x = new_center.x + cxs;
00072 O->center.y = new_center.y + cys;
00073
00074
00075 return O;
00076 }
00077
00078 Value * Runtime::straighten(vector<Value*> v)
00079 {
00080 if (v.size()!=2) return NULL;
00081 return straighten(v[0],v[1]);
00082 }
00083