2015年ALPC暑期专题练习I (计算几何) D Intersecting Lines

来源:互联网 发布:淘宝做外宣技巧 编辑:程序博客网 时间:2024/05/17 23:40

重载了减号(-),果然写代码舒服多了,这个poing类可以作为 模板。

求两条线段所在直线的交点,采用叉积法如下:

设C(x1,y1),D(x2,y2),交点为O(x,y),hc=ACxAB,hd=ADxAB。

如果为红线情况od/oc=hd/hc,将ocd投影到x轴,(x-x2)/(x-x1)=hd/hc,得x=(hc*x2-hd*x1)/(hc-hd)。同理y=(hc*y2-hd*y1)/(hc-hd)。

经检查可知,其他情况同样可以由上述公式得到。


输出两条直线的交点时,竟然出现负零(-0.00)的情况,第一次遇到这种错误。

#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<string>#include<map>#include<set>#include<algorithm>#include<vector>#include<sstream>using namespace std;/**********************************************************///template<class T>struct point{  int x,y;  point (int i,int j){x=i;y=j;}//普通构造函数  point (const point& p){x=p.x;y=p.y;}//拷贝构造函数  point& operator = (const point& p){//重载=    x=p.x;y=p.y;    return *this;  }  point operator - (const point& p){//重载-,b-a => b.-(a) 即线段abreturn point (p.x-x,p.y-y);  }  point (){}};const int MAX_NUM = 1000+10;int coord[4][2];double intersection[2];int CrossMuti (point a,point b){return a.x*b.y-a.y*b.x;}int JudgeLine (point& a,point& b,point& c,point& d){  point ab = b-a;  point ac = c-a;  point ad = d-a;  int hc = CrossMuti (ac,ab);  int hd = CrossMuti (ad,ab);  if (hc==0&&hd==0)return 0;  else if (hc==hd)return 1;  else{intersection[0] = (double) (hc*d.x-hd*c.x)/(hc-hd);intersection[1] = (double) (hc*d.y-hd*c.y)/(hc-hd);for (int i=0;i<2;i++)  if (intersection[i]==-0.0)intersection[i]=0.0;return 2;  }}/**********************************************************/int main(){  int n;  scanf ("%d",&n);  point pset[4];  printf ("INTERSECTING LINES OUTPUT\n");  while (n--)  {for (int i=0;i<4;i++)  scanf ("%d %d",&pset[i].x,&pset[i].y);switch( JudgeLine(pset[0],pset[1],pset[2],pset[3]) ){case 0 :  printf ("LINE\n");  break;case 1 :  printf ("NONE\n");  break;case 2 :  printf ("POINT %.2lf %.2lf\n",intersection[0],intersection[1]);  break;default:  printf ("error\n");  break;}   }  printf ("END OF OUTPUT\n");  return 0;}


0 0