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

重载了减号(-),果然写代码舒服多了,这个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) 即线段ab
	return 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值