几何求交点
原创
©著作权归作者所有:来自51CTO博客作者胡桃小孩儿的原创作品,请联系作者获取转载授权,否则将追究法律责任
今天做了一道题(呵呵,做完我发现自己曾经做过),简直无力吐槽,为什么同一份代码G++错,而C++对,浪费我好几个小时。(不过也让我从不同的角度思考问题了)
POJ 1269 Intersecting Lines
http://poj.org/problem?id=1269
求解两条线段的关系:平行,共线,相交(求交点坐标)
分析:
AB和CD的交点是P,求之:
同理,Y:
即使是不接触相交也能用此法求之。
不过等式涉及正负号的问题(变向)
#include <cstdio>
using namespace std;
struct point{
int x,y;
}p[5];
int multi(point p0,point p1,point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int abs(int x){
return x<0?-x:x;
}
int main(){
//freopen("cin.txt","r",stdin);
int t;
scanf("%d",&t);
printf("INTERSECTING LINES OUTPUT\n");
while(t--){
for(int i=1;i<=4;i++) scanf("%d%d",&p[i].x,&p[i].y);
int r1=multi(p[3],p[4],p[1]);
int r2=multi(p[3],p[4],p[2]);
int r3=multi(p[1],p[2],p[3]);
int r4=multi(p[1],p[2],p[4]);
if(r1==0&&r2==0){
printf("LINE\n");
}
else if((p[1].x-p[2].x)*(p[3].y-p[4].y)==(p[1].y-p[2].y)*(p[3].x-p[4].x)){
printf("NONE\n");
}
else {
int M1=abs(r1),M2=abs(r2),M3=abs(r3),M4=abs(r4);
double x,y;
if(r1*r2>0){
x=(p[1].x*M2-p[2].x*M1+0.0)/(M2-M1);
y=(p[1].y*M2-p[2].y*M1+0.0)/(M2-M1);
}
else if(r3*r4>0){
x=(p[3].x*M4-p[4].x*M3+0.0)/(M4-M3);
y=(p[3].y*M4-p[4].y*M3+0.0)/(M4-M3);
}
else {
x=(p[4].x*M3+p[3].x*M4+0.0)/(M3+M4);
y=(p[4].y*M3+p[3].y*M4+0.0)/(M3+M4);
}
printf("POINT %.2lf %.2lf\n",x,y);
}
}
printf("END OF OUTPUT\n");
return 0;
}
简化:
如果一开始就直接使用multi(a,c,b)作为M1, multi(a,d,b)作为M2,那么计算过程自己就把不接触相交和接触相交的问题解决了。
求交点:
double x=(p[4].x*r3-p[3].x*r4)*1.0/(r3-r4);
double y=(p[4].y*r3-p[3].y*r4)*1.0/(r3-r4);
printf("POINT %.2lf %.2lf\n",x,y);
第二种看法:
相同的过程推出:
double x=(p[2].x*r1-p[1].x*r2)*1.0/(r2-r1);
double y=(p[2].y*r1-p[1].y*r2)*1.0/(r2-r1);
printf("POINT %.2lf %.2lf\n",-x,-y);
惭愧的是,我暂时不能解释为什么第二种看法得到结果是正确值的相反数。