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


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


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