POJ P2318 TOYS与POJ P1269 Intersecting Lines——计算几何入门题两道

rt,计算几何入门;



TOYS

Calculate the number of toys that land in each bin of a partitioned toy box. 
Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys in, but John is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for John to find his favorite toys. 

John's parents came up with the following idea. They put cardboard partitions into the box. Even if John keeps throwing his toys into the box, at least toys that get thrown into different bins stay separated. The following diagram shows a top view of an example toy box. 
 
For this problem, you are asked to determine how many toys fall into each partition as John throws them into the toy box.

                --by POJ

http://poj.org/problem?id=2318



由于数据范围小,M*N的暴力枚举即可,

对于一个点,使其与直线的一点构成向量,与直线方向向量作叉积判断位置即可;

代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const double eps=1e-10;
 7 int dcmp(double x){
 8     if(fabs(x)<eps)return 0;
 9     return x<0?-1:1;
10 }
11 struct Point{
12     double x,y;
13     Point(double x=0,double y=0):x(x),y(y){    };
14 };
15 typedef Point Vector;
16 struct line{
17     Point s,t;
18 }lin[5010];
19 Vector operator - (Point A,Point B){
20     return Vector(A.x-B.x,A.y-B.y);
21 }
22 double Cross(Vector A,Vector B){
23     return A.x*B.y-A.y*B.x;
24 }
25 int ton[5010];
26 int main()
27 {
28     int i,j,k,p;
29     int n,m;
30     Point lu,rd,toy;
31     while(scanf("%d%d",&n,&m)==2&&n!=0){
32         memset(ton,0,sizeof(ton));
33         scanf("%lf%lf%lf%lf",&lu.x,&lu.y,&rd.x,&rd.y);
34         for(i=1;i<=n;i++){
35             scanf("%lf%lf",&lin[i].s.x,&lin[i].t.x);
36             lin[i].s.y=lu.y;lin[i].t.y=rd.y;
37         }
38         for(i=1;i<=m;i++){
39             scanf("%lf%lf",&toy.x,&toy.y);
40             p=0;
41             for(j=1;j<=n;j++)
42                 if(Cross(toy-lin[j].s,lin[j].t-lin[j].s)>0){
43                     ton[j-1]++;p=1;
44                     break;
45                 }
46             if(!p)
47                 ton[n]++;
48         }
49         for(i=0;i<=n;i++)
50             printf("%d: %d\n",i,ton[i]);
51         printf("\n");
52     }
53 }


Intersecting Lines

We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane will intersect in one of three ways: 1) no intersection because they are parallel, 2) intersect in a line because they are on top of one another (i.e. they are the same line), 3) intersect in a point. In this problem you will use your algebraic knowledge to create a program that determines how and where two lines intersect. 
Your program will repeatedly read in four points that define two lines in the x-y plane and determine how and where the lines intersect. All numbers required by this problem will be reasonable, say between -1000 and 1000. 

              --by POJ

http://poj.org/problem?id=1269



判断两直线的位置关系并判断交点;

位置关系:

平行:向量叉积为零,且两直线上点间连向量与直线的向量叉积非零;

重合:向量叉积为零,且不平行;

相交:叉积非零;

求交点:设为(x,y),

交点与直线a的点构成向量与向量a叉积零,

与直线b的点构成向量与向量b叉积零,

列二元方程组,解之即得;

当然没这么麻烦!!!

因为其实有个结论:

设直线分别为P+tV和Q+tW且设向量u=P-Q,设交点在直线1的参数为t1,交点在直线2的参数为t2

t1=cross(w,u)/cross(v,w)
t2=cross(v,u)/cross(v,w)

然而并不知道,花了好久解了下方程

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 using namespace std;
 5 const double eps=1e-10;
 6 int dcmp(double x){
 7     if(fabs(x)<eps)return 0;
 8     return x>0?1:-1;
 9 }
10 struct Point{
11     double x,y;
12     Point(double x=0,double y=0):x(x),y(y){    };
13 };
14 typedef Point Vector;
15 struct line{
16     Point s,t;
17 };
18 Vector operator - (Vector A,Vector B){
19     return Vector(A.x-B.x,A.y-B.y);
20 }
21 double Cross(Vector A,Vector B){
22     return A.x*B.y-A.y*B.x;
23 }
24 int main()
25 {
26     int i,j,k,n;
27     line lin1,lin2;
28     Point Poi;
29     Vector Ve1,Ve2;
30     double k1,k2,X,Y;
31     scanf("%d",&n);
32     printf("INTERSECTING LINES OUTPUT\n");
33     for(i=1;i<=n;i++){
34         scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&lin1.s.x,&lin1.s.y,&lin1.t.x,&lin1.t.y,&lin2.s.x,&lin2.s.y,&lin2.t.x,&lin2.t.y);
35         if(!dcmp(Cross(lin1.t-lin1.s,lin2.t-lin2.s))){
36             if(!dcmp(Cross(lin1.t-lin1.s,lin1.t-lin2.s)))
37                 printf("LINE\n");
38             else
39                 printf("NONE\n");
40         }
41         else{
42             Ve1=lin1.t-lin1.s;Ve2=lin2.t-lin2.s;
43             X=(Ve1.x*Ve2.x*(lin2.t.y-lin1.t.y)-lin2.t.x*Ve1.x*Ve2.y+lin1.t.x*Ve1.y*Ve2.x)/(Ve1.y*Ve2.x-Ve2.y*Ve1.x);
44             if(dcmp(Ve1.x)!=0)
45                 Y=lin1.t.y-(lin1.t.x-X)*Ve1.y/Ve1.x;
46             else
47                 Y=lin2.t.y-(lin2.t.x-X)*Ve2.y/Ve2.x;
48             printf("POINT %.2lf %.2lf\n",X,Y);
49         }
50     }
51     printf("END OF OUTPUT\n");
52 }

 祝AC

 

posted @ 2017-03-30 20:12  F.W.Nietzsche  阅读(212)  评论(0编辑  收藏  举报