计算几何入门题(更新中……)
http://acm.pku.edu.cn/JudgeOnline/problem?id=1696Space Ant用到叉积,点积。这个题的代码稍微改改,貌似可以认为是凸包的o(n^2)算法,即卷包心菜。
1//1696_SpaceAnt ~ alpc02
2#include <math.h>
3#include <algorithm>
4using namespace std;
5
6const int N = 55;
7
8const double PRECISION = 1e-8;
9int dblcmp(double d) {
10 return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
11}
12struct Point {
13 double x, y;
14};
15double dotdet(double x1, double y1, double x2, double y2) {
16 return x1*x2 + y1*y2;
17} //点积
18double det(double x1, double y1, double x2, double y2) {
19 return x1*y2 - x2*y1;
20} //叉积
21int 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——三点共线
24bool 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内部
27double Min(double a, double b){return a<b ? a:b; }
28
29Point a[N];
30bool f[N];
31int 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>
4using namespace std;
5
6const double PRECISION = 1e-8;
7struct Point {
8 double x, y;
9};
10int dblcmp(double d) {
11 return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
12} //三叉口函数,避免精度误差
13double det(double x1, double y1, double x2, double y2) {
14 return x1*y2 - x2*y1;
15} //叉积
16int 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——三点共线
19void 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} //规范相交时,求交点坐标
26void 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} //先把直线先延长得足够长
38int 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 阅读(1371)
评论(2) 编辑 收藏 引用 所属分类:
计算几何