计算几何初步模板

 1 // 计算几何模板 ~ alpc02
 2 const   double  PRECISION  =  1e - 8 ;
 3 struct  Point  {
 4    double x, y;
 5}
;
 6 int  dblcmp( double  d)  {
 7    return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
 8}
  // 三叉口函数,避免精度误差
 9 double  length( double  x,  double  y)  {
10    return sqrt(x*+ y*y);
11}
  // 向量长度
12 double  dotdet( double  x1,  double  y1,  double  x2,  double  y2)  {
13    return x1*x2 + y1*y2;
14}
  // 点积
15 double  det( double  x1,  double  y1,  double  x2,  double  y2)  {
16    return x1*y2 - x2*y1;
17}
  // 叉积
18 int  cross( const  Point  & a,  const  Point  & c,  const  Point  & d)  {
19    return dblcmp( det(a.x-c.x, a.y-c.y, d.x-c.x, d.y-c.y) );
20}
  // 右手螺旋定则,1——a在cd右侧,-1——a在cd左侧,0——三点共线
21 bool  between( const  Point  & a,  const  Point  & c,  const  Point  & d)  {
22    return dblcmp( dotdet(c.x-a.x, c.y-a.y, d.x-a.x, d.y-a.y) ) != 1;
23}
  // 在cross(a,c,d)==0的基础上,可判断点a是否在cd内部
24 int  segIntersect( const  Point  & a,  const  Point  & b,  const  Point  & c,  const  Point  & d)  {
25    int a_cd = cross(a,c,d);
26    if(a_cd == 0 && between(a,c,d))    return 2;
27    int b_cd = cross(b,c,d);
28    if(b_cd == 0 && between(b,c,d))    return 2;
29    int c_ab = cross(c,a,b);
30    if(c_ab == 0 && between(c,a,b))    return 2;
31    int d_ab = cross(d,a,b);
32    if(d_ab == 0 && between(d,a,b))    return 2;
33    if ((a_cd ^ b_cd) == -2 && (c_ab ^ d_ab) == -2)
34        return 1;
35    return 0;
36}
  // 两线段相交情况:0——不相交,1——规范相交,2——不规范相交(交于端点或重合)
37 void  intersectPoint( const  Point  & a,  const  Point  & b,  const  Point  & c,  const  Point  & d, Point  & e)  {
38    double sc, sd;
39    sc = fabs( det(b.x-a.x, b.y-a.y, c.x-a.x, c.y-a.y) );
40    sd = fabs( det(b.x-a.x, b.y-a.y, d.x-a.x, d.y-a.y) );
41    e.x = (sc * d.x + sd * c.x) / (sc + sd);
42    e.y = (sc * d.y + sd * c.y) / (sc + sd);
43}
  // 两线段规范相交时,求交点坐标
44 int  linesegIntersect( const  Point  & a,  const  Point  & b,  const  Point  & c,  const  Point  & d)  {
45    int c_ab = cross(c,a,b);
46    if(c_ab == 0)    return 2;
47    int d_ab = cross(d,a,b);
48    if(d_ab == 0)    return 2;
49    if(c_ab ^ d_ab == -2)
50        return 1;
51    return 0;
52}
  // 直线ab和线段cd相交情况:0——不相交,1——规范相交,2——不规范相交(交于端点或重合)
53 int  lineIntersect( const  Point  & a,  const  Point  & b,  const  Point  & c,  const  Point  & d)  {
54    if(dblcmp(det(b.x-a.x, b.y-a.y, d.x-c.x, d.y-c.y)) != 0)
55        return 1;
56    if(cross(a,c,d) == 0)
57        return 2;
58    return 0;
59}
  // 两直线相交情况:0——平行,1——规范相交,2——不规范相交(重合)
60
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值