POJ1408 两条线段求交点+叉乘求几何面积+枚举

来源:互联网 发布:美国数据分析专业 编辑:程序博客网 时间:2024/09/21 09:21
POJ1408


1  求两条直线规范相交的交点坐标
 


如图,已知点A、B、C、D的坐标,求点P坐标:
 

 


 




其中,第一个式子不需要解释,记住这个定理即可。
第二个式子是由定比分点坐标公式推出。
     

Note①:
二维向量叉乘公式
a(x1,y1),b(x2,y2),则a×b=(x1y2-x2y1).


Note②:
定比分点坐标公式:


已知四点如图所示,其中  , , ,,在两点连线上有一点P,设它的坐标 ,

 ,可以求出P的坐标公式,如下:

 


 

 带入并化简,可得


,纵坐标   同理。


2

#include <iostream>#include <stdio.h>#include <math.h>//基本思想:因为题目要求对应边的对应点相连接,所以免去了很多不必要的情况,因而才可以算出所有交点,枚举得到的所有四边形,保留最大的一个。//关键:主要通过此题掌握,1 利用叉乘求两条规范相交直线的交点坐标 (由定比分点坐标公式和叉乘求三角形面积公式联立化简所得)(规范相交,两条直线只有一个非端点的交点,即该两条线段的四个端点分别处于交点两个方向的左右两侧) ,2 利用叉乘求多面性面积(通过三角形面积相加得到)//注意:叉乘得面积,面积是有正负的,向量ab叉乘向量ac(向量ab是a->b,向量ac是a->c),方向是根据右手定则从ab指向ac时大拇指所指的方向,向外是正,向内是负。using namespace std;struct point{    double x;    double y;}point[35][35];double xx;double yy;double Area(struct point a,struct point b,struct point c){//利用ab叉乘ac    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);//向量ab,即箭头为a->b,时,用点b的坐标减去a的坐标}void Intersection(struct point line1_A,struct point line1_B,struct point line2_C,struct point line2_D){    double area1=Area(line1_A,line1_B,line2_D);    double area2=Area(line1_A,line2_C,line1_B);    xx=( area1*(line2_C.x)+area2*(line2_D.x) ) / ( area1+area2 );    yy=( area1*(line2_C.y)+area2*(line2_D.y) ) / ( area1+area2 );    return;}int main(){    int n;    while(~scanf("%d",&n)&&n!=0){        ///Ini:        point[0][0].x=0;point[0][0].y=0;        point[n+1][n+1].x=1;point[n+1][n+1].y=1;        point[0][n+1].x=0;point[0][n+1].y=1;        point[n+1][0].x=1;point[n+1][0].y=0;        for(int i=1;i<=n;i++){            scanf("%lf",&point[i][0].x);            point[i][0].y=0;        }        for(int i=1;i<=n;i++){            scanf("%lf",&point[i][n+1].x);            point[i][n+1].y=1;        }        for(int i=1;i<=n;i++){            scanf("%lf",&point[0][i].y);            point[0][i].x=0;        }        for(int i=1;i<=n;i++){            scanf("%lf",&point[n+1][i].y);            point[n+1][i].x=1;        }        ///Intersection:        for(int i=1;i<=n;i++){            for(int j=1;j<=n;j++){                Intersection(point[i][0],point[i][n+1],point[0][j],point[n+1][j]);                point[i][j].x=xx;                point[i][j].y=yy;                //cout<<xx<<" "<<yy<<endl;            }        }        ///Enumerate:        double maxx=0;        double temp;        for(int i=0;i<=n;i++){            for(int j=0;j<=n;j++){                temp=Area(point[i][j],point[i+1][j],point[i][j+1]);                temp+=Area(point[i+1][j+1],point[i][j+1],point[i+1][j]);                temp/=2;//因为四边形不一定是正方形,所以用叉乘分别算出(上三角的面积*2)和(下三角的面积*2)相加之后再/2,即可。                if(temp>maxx){                    maxx=temp;                }            }        }        ///printf:        printf("%.6f\n",maxx);    }}



0 0
原创粉丝点击