#include"Point.h" #include static Point As,Bs,Cs,Ds; // 変形元 static Point Ad,Bd,Cd,Dd; // 変形先 static bool g_src=false,g_dst=false; // フラグ // 変形元の座標を設定する // 引数:左回りの頂点座標 void SetSrcPoint(Point A,Point B,Point C,Point D) { As=A; Bs=B; Cs=C; Ds=D; g_src=true; } // 変形先の座標を設定する // 引数:左回りの頂点座標 void SetDstPoint(Point A,Point B,Point C,Point D) { Ad=A; Bd=B; Cd=C; Dd=D; g_dst=true; } // 座標から比率を求める // double &s:横の比率 / double &t:縦の比率 // bool leftTurn:参照点は左回りか // 戻り値:解を得られたか static bool PointToRatio(Point P,double &s,double &t,bool leftTurn) { // s と t の二次方程式を解く Point a=Cs-Ds-Bs+As; Point b=Ds-As; Point c=Bs-As; Point d=P-As; double da=(a.x * c.y)-(c.x * a.y); double db=(d.x * a.y)-(c.x * b.y)+(b.x * c.y)-(a.x * d.y); double dc=(d.x * b.y)-(b.x * d.y); if(da==0) // D==0 { if(db==0) t=0; else t=-1.0*dc/db; if((a.x * t)+b.x == 0) s=0; else s=(d.x-(c.x * t))/((a.x * t)+b.x); return true; } double D=db*db-4*da*dc; // 判別式 if(D<0) // 虚数解 { s=0; t=0; return false; } double dd=sqrt(D); // 解の公式より if(da==0) t=0; else { if(leftTurn) t=(-db+dd)/(2.0*da); else t=(-db-dd)/(2.0*da); } if((a.x * t)+b.x == 0) s=0; else s=(d.x-(c.x * t))/((a.x * t)+b.x); return true; } // 比率から座標を求める // double s:横の比率 / double t:縦の比率 // 戻り値:変形先の座標 static Point RatioToPoint(double s,double t) { Point G=Ad+t*(Bd-Ad); Point H=Dd+t*(Cd-Dd); return G+s*(H-G); } // 比率による自由変形 // Point pt:変形元の座標 // bool leftTurn:参照点は左回りか // 戻り値:変形先の座標 Point TransformRatio(Point pt,bool leftTurn) { if(g_src==false || g_dst==false) return Point(-1,-1); // 変形元または変形先の座標を設定していない double s,t; if(PointToRatio(pt,s,t,leftTurn)) { return RatioToPoint(s,t); } return Point(-1,-1); // 虚数解 }