计算几何入门题(更新中……)
http://acm.pku.edu.cn/JudgeOnline/problem?id=1696Space Ant用到叉积,点积。这个题的代码稍微改改,貌似可以认为是凸包的o(n^2)算法,即卷包心菜。


 1 //1696_SpaceAnt ~ alpc02
//1696_SpaceAnt ~ alpc02
 2 #include <math.h>
#include <math.h>
 3 #include <algorithm>
#include <algorithm>
 4 using namespace std;
using namespace std;
 5
 6 const int N = 55;
const int N = 55;
 7
 8 const double PRECISION = 1e-8;
const double PRECISION = 1e-8;
 9
 int dblcmp(double d)
int dblcmp(double d)  {
{
10 return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
    return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
11 }
}
12
 struct Point
struct Point  {
{
13 double x, y;
    double x, y;
14 };
};
15
 double dotdet(double x1, double y1, double x2, double y2)
double dotdet(double x1, double y1, double x2, double y2)  {
{
16 return x1*x2 + y1*y2;
    return x1*x2 + y1*y2;
17 } //点积
} //点积
18
 double det(double x1, double y1, double x2, double y2)
double det(double x1, double y1, double x2, double y2)  {
{
19 return x1*y2 - x2*y1;
    return x1*y2 - x2*y1;
20 } //叉积
} //叉积
21
 int cross(const Point &a, const Point &c, const Point &d)
int cross(const Point &a, const Point &c, const Point &d)  {
{
22 return dblcmp( det(a.x-c.x, a.y-c.y, d.x-c.x, d.y-c.y) );
    return dblcmp( det(a.x-c.x, a.y-c.y, d.x-c.x, d.y-c.y) );
23 } //右手螺旋定则,1——a在cd右侧,-1——a在cd左侧,0——三点共线
} //右手螺旋定则,1——a在cd右侧,-1——a在cd左侧,0——三点共线
24
 bool between(const Point &a, const Point &c, const Point &d)
bool between(const Point &a, const Point &c, const Point &d)  {
{
25 return dblcmp( dotdet(c.x-a.x, c.y-a.y, d.x-a.x, d.y-a.y) ) != 1;
    return dblcmp( dotdet(c.x-a.x, c.y-a.y, d.x-a.x, d.y-a.y) ) != 1;
26 } //在cross(a,b,c)==0的基础上,可判断点a是否在cd内部
} //在cross(a,b,c)==0的基础上,可判断点a是否在cd内部
27
 double Min(double a, double b)
double Min(double a, double b) {return a<b ? a:b; }
{return a<b ? a:b; }
28
29 Point a[N];
Point a[N];
30 bool f[N];
bool f[N];
31
 int main()
int main()  {
{
32 freopen("in", "r", stdin);
    freopen("in", "r", stdin);
33 int Ca;
    int Ca;
34 scanf("%d", &Ca);
    scanf("%d", &Ca);
35 
    
36 int n, i, j, k;
    int n, i, j, k;
37 int now, temp;
    int now, temp;
38
 while(Ca--)
    while(Ca--)  {
{
39 scanf("%d",&n);
        scanf("%d",&n);
40 a[0].x = 0;
        a[0].x = 0;
41 a[0].y = 1e10;
        a[0].y = 1e10;
42
 for(i=1; i<=n; i++)
        for(i=1; i<=n; i++)  {
{
43 scanf("%d", &k);
            scanf("%d", &k);
44 scanf("%lf %lf", &a[k].x, &a[k].y);
            scanf("%lf %lf", &a[k].x, &a[k].y);
45 a[0].y = Min(a[0].y, a[k].y);
            a[0].y = Min(a[0].y, a[k].y);
46 }
        }
47 memset(f, false, sizeof(f));
        memset(f, false, sizeof(f));
48
49 now = 0;
        now = 0;
50 printf("%d", n);
        printf("%d", n);
51
 for(i=1; i<=n; i++)
        for(i=1; i<=n; i++)  {
{
52 k = -1;
            k = -1;
53 for(j=1; j<=n; j++)
            for(j=1; j<=n; j++)
54
 if(!f[j])
                if(!f[j])  {
{
55 if(k == -1)        k = j;
                    if(k == -1)        k = j;
56
 else
                    else  {
{
57 temp = cross(a[j], a[now], a[k]);
                        temp = cross(a[j], a[now], a[k]);
58 if( (temp == 1) || (temp == 0 && between(a[j], a[now], a[k])) )
                        if( (temp == 1) || (temp == 0 && between(a[j], a[now], a[k])) )
59 k = j;
                            k = j;
60 }
                    }
61 }
                }
62 now = k;
            now = k;
63 printf(" %d", now);
            printf(" %d", now);
64 f[now] = true;
            f[now] = true;
65 }
        }
66 printf("\n");
        printf("\n");
67 }
    }
68 return 0;
    return 0;
69 }
}
70
判断两直线平行、重合还是相交,如果相交,求出交点。


 1 //1269_IntersectingLines ~ alpc02
//1269_IntersectingLines ~ alpc02
 2 #include <math.h>
#include <math.h>
 3 #include <algorithm>
#include <algorithm>
 4 using namespace std;
using namespace std;
 5
 6 const double PRECISION = 1e-8;
const double PRECISION = 1e-8;
 7
 struct Point
struct Point  {
{
 8 double x, y;
    double x, y;
 9 };
};
10
 int dblcmp(double d)
int dblcmp(double d)  {
{
11 return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
    return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
12 } //三叉口函数,避免精度误差
} //三叉口函数,避免精度误差
13
 double det(double x1, double y1, double x2, double y2)
double det(double x1, double y1, double x2, double y2)  {
{
14 return x1*y2 - x2*y1;
    return x1*y2 - x2*y1;
15 } //叉积
} //叉积
16
 int cross(const Point &a, const Point &c, const Point &d)
int cross(const Point &a, const Point &c, const Point &d)  {
{
17 return dblcmp( det(a.x-c.x, a.y-c.y, d.x-c.x, d.y-c.y) );
    return dblcmp( det(a.x-c.x, a.y-c.y, d.x-c.x, d.y-c.y) );
18 } //右手螺旋定则,1——a在cd右侧,-1——a在cd左侧,0——三点共线
} //右手螺旋定则,1——a在cd右侧,-1——a在cd左侧,0——三点共线
19
 void intersect(const Point &a, const Point &b, const Point &c, const Point &d, Point &e)
void intersect(const Point &a, const Point &b, const Point &c, const Point &d, Point &e)  {
{
20 double sc, sd;
    double sc, sd;
21 sc = fabs( det(b.x-a.x, b.y-a.y, c.x-a.x, c.y-a.y) );
    sc = fabs( det(b.x-a.x, b.y-a.y, c.x-a.x, c.y-a.y) );
22 sd = fabs( det(b.x-a.x, b.y-a.y, d.x-a.x, d.y-a.y) );
    sd = fabs( det(b.x-a.x, b.y-a.y, d.x-a.x, d.y-a.y) );
23 e.x = (sc * d.x + sd * c.x) / (sc + sd);
    e.x = (sc * d.x + sd * c.x) / (sc + sd);
24 e.y = (sc * d.y + sd * c.y) / (sc + sd);
    e.y = (sc * d.y + sd * c.y) / (sc + sd);
25 } //规范相交时,求交点坐标
} //规范相交时,求交点坐标
26
 void lineIntersect(Point a, Point b, Point c, Point &d, Point &e)
void lineIntersect(Point a, Point b, Point c, Point &d, Point &e)  {
{
27 double temp = 1000;
    double temp = 1000;
28 a.x += (a.x - b.x) * temp;
    a.x += (a.x - b.x) * temp;
29 a.y += (a.y - b.y) * temp;
    a.y += (a.y - b.y) * temp;
30 b.x += (b.x - a.x) * temp;
    b.x += (b.x - a.x) * temp;
31 b.y += (b.y - a.y) * temp;
    b.y += (b.y - a.y) * temp;
32 c.x += (c.x - d.x) * temp;
    c.x += (c.x - d.x) * temp;
33 c.y += (c.y - d.y) * temp;
    c.y += (c.y - d.y) * temp;
34 d.x += (d.x - c.x) * temp;
    d.x += (d.x - c.x) * temp;
35 d.y += (d.y - c.y) * temp;
    d.y += (d.y - c.y) * temp;
36 intersect(a, b, c, d, e);
    intersect(a, b, c, d, e);
37 } //先把直线先延长得足够长
} //先把直线先延长得足够长
38
 int main()
int main()  {
{
39 freopen("in", "r", stdin);
    freopen("in", "r", stdin);
40 int Ca;
    int Ca;
41 Point a, b, c, d, e;
    Point a, b, c, d, e;
42 printf("INTERSECTING LINES OUTPUT\n");
    printf("INTERSECTING LINES OUTPUT\n");
43 scanf("%d", &Ca);
    scanf("%d", &Ca);
44
 while(Ca--)
    while(Ca--)  {
{
45 scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
        scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
46
 if(dblcmp( det(a.x-b.x, a.y-b.y, c.x-d.x, c.y-d.y) ) != 0)
        if(dblcmp( det(a.x-b.x, a.y-b.y, c.x-d.x, c.y-d.y) ) != 0)  {
{
47 printf("POINT ");
            printf("POINT ");
48 lineIntersect(a, b, c, d, e);
            lineIntersect(a, b, c, d, e);
49 printf("%.2lf %.2lf\n", e.x, e.y);
            printf("%.2lf %.2lf\n", e.x, e.y);
50 }
        }
51
 else
        else  {
{
52 if(cross(a,c,d) == 0)
            if(cross(a,c,d) == 0)
53 printf("LINE\n");
                printf("LINE\n");
54 else
            else
55 printf("NONE\n");
                printf("NONE\n");
56 }
        }
57 }
    }
58 printf("END OF OUTPUT\n");
    printf("END OF OUTPUT\n");
59 return 0;
    return 0;
60 }
}
61
给定n条线段,问是否存在一条直线和每条线段都相交
如果存在,则肯定可以把这条直线调整为经过所有线段端点中的某两个。
这样的话,可枚举这两个端点,然后判断直线和线段相交。
相关代码可参考
http://www.cppblog.com/shiming413/archive/2007/08/22/30617.html
	posted on 2007-08-22 18:28 
LSM 阅读(1409) 
评论(2)  编辑 收藏 引用  所属分类: 
计算几何