一些计算几何基础公式(含5题及相关模板)

一些计算几何基础公式(含5题及相关模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1086

// 判断两直线是否相交
#include < stdio.h >
#define  eps 1e-8
#define  zero(x) (((x)>0?(x):-(x))<eps)
struct  point {
    
double  x,y;
};
struct  line {
    point a,b;
}l[
101 ];
double  xmult(point p1,point p2,point p0){
    
return  (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int  dots_inline(point p1,point p2,point p3){
    
return  zero(xmult(p1,p2,p3));
}
int  same_side(point p1,point p2,line l){
    
return  xmult(l.a,p1,l.b) * xmult(l.a,p2,l.b) > eps;
}
int  dot_online_in(point p,line l){
    
return  zero(xmult(p,l.a,l.b)) && (l.a.x - p.x) * (l.b.x - p.x) < eps && (l.a.y - p.y) * (l.b.y - p.y) < eps;
}
int  intersect_in(line u,line v){
    
if  ( ! dots_inline(u.a,u.b,v.a) ||! dots_inline(u.a,u.b,v.b))
        
return   ! same_side(u.a,u.b,v) &&! same_side(v.a,v.b,u);
    
return  dot_online_in(u.a,v) || dot_online_in(u.b,v) || dot_online_in(v.a,u) || dot_online_in(v.b,u);
}
int  main()
{
    
int  n,i,j;
    
int  cnt;
    
while (scanf( " %d " , & n),n)
    {
        
for (i = 0 ;i < n;i ++ ) {
            scanf(
" %lf%lf%lf%lf " , & l[i].a.x, & l[i].a.y, & l[i].b.x, & l[i].b.y);
        }
        cnt 
=   0 ;
        
for (i = 0 ;i < n;i ++ ) {
            
for (j = i + 1 ;j < n;j ++ ) {
                cnt 
+=  intersect_in(l[i],l[j]);
            }
        }
        printf(
" %d\n " ,cnt);
    }
    
return   0 ;
}


http://acm.hdu.edu.cn/showproblem.php?pid=1115
求多边形重心
#include < stdio.h >
#include
< math.h >
#define  eps 1e-8
struct  point{
    
double  x,y;
}p[
1000001 ];
struct  line{point a,b;};

double  xmult(point p1,point p2,point p0){
    
return  (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
point intersection(line u,line v){
    point ret
= u.a;
    
double  t = ((u.a.x - v.a.x) * (v.a.y - v.b.y) - (u.a.y - v.a.y) * (v.a.x - v.b.x))
        
/ ((u.a.x - u.b.x) * (v.a.y - v.b.y) - (u.a.y - u.b.y) * (v.a.x - v.b.x));
    ret.x
+= (u.b.x - u.a.x) * t;
    ret.y
+= (u.b.y - u.a.y) * t;
    
return  ret;
}
point barycenter(point a,point b,point c){
    line u,v;
    u.a.x
= (a.x + b.x) / 2 ;
    u.a.y
= (a.y + b.y) / 2 ;
    u.b
= c;
    v.a.x
= (a.x + c.x) / 2 ;
    v.a.y
= (a.y + c.y) / 2 ;
    v.b
= b;
    
return  intersection(u,v);
}
point barycenter(
int  n,point *  p){
    point ret,t;
    
double  t1 = 0 ,t2;
    
int  i;
    ret.x
= ret.y = 0 ;
    
for  (i = 1 ;i < n - 1 ;i ++ )
        
if  (fabs(t2 = xmult(p[ 0 ],p[i],p[i + 1 ])) > eps){
            t
= barycenter(p[ 0 ],p[i],p[i + 1 ]);
            ret.x
+= t.x * t2;
            ret.y
+= t.y * t2;
            t1
+= t2;
        }
        
if  (fabs(t1) > eps)
            ret.x
/= t1,ret.y /= t1;
        
return  ret;
}

int  main()
{
    
int  T,i,n;
    scanf(
" %d " , & T);
    
while (T -- )
    {
        scanf(
" %d " , & n);
        
for (i = 0 ;i < n;i ++ ) {
            scanf(
" %lf%lf " , & p[i].x, & p[i].y);
        }
        point x 
=  barycenter(n,p);
        x.x 
+=  eps;
        x.y 
+=  eps;
        printf(
" %.2lf %.2lf\n " ,x.x,x.y);
    }
}


http://acm.hdu.edu.cn/showproblem.php?pid=2671
// 点关于直线的对称点

#include
< stdio.h >
#include
< math.h >
#define  eps 1e-8
struct  point{
    
double  x,y;
};
struct  line{
    point a,b;
};


double  dis(point p1,point p2) {
    
return  sqrt( (p1.x - p2.x) * (p1.x - p2.x)  +  (p1.y - p2.y) * (p1.y - p2.y) );
}
double  xmult(point p1,point p2,point p0){
    
return  (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int  same_side(point p1,point p2,line l){
    
return  xmult(l.a,p1,l.b) * xmult(l.a,p2,l.b) > eps;
}
point intersection(point u1,point u2,point v1,point v2){
    point ret
= u1;
    
double  t = ((u1.x - v1.x) * (v1.y - v2.y) - (u1.y - v1.y) * (v1.x - v2.x))
            
/ ((u1.x - u2.x) * (v1.y - v2.y) - (u1.y - u2.y) * (v1.x - v2.x));
    ret.x
+= (u2.x - u1.x) * t;
    ret.y
+= (u2.y - u1.y) * t;
    
return  ret;
}
point ptoline(point p,line l){
    point t
= p;
    t.x
+= l.a.y - l.b.y;
    t.y
+= l.b.x - l.a.x;
    
return  intersection(p,t,l.a,l.b);
}


int  main()
{
    
int  T;
    
double  k;
    point a,b,c,d;
    line cd;
    scanf(
" %d " , & T);
    
while (T -- )
    {
        scanf(
" %lf " , & k);
        scanf(
" %lf%lf%lf%lf%lf%lf " , & a.x, & a.y, & b.x, & b.y, & c.x, & c.y);
        d.x 
=  c.x  +   1 ;
        d.y 
=  c.y  +   1 * k;
        cd.a 
=  c;
        cd.b 
=  d;
        
if (same_side(a,b,cd)) {
            point e 
=  ptoline(a,cd);
            a.x 
=  a.x  +  (e.x - a.x) * 2 ;
            a.y 
=  a.y  +  (e.y - a.y) * 2 ;
        }
        printf(
" %.2lf\n " ,dis(a,b));
    }
}

http://acm.hdu.edu.cn/showproblem.php?pid=1700

// 一个点绕另外一个点旋转并扩大
#include < stdio.h >
#include 
< math.h >
struct  point{ double  x,y;};

point rotate(point v,point p,
double  angle, double  scale){
    point ret
= p;
    v.x
-= p.x,v.y -= p.y;
    p.x
= scale * cos(angle);
    p.y
= scale * sin(angle);
    ret.x
+= v.x * p.x - v.y * p.y;
    ret.y
+= v.x * p.y + v.y * p.x;
    
return  ret;
}
int  main()
{
    
int  T;
    point a,o,b,c;
    o.x 
=   0 ;
    o.y 
=   0 ;
    scanf(
" %d " , & T);
    
while (T -- )
    {
        scanf(
" %lf%lf " , & a.x, & a.y);
        b 
=  rotate(a,o, 120.0 / 180 * acos( - 1.0 ), 1 );
        c 
=  rotate(a,o, - 120.0 / 180 * acos( - 1.0 ), 1 );
        
if (b.y < c.y  ||  b.y == c.y  &&  b.x < c.x)
            printf(
" %.3lf %.3lf %.3lf %.3lf\n " ,b.x,b.y,c.x,c.y);
        
else
            printf(
" %.3lf %.3lf %.3lf %.3lf\n " ,c.x,c.y,b.x,b.y);
    }
    
return   0 ;
}


http://acm.hdu.edu.cn/showproblem.php?pid=1756
// 判点在任意多边形内,顶点按顺时针或逆时针给出
// on_edge表示点在多边形边上时的返回值,offset为多边形坐标上限

#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< math.h >
#define  offset 1000
#define  eps 1e-8
#define  zero(x) (((x)>0?(x):-(x))<eps)
#define  _sign(x) ((x)>eps?1:((x)<-eps?2:0))
struct  point{ double  x,y;};
double  xmult(point p1,point p2,point p0){
    
return  (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int  inside_polygon(point q, int  n,point *  p, int  on_edge = 1 ){
    point q2;
    
int  i = 0 ,count;
    
while  (i < n)
        
for  (count = i = 0 ,q2.x = rand() + offset,q2.y = rand() + offset;i < n;i ++ )
            
if  (zero(xmult(q,p[i],p[(i + 1 ) % n])) && (p[i].x - q.x) * (p[(i + 1 ) % n].x - q.x) < eps && (p[i].y - q.y) * (p[(i + 1 ) % n].y - q.y) < eps)
                
return  on_edge;
            
else   if  (zero(xmult(q,q2,p[i])))
                
break ;
            
else   if  (xmult(q,p[i],q2) * xmult(q,p[(i + 1 ) % n],q2) <- eps && xmult(p[i],q,p[(i + 1 ) % n]) * xmult(p[i],q2,p[(i + 1 ) % n]) <- eps)
                count
++ ;
            
return  count & 1 ;
}
int  main()
{
    
int  n,m,i;
    point p[
101 ],q;
    
while (scanf( " %d " , & n) == 1 )
    {
        
for (i = 0 ;i < n;i ++ )
            scanf(
" %lf%lf " , & p[i].x, & p[i].y);
        scanf(
" %d " , & m);
        
while (m -- )
        {
            scanf(
" %lf%lf " , & q.x, & q.y);
            puts(inside_polygon(q,n,p)
? " Yes " : " No " );
        }
    }
    
return   0 ;
}

内容及代码日后补充整理。。。。。

你可能感兴趣的:(一些计算几何基础公式(含5题及相关模板))