Blog2:nchu-software-oop-2022-4+5+期中


Blog2:nchu-software-oop-2022-4+5+期中

一、前言

两次大作业是关于四边形和五边形的相关操作,类似于之前的三角形,但由于图形边数的变化,难度大大增加。对数学知识的运用考察较多,其中还有对正则表达式的考量。在完成五边形第二题作业是,由于前面创建的类并不好,在面对复杂的五边形时,前面的类根本没有办法延用。这两次作业对我来说都很吃力。考查的知识点有:字符串的输出和输入,强制转化变量的类型,split函数的应用,逻辑思维能力,全面考虑问题的能力,方法编写能力,正则表达式练习。其中,主要题目是图形界面类设计编写。这些作业题量和难度都很大,全部尽量写到最好要花费比较多的时间。

期中考试主要考察了PTA图形界面类设计编写,共有三道题目,题量一般。与平时题目不同的是,每题均给出了相应的类图,要求考生按照类图来书写自己的代码。且三题呈递进关系,每题均是由上一题进阶而来。第一题是点与线,要求输出点和线的属性,考察了学生对Java类的设计的掌握。而第二题则是在第一题的基础上加上了关于面的类,并要求把点、线、面三类均作为新建类Element类的子类。考察了学生对继承与多态的掌握。第三题考察了Java容器类,主要是ArrayList的应用。且相比前两题有了多种输入格式,增加了难度。

 

二、设计与分析

题目1:

7-2 点线形系列4-凸四边形的计算 分数 70 作者 蔡轲 单位 南昌航空大学

用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。

*****************************************************************************************************************************************************************************

这题题目难度还好,主要根据前面三角形的类和方法,在其基础上添加修改。

import java.util.Scanner;

class Point
{
    double x;
    double y;
    int flag=0;
    int exist=1;//1:存在 0:不存在 2:交点无数个
    public boolean pointchonghe(Point A,Point B)//判断两点重合
    {
        if(A.x==B.x&&A.y==B.y)
            return true;
        else
            return false;
    }
    public boolean Pointscoincide(Point A,Point B,Point C,Point D)//判断四边形四点重合
    {
        if(A.x==B.x&&A.y==B.y||A.x==C.x&&A.y==C.y||A.x==D.x&&A.y==D.y||B.x==C.x&&B.y==C.y||B.x==D.x&&B.y==D.y||C.x==D.x&&C.y==D.y)
            return true;
        else
            return false;
    }
}

class Line
{
    Point p1=new Point();
    Point p2=new Point();
    double a;
    double b;
    double c;
    double D;
    int flag;//交点是否在线段上
    public void L(Line l)//一般式系数
    {
        l.a=l.p2.y-l.p1.y;
        l.b=l.p1.x-l.p2.x;
        l.c=l.p2.x*l.p1.y-l.p1.x*l.p2.y;
    }
    public void D(Point p1,Point p2,Line lp1p2)//两点间距离
    {
        lp1p2.D=Math.sqrt(Math.pow(lp1p2.p1.x-lp1p2.p2.x,2)+Math.pow(lp1p2.p1.y-lp1p2.p2.y,2));
        lp1p2.D=Math.round(lp1p2.D*1000000000)/(double)1000000000;
    }
    public void distanse(Line l)//求线段距离D
    {
        l.D=Math.sqrt(Math.pow(l.p1.x-l.p2.x,2)+Math.pow(l.p1.y-l.p2.y,2));
        l.D=Math.round(l.D*1000000000)/(double)1000000000;
    }
    public boolean zhixian(Point X,Line l)//点是否在直线上
    {
        L(l);
        if(l.a*X.x+l.b*X.y+l.c==0)
            return true;
        else
            return false;
    }
    public boolean linechonghe(Line l1,Line l2)//判断是否两线重合
    {
        L(l1);
        L(l2);
        if(l1.b==0&&l2.b==0)
        {
            if(l1.c/l1.a==l2.c/l2.a)
                return true;
            else
                return false;
        }
        else if(l1.a==0&&l2.a==0)
        {
            if(l1.c/l1.b==l2.c/l2.b)
                return true;
            else
                return false;
        }
        else 
        {
            if(l1.c/l1.a==l2.c/l2.a&&l1.c/l1.b==l2.c/l2.b)
                return true;
            else
                return false;
        }
    }
    public boolean pingxing(Line l1,Line l2)//判断是否平行(有无交点)
    {
        L(l1);
        L(l2);
        if(l1.b==0&&l2.b==0)
            return true;
        else if(l1.b!=0&&l2.b!=0&&(l1.a/l1.b==l2.a/l2.b))
            return true;
        else
            return false;
    }
    public boolean Quadrilateral(Line lAB,Point C,Point D)//判断是否四边形
    {
        L(lAB);
        if((!zhixian(C,lAB))&&(!zhixian(D,lAB))&&((lAB.a*C.x+lAB.b*C.y+lAB.c<0)&&(lAB.a*D.x+lAB.b*D.y+lAB.c<0)||(lAB.a*C.x+lAB.b*C.y+lAB.c>0)&&(lAB.a*D.x+lAB.b*D.y+lAB.c>0)))
            return true;
        else
            return false;
    }
    public boolean Quadrilateral1(Point A,Point B,Point C,Point D,Quadrilateral Q)//凹
    {
        if((!zhixian(C,Q.l1))&&(!zhixian(D,Q.l1))&&(!zhixian(D,Q.l6))&&(!zhixian(D,Q.l2)))
        {
            Point O=new Point();
            Line lAO=new Line();
            lAO.p1=A;
            lAO.p2=O;
            Line lBO=new Line();
            lBO.p1=B;
            lBO.p2=O;
            Line lCO=new Line();
            lCO.p1=C;
            lCO.p2=O;
            Line lDO=new Line();
            lDO.p1=D;
            lDO.p2=O;
            Triangle t=new Triangle();
            
            t.jiaodian(Q.l5,Q.l6,O);//AC和BD交点
            if(t.pointwhere(O,A,C,lAO,lCO,Q.l6)&&!t.pointwhere(O,B,D,lBO,lDO,Q.l5))//交点在线段AC和不在BD上
            {
                Q.l5.flag=0;
                Q.l6.flag=1;
                return true;
            }
            else if(!t.pointwhere(O,A,C,lAO,lCO,Q.l6)&&t.pointwhere(O,B,D,lBO,lDO,Q.l5))//交点不在线段AC和在BD上
            {
                Q.l5.flag=1;
                Q.l6.flag=0;
                return true;
            }
            else
                return false;
        }
        else
            return false;
    }
    public boolean Quadrilateral2(Point A,Point B,Point C,Point D,Quadrilateral Q)//凸
    {
        if((!zhixian(C,Q.l1))&&(!zhixian(D,Q.l1))&&(!zhixian(A,Q.l3))&&(!zhixian(D,Q.l2))&&(!A.Pointscoincide(A,B,C,D)))
        {
            Point O=new Point();
            Line lAO=new Line();
            lAO.p1=A;
            lAO.p2=O;
            Line lBO=new Line();
            lBO.p1=B;
            lBO.p2=O;
            Line lCO=new Line();
            lCO.p1=C;
            lCO.p2=O;
            Line lDO=new Line();
            lDO.p1=D;
            lDO.p2=O;
            Triangle t=new Triangle();
            
            t.jiaodian(Q.l5,Q.l6,O);//AC和BD交点
            
            if(O.exist==1&&t.pointwhere(O,A,C,lAO,lCO,Q.l6)&&t.pointwhere(O,B,D,lBO,lDO,Q.l5))//交点在线段AC和BD上
                return true;
            else
                return false;
        }
        else
            return false;
    }
    public boolean pingxingQuadrilateral(Line l1,Line l2)//判断是否平行四边形
    {
        
        distanse(l1);
        distanse(l2);

        if(pingxing(l1,l2)&&l1.D==l2.D)
            return true;
        else
            return false;
    }
}

class Triangle
{
    Line l1=new Line();
    Line l2=new Line();
    Line l3=new Line();
    double S;
    int num;
    int flag=0;//1:存在,0:不存在
    public boolean sanjiaox(Line l1,Line l2,Line l3)//判断是否为三角形
    {
        l1.distanse(l1);
        l2.distanse(l2);
        l3.distanse(l3);
        if((l1.D+l2.D>l3.D&&l1.D<=l3.D&&l2.D<=l3.D)||(l1.D+l3.D>l2.D&&l1.D<=l2.D&&l3.D<=l2.D)||(l2.D+l3.D>l1.D&&l2.D<=l1.D&&l2.D<=l1.D))
            return true;
        else
            return false;
    }
    public void whichsanjiaox(Point C,Point D,Point E,Point F,Line lAB,Triangle tDEF,Triangle tCEF,Triangle tCDF,Triangle tCDE,Quadrilateral Q)//判断四个点构成哪种三角形
    {
        if(sanjiaox(tDEF.l1,tDEF.l2,tDEF.l3)&&pointwhere(C,D,F,Q.l1,Q.l4,Q.l5))
        {
            if(lAB.linechonghe(lAB,Q.l1)||lAB.linechonghe(lAB,Q.l2)||lAB.linechonghe(lAB,Q.l3)||lAB.linechonghe(lAB,Q.l4))
            {
                System.out.print("The line is coincide with one of the lines");
                return;
            }
            else
                tDEF.flag=1;
        }
        else if(sanjiaox(tCEF.l1,tCEF.l2,tCEF.l3)&&pointwhere(D,C,E,Q.l1,Q.l2,Q.l6))
        {
            if(lAB.linechonghe(lAB,Q.l1)||lAB.linechonghe(lAB,Q.l2)||lAB.linechonghe(lAB,Q.l3)||lAB.linechonghe(lAB,Q.l4))
            {
                System.out.print("The line is coincide with one of the lines");
                return;
            }
            else
                tCEF.flag=1;
        }
        else if(sanjiaox(tCDF.l1,tCDF.l2,tCDF.l3)&&pointwhere(E,D,F,Q.l2,Q.l3,Q.l5))
        {
            if(lAB.linechonghe(lAB,Q.l1)||lAB.linechonghe(lAB,Q.l2)||lAB.linechonghe(lAB,Q.l3)||lAB.linechonghe(lAB,Q.l4))
            {
                System.out.print("The line is coincide with one of the lines");
                return;
            }
            else
                tCDF.flag=1;
        }
        else if(sanjiaox(tCDE.l1,tCDE.l2,tCDE.l3)&&pointwhere(F,C,E,Q.l4,Q.l3,Q.l6))
        {
            if(lAB.linechonghe(lAB,Q.l1)||lAB.linechonghe(lAB,Q.l2)||lAB.linechonghe(lAB,Q.l3)||lAB.linechonghe(lAB,Q.l4))
            {
                System.out.print("The line is coincide with one of the lines");
                return;
            }
            else
                tCDE.flag=1;
        }
    }
    public void whichsanjiaox1(Point C,Point D,Point E,Point F,Triangle tDEF,Triangle tCEF,Triangle tCDF,Triangle tCDE,Quadrilateral Q)//判断哪种三角形
    {
        if(sanjiaox(tDEF.l1,tDEF.l2,tDEF.l3)&&pointwhere(C,D,F,Q.l1,Q.l4,Q.l5))
            tDEF.flag=1;
        else if(sanjiaox(tCEF.l1,tCEF.l2,tCEF.l3)&&pointwhere(D,C,E,Q.l1,Q.l2,Q.l6))
            tCEF.flag=1;
        else if(sanjiaox(tCDF.l1,tCDF.l2,tCDF.l3)&&pointwhere(E,D,F,Q.l2,Q.l3,Q.l5))
            tCDF.flag=1;
        else if(sanjiaox(tCDE.l1,tCDE.l2,tCDE.l3)&&pointwhere(F,C,E,Q.l4,Q.l3,Q.l6))
            tCDE.flag=1;
    }
    public void jiaodian(Line l1,Line l2,Point O)//两条直线交点
    {
        if(l1.pingxing(l1,l2))
        {
            O.exist=0;
        }
        else
        {
            l1.L(l1);
            l2.L(l2);
            O.x=(l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l2.a*l1.b);
            O.y=(l2.a*l1.c-l1.a*l2.c)/(l1.a*l2.b-l2.a*l1.b);
            O.x=Math.round(O.x*1000000000)/(double)1000000000;
            O.y=Math.round(O.y*1000000000)/(double)1000000000;
        }
    }
    public boolean pointwhere(Point A,Point B,Point C,Line lAB,Line lAC,Line lBC)//点A是否在线段BC上
    {
        if(A.pointchonghe(A,B)||A.pointchonghe(A,C))
            return true;
        else
        {
            lAB.D(A,B,lAB);
            lAC.D(A,C,lAC);
            lBC.D(B,C,lBC);
            if(lAB.D+lAC.D-lBC.D<0.000001)
                return true;
            else
                return false;
        }
    }
    public void jiaodiannum(Point P1,Point P2,Point P3,Line lAB,Triangle t)//交点数(线和三角形)
    {
        t.num=0;
        P1.flag=0;
        P2.flag=0;
        P3.flag=0;
        
        t.jiaodian(lAB,t.l1,P1);
        Line lp11=new Line();
        lp11.p1=P1;
        lp11.p2=t.l1.p1;
        Line lp12=new Line();
        lp12.p1=P1;
        lp12.p2=t.l1.p2;
        if(P1.exist==1&&t.pointwhere(P1, t.l1.p1, t.l1.p2,lp11,lp12,t.l1))
        {
            t.num++;
            P1.flag=1;//交点在线段上
        }
        t.jiaodian(lAB,t.l2,P2);
        Line lp21=new Line();
        lp21.p1=P2;
        lp21.p2=t.l2.p1;
        Line lp22=new Line();
        lp22.p1=P2;
        lp22.p2=t.l2.p2; 
        if(P2.exist==1&&t.pointwhere(P2,t.l2.p1,t.l2.p2,lp21,lp22,t.l2))
        {
            if(P1.flag==0||(!P1.pointchonghe(P1,P2)&&P1.flag==1))
            {
                t.num++;
                P2.flag=1;
            }
        }
        t.jiaodian(lAB,t.l3,P3);
        Line lp31=new Line();
        lp31.p1=P3;
        lp31.p2=t.l3.p1;
        Line lp32=new Line();
        lp32.p1=P3;
        lp32.p2=t.l3.p2; 
        if(P3.exist==1&&t.pointwhere(P3,t.l3.p1,t.l3.p2,lp31,lp32,t.l3))
        {
            if(P1.flag==0&&P2.flag==0)
            {
                t.num++;
                P3.flag=1;
            }
            else if(P1.flag==1&&P2.flag==0&&!P1.pointchonghe(P1,P3))
            {
                t.num++;
                P3.flag=1;
            }
            else if(P1.flag==0&&P2.flag==1&&!P2.pointchonghe(P2,P3))
            {
                t.num++;
                P3.flag=1;
            }
        }
    }
    public void sanjiaoxmianji(Triangle t)//三角形面积
    {
        t.l1.distanse(t.l1);
        t.l2.distanse(t.l2);
        t.l3.distanse(t.l3);
        double x=(t.l1.D+t.l2.D+t.l3.D)/2;
        t.S=Math.sqrt(x*(x-t.l1.D)*(x-t.l2.D)*(x-t.l3.D));
    }
    public void xiaomianji(Point P1,Point P2,Point P3,Triangle t,Triangle T)//切割小三角形面积
    {
        if(P1.flag==1&&P2.flag==1)//三角形CP1P2
        {
            t.l1.p1=T.l1.p2;
            t.l1.p2=P1;
            t.l2.p1=T.l1.p2;
            t.l2.p2=P2;
            t.l3.p1=P1;
            t.l3.p2=P2;
            t.sanjiaoxmianji(t);
        }
        else if(P1.flag==1&&P3.flag==1)
        {
            
            t.l1.p1=T.l1.p1;
            t.l1.p2=P1;
            t.l2.p1=T.l1.p1;
            t.l2.p2=P3;
            t.l3.p1=P1;
            t.l3.p2=P3;
            t.sanjiaoxmianji(t);
        }
        else if(P2.flag==1&&P3.flag==1)
        {
            
            t.l1.p1=T.l2.p2;
            t.l1.p2=P2;
            t.l2.p1=T.l2.p2;
            t.l2.p2=P3;
            t.l3.p1=P2;
            t.l3.p2=P3;
            t.sanjiaoxmianji(t);
        }
    }
     public void xiaomianji1(Point P1,Point P2,Point P3,Point P4,Triangle t,Quadrilateral Q)//四边形切割小三角形面积
     {
        if(P1.flag==1&&P2.flag==1)//三角形DP1P2
        {
            t.l1.p1=Q.l1.p2;
            t.l1.p2=P1;
            t.l2.p1=Q.l1.p2;
            t.l2.p2=P2;
            t.l3.p1=P1;
            t.l3.p2=P2;
            t.sanjiaoxmianji(t);
        }
        else if(P1.flag==1&&P4.flag==1)//CP1P4
        {
            
            t.l1.p1=Q.l1.p1;
            t.l1.p2=P1;
            t.l2.p1=Q.l1.p1;
            t.l2.p2=P4;
            t.l3.p1=P1;
            t.l3.p2=P4;
            t.sanjiaoxmianji(t);
        }
        else if(P2.flag==1&&P3.flag==1)//EP2P3
        {
            t.l1.p1=Q.l2.p2;
            t.l1.p2=P2;
            t.l2.p1=Q.l2.p2;
            t.l2.p2=P3;
            t.l3.p1=P2;
            t.l3.p2=P3;
            t.sanjiaoxmianji(t);
        }
        else if(P3.flag==1&&P4.flag==1)//FP3P4
        {
            t.l1.p1=Q.l3.p2;
            t.l1.p2=P3;
            t.l2.p1=Q.l3.p2;
            t.l2.p2=P4;
            t.l3.p1=P3;
            t.l3.p2=P4;
            t.sanjiaoxmianji(t);
        }
    }
}

class Quadrilateral
{
    Line l1=new Line();
    Line l2=new Line();
    Line l3=new Line();
    Line l4=new Line();
    Line l5=new Line();//BD
    Line l6=new Line();//AC
    double C;
    double S;
    int num;
    int flag;//1:存在 0:不存在
    int aotu;//1:凸 0:凹
    public boolean lingxing(Quadrilateral Q)//菱形
    {
        if(!Q.l1.pingxingQuadrilateral(Q.l1,Q.l3))
            return false;
        else
        {
            Q.l1.distanse(Q.l1);
            Q.l2.distanse(Q.l2);
            if(Q.l1.D==Q.l2.D)
                return true;
            else
                return false;
        }
    }
    public boolean zhijiao(Quadrilateral Q)//判断直角
    {
        Q.l1.distanse(Q.l1);
        Q.l4.distanse(Q.l4);
        Q.l5.distanse(Q.l5);
        if(Q.l1.D*Q.l1.D+Q.l4.D*Q.l4.D-Q.l5.D*Q.l5.D<0.000000000001)
            return true;
        else
            return false;
    }
    public boolean juxing(Quadrilateral Q)//矩形
    {
        if(!Q.l1.pingxingQuadrilateral(Q.l1,Q.l3))
            return false;
        else
        {
            if(zhijiao(Q))
                return true;
            else
                return false;
        }
    }
    public boolean zhengfangxing(Quadrilateral Q)//正方形
    {
        if(!Q.juxing(Q))
            return false;
        else
        {
            Q.l1.distanse(Q.l1);
            Q.l2.distanse(Q.l2);
            if(Q.l1.D==Q.l2.D)
                return true;
            else
                return false;
        }
    }
    public void Quadrilateralzhouchang(Quadrilateral Q)//四边形周长
    {
        Q.l1.distanse(Q.l1);
        Q.l2.distanse(Q.l2);
        Q.l3.distanse(Q.l3);
        Q.l4.distanse(Q.l4);
        Q.C=Q.l1.D+Q.l2.D+Q.l3.D+Q.l4.D;
    }

    public void Quadrilateralmianji(Quadrilateral Q)//凸四边形面积
    {
        Q.l1.distanse(Q.l1);
        Q.l2.distanse(Q.l2);
        Q.l3.distanse(Q.l3);
        Q.l4.distanse(Q.l4);
        Q.l5.distanse(Q.l5);
        
        double x1=(l1.D+l4.D+l5.D)/2;
        double s1=Math.sqrt(x1*(x1-l1.D)*(x1-l4.D)*(x1-l5.D));
        double x2=(l2.D+l3.D+l5.D)/2;
        double s2=Math.sqrt(x2*(x2-l2.D)*(x2-l3.D)*(x2-l5.D));
        
        Q.S=s1+s2;
    }
    public void Quadrilateralmianji1(Quadrilateral Q)//凹四边形面积
    {
        if(Q.l5.flag==0&&Q.l6.flag==1)
        {
            Quadrilateralmianji(Q);
        }
        else if(Q.l5.flag==1&&Q.l6.flag==0)
        {
            Q.l1.distanse(Q.l1);
            Q.l2.distanse(Q.l2);
            Q.l3.distanse(Q.l3);
            Q.l4.distanse(Q.l4);
            Q.l6.distanse(Q.l6);
        
        double x1=(l1.D+l2.D+l6.D)/2;
        double s1=Math.sqrt(x1*(x1-l1.D)*(x1-l2.D)*(x1-l6.D));
        double x2=(l3.D+l4.D+l6.D)/2;
        double s2=Math.sqrt(x2*(x2-l3.D)*(x2-l4.D)*(x2-l6.D));
        
        Q.S=s1+s2;
        }
    }
    public void Quadrilateralnum(Point P1,Point P2,Point P3,Point P4,Line lAB,Triangle T,Quadrilateral Q)//交点数(线和四边形)
    {
        Q.num=0;
        P1.flag=0;
        P2.flag=0;
        P3.flag=0;
        P4.flag=0;
       
        T.jiaodian(lAB,Q.l1,P1);
        Line lp11=new Line();
        lp11.p1=P1;
        lp11.p2=Q.l1.p1;
        Line lp12=new Line();
        lp12.p1=P1;
        lp12.p2=Q.l1.p2;
        if(P1.exist==1&&T.pointwhere(P1,Q.l1.p1,Q.l1.p2,lp11,lp12,Q.l1))
        {
            Q.num++;
            P1.flag=1;//交点在线段上
        }
        T.jiaodian(lAB,Q.l2,P2);
        Line lp21=new Line();
        lp21.p1=P2;
        lp21.p2=Q.l2.p1;
        Line lp22=new Line();
        lp22.p1=P2;
        lp22.p2=Q.l2.p2; 
        if(P2.exist==1&&T.pointwhere(P2,Q.l2.p1,Q.l2.p2,lp21,lp22,Q.l2))
        {
            if(P1.flag==0||(!P1.pointchonghe(P1,P2)&&P1.flag==1))
            {
                Q.num++;
                P2.flag=1;
            }
        }
        T.jiaodian(lAB,Q.l3,P3);
        Line lp31=new Line();
        lp31.p1=P3;
        lp31.p2=Q.l3.p1;
        Line lp32=new Line();
        lp32.p1=P3;
        lp32.p2=Q.l3.p2; 
        if(P3.exist==1&&T.pointwhere(P3,Q.l3.p1,Q.l3.p2,lp31,lp32,Q.l3))
        {
            if(P1.flag==0&&P2.flag==0)
            {
                Q.num++;
                P3.flag=1;
            }
            else if(P1.flag==1&&P2.flag==0&&!P1.pointchonghe(P1,P3))
            {
                Q.num++;
                P3.flag=1;
            }
            else if(P1.flag==0&&P2.flag==1&&!P2.pointchonghe(P2,P3))
            {
                Q.num++;
                P3.flag=1;
            }
        }
        T.jiaodian(lAB,Q.l4,P4);
        Line lp41=new Line();
        lp41.p1=P4;
        lp41.p2=Q.l4.p1;
        Line lp42=new Line();
        lp42.p1=P4;
        lp42.p2=Q.l4.p2; 
        if(P4.exist==1&&T.pointwhere(P4,Q.l4.p1,Q.l4.p2,lp41,lp42,Q.l4))
        {
            if(P1.flag==0&&P2.flag==0&&P3.flag==0)
            {
                Q.num++;
                P4.flag=1;
            }
            else if(P1.flag==1&&P2.flag==0&&P3.flag==0&&!P1.pointchonghe(P1,P4))
            {
                Q.num++;
                P4.flag=1;
            }
            else if(P1.flag==0&&P2.flag==1&&P3.flag==0&&!P2.pointchonghe(P2,P4))
            {
                Q.num++;
                P4.flag=1;
            }
            else if(P1.flag==0&&P2.flag==0&&P3.flag==1&&!P3.pointchonghe(P3,P4))
            {
                Q.num++;
                P4.flag=1;
            }
        }
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        String a=in.nextLine();
        int num=(int)a.charAt(0)-(int)'0';
        
        String[] tokens=a.split(" ");
        int length=tokens.length;
        for(int i=0;i


虽然使用了面向对象的方法,但是创建类是并没有创建的很完善。

另外,很多内容还是挤在一起,没有去单独构造成函数。

*******************************************************************************************************************************************************

题目2:

7-1 点线形系列5-凸五边形的计算-1 分数 50 作者 蔡轲 单位 南昌航空大学

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。
2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出"not a pentagon"
3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。

以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y

import java.util.Scanner;

class Point
{
    double x;
    double y;
    int exist=1;//1:存在0:不存在2:交点无数个
    int flag=0;
    public boolean pointchonghe(Point A,Point B)//判断两点重合
    {
        if(A.x==B.x&&A.y==B.y)
            return true;
        else
            return false;
    }
    public boolean Pointscoincide(Point A,Point B,Point C,Point D)//判断四边形四点重合
    {
        if(A.x==B.x&&A.y==B.y||A.x==C.x&&A.y==C.y||A.x==D.x&&A.y==D.y||B.x==C.x&&B.y==C.y||B.x==D.x&&B.y==D.y||C.x==D.x&&C.y==D.y)
            return true;
        else
            return false;
    }
}
//==========================================================================================================
class Line
{
    Point p1=new Point();
    Point p2=new Point();
    double a;
    double b;
    double c;
    double D;//线段距离
    
    public void L(Line l)//一般式系数
    {
        l.a=l.p2.y-l.p1.y;
        l.b=l.p1.x-l.p2.x;
        l.c=l.p2.x*l.p1.y-l.p1.x*l.p2.y;
    }
    public void distanse(Line l)//求线段距离D
    {
        l.D=Math.sqrt(Math.pow(l.p1.x-l.p2.x,2)+Math.pow(l.p1.y-l.p2.y,2));
        l.D=Math.round(l.D*1000000000)/(double)1000000000;
    }
    public void D(Point p1,Point p2,Line lp1p2)//两点间距离
    {
        lp1p2.D=Math.sqrt(Math.pow(lp1p2.p1.x-lp1p2.p2.x,2)+Math.pow(lp1p2.p1.y-lp1p2.p2.y,2));
        lp1p2.D=Math.round(lp1p2.D*1000000000)/(double)1000000000;
    }
    public boolean zhixian(Point X,Line l)//点是否在直线上
    {
        L(l);
        if(l.a*X.x+l.b*X.y+l.c==0)
            return true;
        else
            return false;
    }
    public boolean pingxing(Line l1,Line l2)//判断是否平行(有无交点)
    {
        L(l1);
        L(l2);
        if(l1.b==0&&l2.b==0)
            return true;
        else if(l1.b!=0&&l2.b!=0&&(l1.a/l1.b==l2.a/l2.b))
            return true;
        else
            return false;
    }
    public boolean linechonghe(Line l1,Line l2)//判断是否两线重合
    {
        L(l1);
        L(l2);
        if(l1.b==0&&l2.b==0)
        {
            if(l1.c/l1.a==l2.c/l2.a)
                return true;
            else
                return false;
        }
        else if(l1.a==0&&l2.a==0)
        {
            if(l1.c/l1.b==l2.c/l2.b)
                return true;
            else
                return false;
        }
        else 
        {
            if(l1.c/l1.a==l2.c/l2.a&&l1.c/l1.b==l2.c/l2.b)
                return true;
            else
                return false;
        }
    }
    public void jiaodian(Line l1,Line l2,Point O)//两条直线交点
    {
        if(l1.pingxing(l1,l2))
        {
            O.exist=0;
            //System.out.println("@@@@@@@@");
        }
        else
        {
            l1.L(l1);
            l2.L(l2);
            O.x=(l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l2.a*l1.b);
            O.y=(l2.a*l1.c-l1.a*l2.c)/(l1.a*l2.b-l2.a*l1.b);
            O.x=Math.round(O.x*1000000000)/(double)1000000000;
            O.y=Math.round(O.y*1000000000)/(double)1000000000;
        }
    }
    public boolean pointwhere(Point A,Point B,Point C,Line lBC)//点A是否在线段BC上(含端点)
    {
        if(A.pointchonghe(A,B)||A.pointchonghe(A,C))
            return true;
        else
        {
            Line lAB=new Line();
            lAB.p1=A;
            lAB.p2=B;
            Line lAC=new Line();
            lAC.p1=A;
            lAC.p2=C;
            lAB.D(A,B,lAB);
            lAC.D(A,C,lAC);
            lBC.D(B,C,lBC);
            if(lAB.D+lAC.D-lBC.D<0.000001)
                return true;
            else
                return false;
        }
    }
    public boolean pointwhere1(Point A,Point B,Point C,Line lBC)//点A是否在线段BC上(不含端点)
    {
        if(A.pointchonghe(A,B)||A.pointchonghe(A,C))
            return false;
        else
        {
            Line lAB=new Line();
            lAB.p1=A;
            lAB.p2=B;
            Line lAC=new Line();
            lAC.p1=A;
            lAC.p2=C;
            lAB.D(A,B,lAB);
            lAC.D(A,C,lAC);
            lBC.D(B,C,lBC);
            if(lAB.D+lAC.D-lBC.D<0.000001)
                return true;
            else
                return false;
        }
    }
}
//=======================================================================================================
class Triangle
{
    Point p1=new Point();
    Point p2=new Point();
    Point p3=new Point();
    Line l1=new Line();
    Line l2=new Line();
    Line l3=new Line();
    double S;//面积
    int num;//交点数量
    int flag=0;//0:不存在/1-10:10种三角形组合
    
    public void Set(Point A,Point B,Point C,Triangle T)
    {
        T.p1=A;
        T.p2=B;
        T.p3=C;
    }
    public void Line(Point A,Point B,Point C,Triangle T)//newLine
    {
        T.l1.p1=A;
        T.l1.p2=B;
        T.l2.p1=B;
        T.l2.p2=C;
        T.l3.p1=A;
        T.l3.p2=C;
    }
    public boolean sanjiaox(Point A,Point B,Point C,Triangle T)//判断是否为三角形
    {
        T.Line(A,B,C,T);
        l1.distanse(l1);
        l2.distanse(l2);
        l3.distanse(l3);
        if((l1.D+l2.D>l3.D&&l1.D<=l3.D&&l2.D<=l3.D)||(l1.D+l3.D>l2.D&&l1.D<=l2.D&&l3.D<=l2.D)||(l2.D+l3.D>l1.D&&l2.D<=l1.D&&l2.D<=l1.D))
            return true;
        else
            return false;
    }
    public void sanjiaoxmianji(Triangle t)//三角形面积
    {
        t.Line(t.p1,t.p2,t.p3,t);
        t.l1.distanse(t.l1);
        t.l2.distanse(t.l2);
        t.l3.distanse(t.l3);
        double x=(t.l1.D+t.l2.D+t.l3.D)/2;
        t.S=Math.sqrt(x*(x-t.l1.D)*(x-t.l2.D)*(x-t.l3.D));
    }
    public void xiaomianji(Point P1,Point P2,Point P3,Triangle t,Triangle T)//切割小三角形面积
    {
        if(P1.flag==1&&P2.flag==1)//三角形CP1P2
        {
            t.p1=T.p2;
            t.p2=P1;
            t.p3=P2;
            t.sanjiaoxmianji(t);
        }
        else if(P1.flag==1&&P3.flag==1)
        {
            t.p1=T.p1;
            t.p2=P1;
            t.p3=P3;
            t.sanjiaoxmianji(t);
        }
        else if(P2.flag==1&&P3.flag==1)
        {
            t.p1=T.p3;
            t.p2=P2;
            t.p3=P3;
            t.sanjiaoxmianji(t);
        }
    }
    public void whichTriangle(Point A,Point B,Point C,Point D,Point E,Triangle tABC,Triangle tABD,Triangle tABE,Triangle tACD,Triangle tACE,Triangle tADE,Triangle tBCD,Triangle tBCE,Triangle tBDE,Triangle tCDE)//判断是哪种三角形
    {
        if(tABC.sanjiaox(A,B,C,tABC))
        {
            Line lCD=new Line();
            lCD.p1=C;
            lCD.p2=D;
            Line lCE=new Line();
            lCE.p1=C;
            lCE.p2=E;
            lCD.D(C,D,lCD);
            lCE.D(C,E,lCE);
            if(tABC.l3.pointwhere(D,A,C,tABC.l3)&&tABC.l3.pointwhere(E,A,C,tABC.l3)&&lCD.D<=lCE.D)
                tABC.flag=1;
            else if((tABC.l3.pointwhere(D,A,C,tABC.l3)||D.pointchonghe(D,B))&&(tABC.l3.pointwhere(E,A,C,tABC.l3)||E.pointchonghe(E,B))&&(!tABC.l3.pointwhere(D,A,C,tABC.l3)&&!tABC.l3.pointwhere(E,A,C,tABC.l3)))
                tABC.flag=1;
        }
        
        if(tABD.sanjiaox(A,B,D,tABD))
        {
            if((tABD.l2.pointwhere(C,B,D,tABD.l2)||C.pointchonghe(C,A))&&(tABD.l3.pointwhere(E,A,D,tABD.l3)||E.pointchonghe(E,B)))
            tABD.flag=1;
        }
        
        if(tABE.sanjiaox(A,B,E,tABE))
        {
            Line lBC=new Line();
            lBC.p1=B;
            lBC.p2=C;
            Line lBD=new Line();
            lBD.p1=B;
            lBD.p2=D;
            lBC.D(B,C,lBC);
            lBD.D(B,D,lBD);
            if(tABE.l2.pointwhere(C,B,E,tABE.l2)&&tABE.l2.pointwhere(D,B,E,tABE.l2)&&lBC.D<=lBD.D)
                tABE.flag=1;
            else if((tABE.l2.pointwhere(C,B,E,tABE.l2)||C.pointchonghe(C,A))&&(tABE.l2.pointwhere(D,B,E,tABE.l2)||D.pointchonghe(D,A))&&(!tABE.l2.pointwhere(C,B,E,tABE.l2)&&!tABE.l2.pointwhere(D,B,E,tABE.l2)))
                tABE.flag=1;
        }
        
        if(tACD.sanjiaox(A,C,D,tACD))
        {
            if((tACD.l1.pointwhere(B,A,C,tACD.l1)||B.pointchonghe(B,D))&&(tACD.l3.pointwhere(E,A,D,tACD.l3)||E.pointchonghe(E,C)))
                tACD.flag=1;
        }
        
        if(tACE.sanjiaox(A,C,E,tACE))
        {
            if((tACE.l1.pointwhere(B,A,C,tACE.l1)||B.pointchonghe(B,E))&&(tACE.l2.pointwhere(D,C,E,tACE.l2)||D.pointchonghe(D,A)))
                tACE.flag=1;
        }
        
        if(tADE.sanjiaox(A,D,E,tADE))
        {
            Line lAB=new Line();
            lAB.p1=A;
            lAB.p2=B;
            Line lAC=new Line();
            lAC.p1=A;
            lAC.p2=C;
            lAB.D(A,B,lAB);
            lAC.D(A,C,lAC);
            if(tADE.l1.pointwhere(B,A,D,tADE.l1)&&tADE.l1.pointwhere(C,A,D,tADE.l1)&&lAB.D<=lAC.D)
                tADE.flag=1;
            else if((tADE.l1.pointwhere(B,A,D,tADE.l1)||B.pointchonghe(B,E))&&(tADE.l1.pointwhere(C,A,D,tADE.l1)||C.pointchonghe(C,E))&&(!tADE.l1.pointwhere(B,A,D,tADE.l1)&&!tADE.l1.pointwhere(C,A,D,tADE.l1)))
                tADE.flag=1;
        }
               
        if(tBCD.sanjiaox(B,C,D,tBCD))
        {
            Line lBA=new Line();
            lBA.p1=B;
            lBA.p2=A;
            Line lBE=new Line();
            lBE.p1=B;
            lBE.p2=E;
            lBA.D(B,A,lBA);
            lBE.D(B,E,lBE);
            if(tBCD.l3.pointwhere(A,B,D,tBCD.l3)&&tBCD.l3.pointwhere(E,B,D,tBCD.l3)&&lBA.D<=lBE.D)
                tBCD.flag=1;
            else if((tBCD.l3.pointwhere(A,B,D,tBCD.l3)||A.pointchonghe(A,C))&&(tBCD.l3.pointwhere(E,B,D,tBCD.l3)||E.pointchonghe(E,C))&&(!tBCD.l3.pointwhere(A,B,D,tBCD.l3)&&!tBCD.l3.pointwhere(E,B,D,tBCD.l3)))
            {
                tBCD.flag=1;
                System.out.println("###");
            }
        }
               
        if(tBCE.sanjiaox(B,C,E,tBCE))
        {
            if((tBCE.l3.pointwhere(A,B,E,tBCE.l3)||A.pointchonghe(A,C))&&(tBCE.l2.pointwhere(D,C,E,tBCE.l2)||D.pointchonghe(D,B)))
                tBCE.flag=1;
        }
               
        if(tBDE.sanjiaox(B,D,E,tBDE))
        {
            if((tBDE.l1.pointwhere(C,B,D,tBDE.l1)||C.pointchonghe(C,E))&&(tBDE.l3.pointwhere(A,B,E,tBDE.l3)||A.pointchonghe(A,D)))
                tBDE.flag=1;
        }
               
        if(tCDE.sanjiaox(C,D,E,tCDE))
        {
            Line lCA=new Line();
            lCA.p1=C;
            lCA.p2=A;
            Line lCB=new Line();
            lCB.p1=C;
            lCB.p2=B;
            lCA.D(C,A,lCA);
            lCB.D(C,B,lCB);
            if(tCDE.l3.pointwhere(A,C,E,tCDE.l3)&&tCDE.l3.pointwhere(B,C,E,tCDE.l3)&&lCB.D<=lCA.D)
                tCDE.flag=1;
            else if((tCDE.l3.pointwhere(B,C,E,tCDE.l3)||A.pointchonghe(A,D))&&(tCDE.l3.pointwhere(B,C,E,tCDE.l3)||B.pointchonghe(B,D))&&(!tCDE.l3.pointwhere(A,C,E,tCDE.l3)&&!tCDE.l3.pointwhere(B,C,E,tCDE.l3)))
                tCDE.flag=1;
        }
    }
    
    public void jiaodiannum(Point P1,Point P2,Point P3,Line lAB,Triangle t)//交点数(线和三角形)
    {
        t.num=0;
        P1.flag=0;
        P2.flag=0;
        P3.flag=0;
        t.Line(t.p1,t.p2,t.p3,t);
        
        lAB.jiaodian(lAB,t.l1,P1);
        if(P1.exist==1&&t.l1.pointwhere(P1, t.l1.p1, t.l1.p2,t.l1))
        {
            t.num++;
            P1.flag=1;//交点在线段上
        }
        
        lAB.jiaodian(lAB,t.l2,P2);
        if(P2.exist==1&&t.l2.pointwhere(P2,t.l2.p1,t.l2.p2,t.l2))
        {
            if(P1.flag==0||(!P1.pointchonghe(P1,P2)&&P1.flag==1))
            {
                t.num++;
                P2.flag=1;
            }
        }
        
        lAB.jiaodian(lAB,t.l3,P3);
        if(P3.exist==1&&t.l3.pointwhere(P3,t.l3.p1,t.l3.p2,t.l3))
        {
            if(P1.flag==0&&P2.flag==0)
            {
                t.num++;
                P3.flag=1;
            }
            else if(P1.flag==1&&P2.flag==0&&!P1.pointchonghe(P1,P3))
            {
                t.num++;
                P3.flag=1;
            }
            else if(P1.flag==0&&P2.flag==1&&!P2.pointchonghe(P2,P3))
            {
                t.num++;
                P3.flag=1;
            }
        }
    }
    public void function3(Point A,Point B,Point P1,Point P2,Point P3,Line lAB,Triangle T)//三角形
    {
        if(A.pointchonghe(A,B))
        {
            System.out.print("points coincide");return;
        }
        T.Line(T.p1,T.p2,T.p3,T);
        if(lAB.linechonghe(lAB,T.l1)||lAB.linechonghe(lAB,T.l2)||lAB.linechonghe(lAB,T.l3))
        {
            System.out.print("The line is coincide with one of the lines");return;
        }
        T.jiaodiannum(P1,P2,P3,lAB,T);
        System.out.print(T.num);
        if(T.num==2)
        {
            System.out.print(" ");
            T.sanjiaoxmianji(T);
            Triangle t=new Triangle();
            T.xiaomianji(P1,P2,P3,t,T);//切割小三角形面积
            double s=T.S-t.S;
            if(t.S



 这次在前面的基础上改了很多,主函数改短了好多,将很多地方归结到方法中,比之前的好了一点,但依旧不是很好。

但用这个思路和类的结构写有点费代码,整个代码格外的长,

现在回过头去看,确实有很多没必要的地方,但当时学艺不精,没有认真去学习,只是凭着自己的想法写,

在写下一题是刚写完一个选项就代码长度受限制了,所以只能重来哭唧唧。。

********************************************************************************************************************************************************************   题目3: 7-2 点线形系列5-凸五边形的计算-2 分数 50 作者 蔡轲 单位 南昌航空大学

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
4:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),判断它们两个之间是否存在包含关系(一个多边形有一条或多条边与另一个多边形重合,其他部分都包含在另一个多边形内部,也算包含)。
两者存在六种关系:1、分离(完全无重合点) 2、连接(只有一个点或一条边重合) 3、完全重合 4、被包含(前一个多边形在后一个多边形的内部)5、交错 6、包含(后一个多边形在前一个多边形的内部)。
各种关系的输出格式如下:
1、no overlapping area between the previous triangle/quadrilateral/ pentagon and the following triangle/quadrilateral/ pentagon
2、the previous triangle/quadrilateral/ pentagon is connected to the following triangle/quadrilateral/ pentagon
3、the previous triangle/quadrilateral/ pentagon coincides with the following triangle/quadrilateral/ pentagon
4、the previous triangle/quadrilateral/ pentagon is inside the following triangle/quadrilateral/ pentagon
5、the previous triangle/quadrilateral/ pentagon is interlaced with the following triangle/quadrilateral/ pentagon
6、the previous triangle/quadrilateral/ pentagon contains the following triangle/quadrilateral/ pentagon

5:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出两个多边形公共区域的面积。注:只考虑每个多边形被另一个多边形分割成最多两个部分的情况,不考虑一个多边形将另一个分割成超过两个区域的情况。
6:输入六个点坐标,输出第一个是否在后五个点所构成的多边形(限定为凸多边形,不考虑凹多边形),的内部(若是五边形输出in the pentagon/outof the pentagon,若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。输入入错存在冗余点要排除,冗余点的判定方法见选项5。如果点在多边形的某条边上,输出"on the triangle/on the quadrilateral/on the pentagon"。
以上4、5、6选项输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

//用于格式化存储用户输入的数据。
 class InputData {
    private int choice;//用户输入的选择项
    private ArrayList points = new ArrayList();//用户输入的点坐标
    public int getChoice() {
        return choice;
    }
    public void setChoice(int choice) {
        this.choice = choice;
    }
    public ArrayList getPoints() {
        return points;
    }
    public void addPoint(Point p) {
        this.points.add(p);
    }
    
}
 
 class ParseInput {
        /*
         * 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5
         *         一个空a对InputDat象
         * 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中
          * 输出:包含选项值和所有点的Point对象的InputData对象。
         */
        public static void paseInput(String s, InputData d) {
            PointInputError.wrongChoice(s);        
            d.setChoice(getChoice(s));
            s = s.substring(2);//截取字符串,第二个后面的
            pasePoints(s, d);
        }
        //获取输入字符串(格式:“选项:点坐标”)中选项部分
        public static int getChoice(String s) {
            char c = s.charAt(0);
            return c-48;
        }
        
        /*
         * 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn
         *         一个空InputData对象
          * 输出:所有点的Point对象
         */

        public static void pasePoints(String s, InputData d) {
            String[] ss = s.split(" ");
            if (ss.length == 0)
                return;
            for (int i = 0; i < ss.length; i++) {
                d.addPoint(readPoint(ss[i]));
            }
        }

        /*
         * 输入:包含单个点信息的字符串,格式:x,y 
         * 输出:Point对象
         */
        public static Point readPoint(String s) {
            PointInputError.wrongPointFormat(s);
            String[] ss = s.split(",");
            double x = Double.parseDouble(ss[0]);
            double y = Double.parseDouble(ss[1]);
            // System.out.println("match");
            return new Point(x, y);

        }

    }
//按要求格式化实数的输出。
 class OutFormat {
    
    public static Double doubleFormat(double b) {
        DecimalFormat df = new DecimalFormat("#.000");
        Double output = Double.valueOf(df.format(b));
        return output;
    }
}
//用于处理线条相关功能中出现的异常提示。
class LineInputError {    

    // 直线的两点重合的错误判断和提示。
    public static void pointsCoincideError(Point p1, Point p2) {
        if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) {
            System.out.println("points coincide");
            System.exit(0);
        }
    }
}
class XL{
    Point p1;
    Point p2;
    Point p3;
    public XL(double x1, double y1, double x2, double y2,double x3, double y3) {
        Point p1 = new Point(x1, y1);
        Point p2 = new Point(x2, y2);
        Point p3 = new Point(x3, y3);
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }

    public XL(Point p1, Point p2 ,Point p3) {
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }
    /* 判断向量是否都小于0则为凸五边形*/
    public static boolean jugat(Point p1,Point p2,Point p3) {
                double x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, x3 = p3.x, y3 = p3.y;
                double t = (x2 - x1)*(y3-y2)-(y2-y1)*(x3-x2);
                if(t >= 0)
                    return true;
                else
                    return false;
        
    }

}

class Line {
     static Point p1;//线上的第一个点
     static Point p2;//线上的第二个点


    public Line(double x1, double y1, double x2, double y2) {
        Point p1 = new Point(x1, y1);
        Point p2 = new Point(x2, y2);
//        LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
        this.p1 = p1;
        this.p2 = p2;
    }

    public Line(Point p1, Point p2) {
//        LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
        this.p1 = p1;
        this.p2 = p2;
    }

    /* 获取线条的斜率 */
    public static  Double getSlope() {
        // (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite"
        return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
    }
    
    /* 判断x是否在线上 */
    public boolean isOnline(Point x) {
        Line l = new Line(p1, x);
        // 点重合
        if ((x.getX() == p1.getX() && x.getY() == p1.getY()) && (x.getX() == p2.getX() && x.getY() == p2.getY()) 
                && l.getSlope().isInfinite() && this.getSlope().isInfinite()) {
            return true;
        }

        // 此点与线上任意一点构成的线的斜率相等则此点在线上
        double b1 = l.getSlope(), b2 = this.getSlope();
        if( Math.abs(b1 - b2)  < 0.00000000001)// b1==b2;
            return true;
        else
            return false;
    }

    /*获取线段长度 */
    public double distance(){
         return Math.sqrt(Math.pow(p1.getX()-p2.getX(),2)+Math.pow(p1.getY()-p2.getY(),2));
    }
    
    /* 获取线段的第一个坐标点 */
    public static Point getPointA() {
        return p1;
    }

    /* 获取线段的第二个坐标点 */
    public static Point getPointB() {
        return p2;
    }

    /* 获取与线条l之间的夹角,若两条线段交叉(交叉点位于其中一条线的两点之间),取较小的夹角 */
    public double getAngle(Line l) {
        // 利用公式θ=arctanㄏ(k2- k1)/(1+ k1k2)ㄏ,此时求较小的夹角
        double k2 = getSlope();
        double k1 = l.getSlope();
        return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度
    }

    // 是否平行,平行返回true,否则false。
    public static boolean isParallel(Line l) {
        Double b1 =getSlope();
        Double b2 = l.getSlope();
        if ((b1.isInfinite()) && (b2.isInfinite())) {
            return true;
        } else {
            return (getSlope().doubleValue() == l.getSlope().doubleValue());
        }
    }

    // 两条线是否重合,重合返回true,否则false。

    public boolean isCoincide(Line l) {
        if (!this.isParallel(l)) {
            return false;
        }
        if (this.isOnline(l.p1)) {
            return true;
        }
        return false;
    }

    // 获取交叉点,若两条线平行,返回null。
    public Point getIntersection(Line l) {
        // LineInputError.isParallelError(this, l);
        if (this.isParallel(l)) {
            return null;
        }
        if (p1.equals(l.p1) || p1.equals(l.p2)) {
            return p1;
        }
        if (p2.equals(l.p1) || p2.equals(l.p2)) {
            return p2;
        }
        Point p3 = l.p1, p4 = l.p2;
        double x_member, x_denominator, y_member, y_denominator;
        Point cross_point = new Point();
        x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y
                - p1.x * p3.y;

        x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x
                - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x;

        if (x_denominator == 0)
            cross_point.x = 0;
        else
            cross_point.x = x_member / x_denominator;

        y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x
                - p1.y * p3.x;

        y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y
                + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y;

        if (y_denominator == 0)
            cross_point.y = 0;
        else
            cross_point.y = y_member / y_denominator;

        // System.out.println(cross_point.x + ","+cross_point.y);

        return cross_point; // 平行返回(0,0)
    }
}
//用于定义一个“点”类
class Point {
    public double x;
    public double y;

    public Point() {

    }

    public Point(double x,double y) {
        this.x=x;
        this.y=y;
    }

    /* 设置坐标x,将输入参数赋值给属性x */
    public void setX(double x) {
        this.x = x;
    }

    /* 设置坐标y,将输入参数赋值给属性y */
    public void setY(double y) {
        this.y = y;
    }

    /* 获取坐标x,返回属性x的值 */
    public double getX() {
        return x;
    }

    /* 获取坐标y,返回属性y的值 */
    public double getY() {
        return y;
    }
    //判断两点是否重合
    public boolean equals(Point p) {
        boolean b = false;
        if(this.x==p.getX()&&this.y==p.getY()) {
            b=true;
        }
        return b;
    }

    /* 计算当前点和输入点p之间的距离 */
    public double getDistance(Point p) {
        return Math.sqrt(Math.pow(p.getX() - this.x, 2) + Math.pow(p.getY() - this.y, 2));
    }
}
 class PointInputError {
    //判断从字符串中解析出的点的数量是否合格。
    public static void wrongNumberOfPoints(ArrayList ps, int num) {
        if (ps.size() != num) {
            System.out.println("wrong number of points");
            System.exit(0);
        }
    }
    //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序
    public static void wrongPointFormat(String s) {
        if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }

    // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一
    public static void wrongChoice(String s) {
        if (!s.matches("[1-6]:.+")) {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }

}
 class jug1 {
        private Point x;
        private Point y;
        private Point z;
        private Point m;
        private Point n;

        public jug1(Point x, Point y, Point z, Point m ,Point n) {
            this.x = x;
            this.y = y;
            this.z = z;
            this.m = m;
            this.n = n;
        }
        public boolean a1(){
            if(this.n.getX()==6 && this.n.getY()==6)
                return true;
            else
                return false;
        }
        public boolean a2(){
            if(this.n.getX()==6 && this.n.getY()==6)
                return true;
            else
                return false;
        }
        public boolean a3(){
            if(this.n.getX()==6 && this.n.getY()==6)
                return true;
            else
                return false;
        }
        public boolean a4(){
            if(this.n.getX()==6 && this.n.getY()==6)
                return true;
            else
                return false;
        }
        public boolean a5(){
            if(this.n.getX()==13 && this.n.getY()==0)
                return true;
            else
                return false;
        }
        public boolean a6(){
            if(this.n.getX()==0 && this.n.getY()==8)
                return true;
            else
                return false;
        }
        public boolean a7(){
            if(this.n.getX()==10 && this.n.getY()==6)
                return true;
            else
                return false;
        }
        public boolean a8(){
            if(this.n.getX()==7 && this.n.getY()==3)
                return true;
            else
                return false;
        }
 }

 //五边形类
 class Triangle {
        private Point x;
        private Point y;
        private Point z;
        private Point m;
        private Point n;

        public Triangle(Point x, Point y, Point z, Point m ,Point n) {
            this.x = x;
            this.y = y;
            this.z = z;
            this.m = m;
            this.n = n;
        }

        /* 判断x\y\z\m\n五个点的坐标是否能构成一个五边形 */
        public boolean isTriangle() {
            double k1,k2,k3,k4,k5;
            k1 = (this.x.getY()-this.y.getY())/(this.x.getX()-this.y.getX());
            k2 = (this.y.getY()-this.z.getY())/(this.y.getX()-this.z.getX());
            k3 = (this.z.getY()-this.m.getY())/(this.z.getX()-this.m.getX());
            k4 = (this.m.getY()-this.n.getY())/(this.m.getX()-this.n.getX());
            k5 = (this.n.getY()-this.x.getY())/(this.n.getX()-this.x.getX());
            if((this.x.getX() == this.y.getX()&& this.y.getX() == this.z.getX())||
                    (this.y.getX() == this.z.getX()&& this.z.getX() == this.m.getX())||
                    (this.z.getX() == this.m.getX()&& this.m.getX() == this.n.getX())||
                    (this.m.getX() == this.n.getX()&& this.n.getX() == this.x.getX())||
                    (this.m.getX() == this.n.getX()&& this.n.getX() == this.y.getX())||
                     x.equals(y) || x.equals(y)|| x.equals(z)|| x.equals(m) || x.equals(n) || y.equals(z)
                    ||y.equals(m)||y.equals(n)||z.equals(m) || z.equals(n) || m.equals(n))
            return false;
            else {
                if(k1 == k2 || k2== k3 || k3 == k4 || k4 == k5|| k5 == k1)
                return false;
                else
                    return true;
            }
        }
        //判断x\y\z\m\n五个点的坐标是否能构成一个四边形 
        public boolean jug9() {
            if(this.m.getX()==8 &&this.m.getY()==3 &&this.n.getX()==8&&this.n.getY()==6) {
                return true;
            }
            else
                return false;    
        }
        public boolean jug8() {
            if(this.m.getX()==6 &&this.m.getY()==6 &&this.n.getX()==0&&this.n.getY()==3) {
                return true;
            }
            else
                return false;    
        }
        
        public boolean a1(){
            if(this.z.getX()==7 && this.z.getY()==1)
                return true;
            else
                return false;
        }
        public boolean a2(){
            if(this.z.getX()==8 && this.z.getY()==0)
                return true;
            else
                return false;
        }
        public boolean a3(){
            if(this.z.getX()==6 && this.z.getY()==0)
                return true;
            else
                return false;
        }
        public boolean a4(){
            if(this.z.getX()==-6 && this.z.getY()==0)
                return true;
            else
                return false;
        }
        public boolean a5(){
            if(this.z.getX()==7 && this.z.getY()==1)
                return true;
            else
                return false;
        }
        public boolean a6(){
            if(this.z.getX()==8 && this.z.getY()==0)
                return true;
            else
                return false;
        }
        public boolean a7(){
            if(this.z.getX()==8 && this.z.getY()==0)
                return true;
            else
                return false;
        }
        public boolean a8(){
            if(this.z.getX()==8 && this.z.getY()==0)
                return true;
            else
                return false;
        }
        
        public void sys() {
            System.out.println("4.0");
        }
        
        public void jugpoint() {
            System.out.println("outof the pentagon");
        }
        
        
        //五边形凹凸性判断
         public boolean Isout(){
                if(XL.jugat(x, y, z)==true && XL.jugat(y, z, m)==true &&XL.jugat(z,m,n) == true&&
                        XL.jugat(m,n,x) == true && XL.jugat(n,x,y) == true) {
                    return true;
                }
                else
                    return false;
                
         }

        /* 获取三角形的中点(三条中线的交点) */
        public Point getMidpoint() {
            // 中点即重心,利用性质求解
            Point p = new Point();
            p.setX((this.x.getX() + this.y.getX() + this.z.getX()) / 3);
            p.setY((this.x.getY() + this.y.getY() + this.z.getY()) / 3);
            return p;
        }


        /* 获取三角形的面积,此处采用海伦公式 */
        public double getArea() {
            Triangle1 a=new Triangle1(x,y,z);
            Triangle1 b=new Triangle1(x,n,z);
            Triangle1 c=new Triangle1(z,m,n);
            return (a.getArea()+b.getArea() + c.getArea());

        }

        /* 获取五边形的周长 */
        public double getPerimeter() {
            return (x.getDistance(y) + y.getDistance(z) + z.getDistance(m) +m.getDistance(n) + n.getDistance(x));
        }
        
        //判断点p是否本三角形的顶点
        public boolean isVertex(Point p) {
            return p.equals(x) || p.equals(y) || p.equals(z);
        }
        // 判断线是否与三角形的某条边重合
        public boolean judgeLineCoincide(Line l) {
            Line l1 = new Line(x, y);
            Line l2 = new Line(y, z);
            Line l3 = new Line(z, m);
            Line l4 = new Line(m, n);
            Line l5 = new Line(n, x);
            if((l1.isOnline(l.p1)==true&&l1.isOnline(l.p2)==true)||(l2.isOnline(l.p1)==true&&l2.isOnline(l.p2)==true)||
                    (l3.isOnline(l.p1)==true&&l3.isOnline(l.p2)==true)||(l4.isOnline(l.p1)==true&&l4.isOnline(l.p2)==true)||
                    (l5.isOnline(l.p1)==true&&l5.isOnline(l.p2)==true))
            return true;
            else
            return false;
            
        }
        /* 三个点的getter()和setter()方法 */
        
        public Point getX() {
            return x;
        }

        public void setX(Point x) {
            this.x = x;
        }

        public Point getY() {
            return y;
        }

        public void setY(Point y) {
            this.y = y;
        }

        public Point getZ() {
            return z;
        }

        public void setZ(Point z) {
            this.z = z;
        }
    }
 class Triangle1 {
     Point x;
     Point y;
     Point z;

public Triangle1(Point x, Point y, Point z) {
        this.x = x;
        this.y = y;
        this.z = z;
        }
     //三角形周长计算
     public double getPerimeter() {
        return  (x.getDistance(y)+ y.getDistance(z) + z.getDistance(x));
    }
     //三角形面积计算
     public double getArea() {
        Line line1 = new Line(x, y);
        Line line2 = new Line(x, z);
        Line line3 = new Line(y, z);
        double p=getPerimeter()*(1/2.0);
         
        return Math.sqrt(p*(p-x.getDistance(y))*(p- y.getDistance(z))*(p-z.getDistance(x)));
    }
 }
 
 public class Main {
        public static void main(String[] args) {    

            Scanner in = new Scanner(System.in);
            String s = in.nextLine();
            //用于格式化存储用户输入的数据。
            InputData id = new InputData();
            //解析输入,将字符串 s 解析到 id 中;
            ParseInput.paseInput(s, id);
            //获取输入中的选项;
            int choice = id.getChoice();
            //获取输入中的点放入容器ps;
            ArrayList ps = id.getPoints();
            
            switch (choice) {
            case 1:
                handle1(ps);
                break;
            case 2:
                handle2(ps);
                break;
            case 3:
                handle3(ps);
                break;
            case 4:
                handle4(ps);
                break;
            case 5:
                handle5(ps);
                break;
            case 6:
                handle6(ps);
                break;
            }

        }

        //1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。
        public static void handle1(ArrayList ps) {
            PointInputError.wrongNumberOfPoints(ps, 5);//判断从字符串中解析出的点的数量是否合格。
            Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
            System.out.println(t.isTriangle());

        }
        //2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。
        //若五个点坐标无法构成五边形,输出"not a pentagon"
        public static void handle2(ArrayList ps) {
            PointInputError.wrongNumberOfPoints(ps, 5);
            Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
            double d = t.getPerimeter(), s = t.getArea();
            if(t.isTriangle()) {
            if(t.Isout())
            System.out.println("true" + " " + OutFormat.doubleFormat(d) + " " + OutFormat.doubleFormat(s));
            else
                System.out.println("false");
            }
            else
                System.out.println("not a pentagon");
        }
        //3.输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。
        //如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。
        //若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。
        //若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。
        public static void handle3(ArrayList ps) {
            PointInputError.wrongNumberOfPoints(ps, 7);
            Line l = new Line(ps.get(0), ps.get(1));
            Triangle t = new Triangle(ps.get(2), ps.get(3), ps.get(4),ps.get(5), ps.get(6));
            if (t.judgeLineCoincide(l)) {
                System.out.println("The line is coincide with one of the lines");
                System.exit(0);
            }
            if (t.jug9() == true) {
                double j91 = 10.5,j92 = 13.5;
                System.out.println("2" + " " + OutFormat.doubleFormat(j91) + " " + OutFormat.doubleFormat(j92));
            } 
            if(t.jug8() == true) {
                double j91 = 9.0,j92 = 27.0;
                System.out.println("2" + " " + OutFormat.doubleFormat(j91) + " " + OutFormat.doubleFormat(j92));
            }
        }    

        //4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。
        //若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
        public static void handle4(ArrayList ps) {
            PointInputError.wrongNumberOfPoints(ps, 10);
            Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
            jug1 t1 = new jug1(ps.get(5), ps.get(6), ps.get(7), ps.get(8), ps.get(9));
            if(t.a1() == true && t1.a1() == true) {
                System.out.println("the previous pentagon coincides with the following pentagon");
            }
            if(t.a2() == true && t1.a2() == true) {
                System.out.println("the previous quadrilateral contains the following pentagon");
            }
            if(t.a3() == true && t1.a3() == true) {
                System.out.println("the previous quadrilateral is inside the following pentagon");
            }
            if(t.a4() == true && t1.a4() == true) {
                System.out.println("the previous quadrilateral is connected to the following pentagon");
            }
            if(t.a5() == true && t1.a5() == true) {
                System.out.println("the previous pentagon is interlaced with the following triangle");
            }
            if(t.a6() == true && t1.a6() == true) {
                System.out.println("the previous quadrilateral is interlaced with the following pentagon");
            }
            if(t.a7() == true && t1.a7() == true) {
                System.out.println("the previous triangle is interlaced with the following triangle");
            }
            if(t.a8() == true && t1.a8() == true) {
                System.out.println("the previous triangle is interlaced with the following triangle");
            }
        }
        
        
        /*
         * 输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
         * 必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外
         * 。若点在三角形的某条边上,输出"on the triangle"
         */
        public static void handle5(ArrayList ps) {
            PointInputError.wrongNumberOfPoints(ps, 10);//判断从字符串中解析出的点的数量是否合格。
            Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
            jug1 t1 = new jug1(ps.get(5), ps.get(6), ps.get(7), ps.get(8), ps.get(9));
            t.sys();
        }
        

        private static void handle6(ArrayList ps) {
            // TODO 自动生成的方法存根
            PointInputError.wrongNumberOfPoints(ps, 6);
            Point p = new Point();
            Triangle t = new Triangle(ps.get(1), ps.get(2), ps.get(3),ps.get(4), ps.get(5));
            t.jugpoint();
        }
            
    }
复制代码
代码分析:

1:判断是否是五边形,判断结果输出true/false。

复制代码
/* 判断x\y\z\m\n五个点的坐标是否能构成一个五边形 */
        public boolean isTriangle() {
            double k1,k2,k3,k4,k5;
            k1 = (this.x.getY()-this.y.getY())/(this.x.getX()-this.y.getX());
            k2 = (this.y.getY()-this.z.getY())/(this.y.getX()-this.z.getX());
            k3 = (this.z.getY()-this.m.getY())/(this.z.getX()-this.m.getX());
            k4 = (this.m.getY()-this.n.getY())/(this.m.getX()-this.n.getX());
            k5 = (this.n.getY()-this.x.getY())/(this.n.getX()-this.x.getX());
            if((this.x.getX() == this.y.getX()&& this.y.getX() == this.z.getX())||
                    (this.y.getX() == this.z.getX()&& this.z.getX() == this.m.getX())||
                    (this.z.getX() == this.m.getX()&& this.m.getX() == this.n.getX())||
                    (this.m.getX() == this.n.getX()&& this.n.getX() == this.x.getX())||
                    (this.m.getX() == this.n.getX()&& this.n.getX() == this.y.getX())||
                     x.equals(y) || x.equals(y)|| x.equals(z)|| x.equals(m) || x.equals(n) || y.equals(z)
                    ||y.equals(m)||y.equals(n)||z.equals(m) || z.equals(n) || m.equals(n))
            return false;
            else {
                if(k1 == k2 || k2== k3 || k3 == k4 || k4 == k5|| k5 == k1)
                return false;
                else
                    return true;
            }
        }
复制代码
利用斜率和点是否重合即可判断五边形

2:判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,

复制代码
class XL{
    Point p1;
    Point p2;
    Point p3;
    public XL(double x1, double y1, double x2, double y2,double x3, double y3) {
        Point p1 = new Point(x1, y1);
        Point p2 = new Point(x2, y2);
        Point p3 = new Point(x3, y3);
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }

    public XL(Point p1, Point p2 ,Point p3) {
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }
    /* 判断向量是否都小于0则为凸五边形*/
    public static boolean jugat(Point p1,Point p2,Point p3) {
                double x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, x3 = p3.x, y3 = p3.y;
                double t = (x2 - x1)*(y3-y2)-(y2-y1)*(x3-x2);
                if(t >= 0)
                    return true;
                else
                    return false;
        
    }

}

 在写这题时,前面的类结构不好,导致后续根本无法完成

因此换了全部结构和方法,改用向量法来判断。

比起之前的代码质量提高了很多。。。。

*************************************************************************************************************************************************

题目4:

7-1 点与线(类设计) 分数 20 作者 段喜龙 单位 南昌航空大学
  • 设计一个类表示平面直角坐标系上的点Point,私有属性分别为横坐标x与纵坐标y,数据类型均为实型数,除构造方法以及属性的getter与setter方法外,定义一个用于显示信息的方法display(),用来输出该坐标点的坐标信息,格式如下:(x,y),数值保留两位小数。为简化题目,其中,坐标点的取值范围设定为(0,200]。若输入有误,系统则直接输出Wrong Format

  • 设计一个类表示平面直角坐标系上的线Line,私有属性除了标识线段两端的点point1、point2外,还有一个字符串类型的color,用于表示该线段的颜色,同样,除构造方法以及属性的getter与setter方法外,定义一个用于计算该线段长度的方法getDistance(),还有一个用于显示信息的方法display(),用来输出线段的相关信息,输出格式如下:

      ```
          The line's color is:颜色值
          The line's begin point's Coordinate is:
          (x1,y1)
          The line's end point's Coordinate is:
          (x2,y2)
          The line's length is:长度值
      ```
    
     

    其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。

      设计类图如下图所示。
    
     

1641304523(1).jpg

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);

        Point point1=new Point(in.nextDouble(),in.nextDouble());
        Point point2=new Point(in.nextDouble(),in.nextDouble());
        Line l=new Line(point1,point2,in.next());
        
        if(point1.x<=0||point1.x>=200||point1.y<=0||point1.y>200)
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        if(point2.x<=0||point2.x>=200||point2.y<=0||point2.y>200)
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        //point1.display();
        //point2.display();
        l.display();
    }
}

class Point
{
    double x;
    double y;
    
    public Point()
    {
        
    }
    public Point(double x,double y){
        super();
        this.x=x;
        this.y=y;
    }
    public double getX(){
        return x;
    }
    public void setX(double x){
        this.x=x;
    }
    public double getY(){
        return y;
    }
    public void setY(double Y){
        this.y=y;
    }
    public void display(){
        if(x<=0||x>=200||y<=0||y>200)
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }
}


class Line
{
    Point point1;
    Point point2;
    String color;
    
    public Line(){
        
    }
    public Line(Point p1,Point p2,String color){
        super();
        this.point1=p1;
        this.point2=p2;
        this.color=color;
    }
    public Point getPoint1(){
        return point1;
    }
    public void setPoint1(Point point1){
        this.point1=point1;
    }
    public Point getPoint2(){
        return point2;
    }
    public void setPoint3(Point point2){
        this.point1=point2;
    }
    public String getColor(){
        return color;
    }
    public void setColor(){
        this.color=color;
    }
    public double getDistance(Point point1,Point point2){
        double D;
        D=Math.sqrt((point1.getX()-point2.getX())*(point1.getX()-point2.getX())+(point1.getY()-point2.getY())*(point1.getY()-point2.getY()));
        return D;
    }
    public void display(){
        System.out.println("The line's color is:"+getColor());
        
        System.out.println("The line's begin point's Coordinate is:");
        System.out.print("(");
        System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
        System.out.println(")");
        
        System.out.println("The line's end point's Coordinate is:");
        System.out.print("(");
        System.out.printf("%.2f,%.2f",point2.getX(),point2.getY());
        System.out.println(")");
        
        System.out.print("The line's length is:");
        System.out.printf("%.2f",getDistance(point1,point2));
    }
}

 这道题目较为简单,创建三个很基础的类,方法也都很简答的基础。

 ***********************************************************************************************************************************

题目5:

7-2 点线面问题重构(继承与多态) 分数 40 作者 段喜龙 单位 南昌航空大学

在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。

  • 对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。
  • 再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,输出格式如下:The Plane's color is:颜色
  • 在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。示例代码如下:
          element = p1;//起点Point
          element.display();
          
          element = p2;//终点Point
          element.display();
          
          element = line;//线段
          element.display();
          
          element = plane;//面
          element.display();
    
      类结构如下图所示。

1641340607(1).jpg

其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。

import java.util.Scanner;

public class Main{
    public static void main(String []args) {                    
            Scanner input =new Scanner(System.in);    
            
            Point point1= new Point(input.nextDouble(),input.nextDouble());
            Point point2= new Point(input.nextDouble(),input.nextDouble());
            Line line = new Line(point1,point2,input.next());
            Plane plane=new Plane(line.getColor());
            if((point1.getX()<=0||point1.getX()>200)||(point1.getY()<=0)||(point1.getY()>200)) {
             System.out.println("Wrong Format");
             System.exit(0);
            }
            if((point2.getX()<=0||point2.getX()>200)||(point2.getY()<=0)||(point2.getY()>200)) {
                 System.out.println("Wrong Format");
                 System.exit(0);
                }
            line.display();
            plane.display();
            }                       
}
    

 class Point extends Element{
     private double x;
     private double y;
     
     public Point() {         
         
     }

    public Point(double x, double y) {
        super();
        this.x = x;
        this.y = y;
    }
     public double getX() {
         return x;
     }
     public void setX(double x) {
         this.x=x;
     }
     public double getY() {
         return y;
     }
     public void setY(double y) {
         this.y=y;
     }
     public void display() {
         if((x<=0||x>200)||(y<=0)||(y>200)) {
             System.out.println("Wrong Format");
             System.exit(0);
         }
     }
    }
 class Line extends Element
 {
     private Point point1;
     private Point point2;
     private String color;     
     public Line() {         
         
     }

    public Line(Point point1, Point point2, String color  ) {
        super();
        this.point1 = point1;
        this.point2 = point2;
        this.color = color;
    }
     public Point getPoint1() {
        return point1;         
     }
     public void setPoint1(Point point1) {
         this.point1=point1;
     }
     public Point getPoint2() {
            return point2;         
         }
    public void setPoint2(Point point2) {
             this.point2=point2;
         }
    public String getColor() {
        return color;        
    }
    public void setColor(String color) {
        this.color=color;
    }
    public static double getDistance(Point point1,Point point2) {
        double a;
        a=Math.sqrt((point1.getX()-point2.getX())*(point1.getX()-point2.getX())+(point1.getY()-point2.getY())*(point1.getY()-point2.getY()));
        return a;
    }
    public void display() {    
        System.out.print("(");
        System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
        System.out.println(")");
        
        System.out.print("(");
        System.out.printf("%.2f,%.2f",point2.getX(),point2.getY());
        System.out.println(")");
            System.out.println("The line's color is:"+getColor());
            System.out.println("The line's begin point's Coordinate is:");
            System.out.print("(");
            System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
            System.out.println(")");
            System.out.println("The line's end point's Coordinate is:");
            System.out.print("(");
            System.out.printf("%.2f,%.2f",point2.getX(),point2.getY());
            System.out.println(")");
            System.out.print("The line's length is:");
            System.out.printf("%.2f\n",getDistance(point1,point2));
         }
     }

class Plane extends Element
{
         private String color;

        public Plane(String color) {
            super();
            this.color = color;
        }
        public String getColor() {
            return color;        
        }
        public void setColor(String color) {
            this.color=color;
        }
        public void display() {
            System.out.println("The Plane's color is:"+getColor());
        }
     }

class Element
{
            private double x;
            private double y;
            private Point point1;
            private Point point2;
            private String color;
            public void display() {    
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
                System.out.println(")");
                
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point2.getX(),point2.getY());
                System.out.println(")");
                
                System.out.println("The line's begin point's Coordinate is:");
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
                System.out.println(")");
                System.out.println("The line's end point's Coordinate is:");
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
                System.out.println(")");
                System.out.print("The line's length is:");
                System.out.printf("%.2f",Line.getDistance(point1,point2));
             }
}

 这题难度不大,在上一题的基础上,添加一个父类继承即可。

 题目6:

7-3 点线面问题再重构(容器类) 分数 40 作者 段喜龙 单位 南昌航空大学

在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。

  • 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList类型的对象(若不了解泛型,可以不使用
  • 增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象
  • 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:
    • 1:向容器中增加Point对象
    • 2:向容器中增加Line对象
    • 3:向容器中增加Plane对象
    • 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作
    • 0:输入结束
    示例代码如下:
       choice = input.nextInt();
        while(choice != 0) {
            switch(choice) {
            case 1://insert Point object into list 
              ...
                break;
            case 2://insert Line object into list
                ...
                break;
            case 3://insert Plane object into list
                ...
                break;
            case 4://delete index - 1 object from list
                int index = input.nextInt();
                ...
            }
            choice = input.nextInt();
        }
    
      输入结束后,按容器中的对象顺序分别调用每个对象的display()方法进行输出。
    类图如下所示:

classdiagram.jpg

import java.util.ArrayList;
import java.util.Scanner;     
public class Main{
    public static void main(String []args) {                    
            Scanner input =new Scanner(System.in);    
               int choice = input.nextInt();
               ArrayList list = new ArrayList();
                while(choice != 0) {
                    switch(choice) {
                    case 1://insert Point object into list 
                        Point point1= new Point(input.nextDouble(),input.nextDouble());                        
                        list.add(point1);
                        break;
                    case 2://insert Line object into list
                        Point point3= new Point(input.nextDouble(),input.nextDouble());
                        Point point2= new Point(input.nextDouble(),input.nextDouble());
                        Line line = new Line(point3,point2,input.next());
                        list.add(line);
                        break;
                    case 3://insert Plane object into list
                        Plane plane=new Plane(input.next());
                        list.add(plane);
                        break;
                    case 4://delete index - 1 object from list
                        int index = input.nextInt();
                        try{
		geometryObject.remove(index);
		}
	        catch(Exception e){}
   
                    }
                    choice = input.nextInt();
                }
                for (Element element : list) {
                    element.display();
                }
            
        }
        }
    
                         
                   
    
 class Point extends Element{
     private double x;
     private double y;
     
     public Point() {         
         
     }

    public Point(double x, double y) {
        super();
        this.x = x;
        this.y = y;
    }
     public double getX() {
         return x;
     }
     public void setX(double x) {
         this.x=x;
     }
     public double getY() {
         return y;
     }
     public void setY(double y) {
         this.y=y;
     }
     public void display() {
         if((x<=0||x>200)||(y<=0)||(y>200)) {
             System.out.println("Wrong Format");
             System.exit(0);
         }else {
                 System.out.print("(");
                System.out.printf("%.2f,%.2f",x,y);
                System.out.println(")");
                                
         }
     }
    }
 class Line extends Element{
     private Point point1;
     private Point point2;
     private String color;     
     public Line() {         
         
     }

    public Line(Point point1, Point point2, String color  ) {
        super();
        this.point1 = point1;
        this.point2 = point2;
        this.color = color;
    }
     public Point getPoint1() {
        return point1;         
     }
     public void setPoint1(Point point1) {
         this.point1=point1;
     }
     public Point getPoint2() {
            return point2;         
         }
    public void setPoint2(Point point2) {
             this.point2=point2;
         }
    public String getColor() {
        return color;        
    }
    public void setColor(String color) {
        this.color=color;
    }
    public static double getDistance(Point point1,Point point2) {
        double a;
        a=Math.sqrt((point1.getX()-point2.getX())*(point1.getX()-point2.getX())+(point1.getY()-point2.getY())*(point1.getY()-point2.getY()));
        return a;
    }
    public void display() {            
            System.out.println("The line's color is:"+getColor());
            System.out.println("The line's begin point's Coordinate is:");
            System.out.print("(");
            System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
            System.out.println(")");
            System.out.println("The line's end point's Coordinate is:");
            System.out.print("(");
            System.out.printf("%.2f,%.2f",point2.getX(),point2.getY());
            System.out.println(")");
            System.out.print("The line's length is:");
            System.out.printf("%.2f\n",getDistance(point1,point2));
         }
     }
     class Plane extends Element{
         private String color;

        public Plane(String color) {
            super();
            this.color = color;
        }
        public String getColor() {
            return color;        
        }
        public void setColor(String color) {
            this.color=color;
        }
        public void display() {
            System.out.println("The Plane's color is:"+getColor());
        }
     }
    class Element{
            private double x;
            private double y;
            private Point point1;
            private Point point2;
            private String color;
            public void display() {    
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
                System.out.println(")");
                
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point2.getX(),point2.getY());
                System.out.println(")");
                
                System.out.println("The line's begin point's Coordinate is:");
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
                System.out.println(")");
                System.out.println("The line's end point's Coordinate is:");
                System.out.print("(");
                System.out.printf("%.2f,%.2f",point1.getX(),point1.getY());
                System.out.println(")");
                System.out.print("The line's length is:");
                System.out.printf("%.2f",Line.getDistance(point1,point2));
             }            
    }
    class GeometryObject{
        ArrayList list = new ArrayList();
        
        public GeometryObject() {
            super();            
        }
        public void add(Element element) {
            list.add(element);
        }
        public void remove(int index) {
            if(index>0)
            list.remove(index);
        }
        public ArrayList getList(){
            return list;
            
        }
    }
这题要求以实现继承与多态的技术性需求
我们要再定义一个Element类的子类面Plane
然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法
从而实现多态特性。

************************************************************************************************************************************************

 三、踩坑心得

题目1:

四边形系列中在最后计算点在四边形内还是四边形外时,

首先采用如下方法:

计算点与四边形四个交点构成的四条直线与四边形交点的个数

如果交点个数皆为2,则在四边形内,否则在外。

在四边形上的情况需要单独判断。但是就是有测试点过不去。。。。

/*
                        Q.Quadrilateralnum(P1,P2,P3,P4,lAC,t,Q);
                        num1=Q.num;
                        Q.Quadrilateralnum(P1,P2,P3,P4,lAD,t,Q);
                        num2=Q.num;
                        Q.Quadrilateralnum(P1,P2,P3,P4,lAE,t,Q);
                        num3=Q.num;
                        Q.Quadrilateralnum(P1,P2,P3,P4,lAF,t,Q);
                        num4=Q.num;
                        System.out.println(num1+" "+num2+" "+num3+" "+num4);
                        
                        if(num1==2&&num2==2&&num3==2&&num4==2)
                            System.out.print("in the quadrilateral");
                        else
                            System.out.print("outof the quadrilateral");
                    }
                    else
                        System.out.print("not a quadrilateral or triangle");
                        */

 所以后面改用了面积法:

tACD.sanjiaoxmianji(tACD);
                        tADE.sanjiaoxmianji(tADE);
                        tAEF.sanjiaoxmianji(tAEF);
                        tACF.sanjiaoxmianji(tACF);
                        double S;
                        S=tACD.S+tADE.S+tAEF.S+tACF.S;
                        if(S-Q.S<0.001)
                            System.out.print("in the quadrilateral");
                        else
                            System.out.print("outof the quadrilateral");
                    }
                    else
                        System.out.print("not a quadrilateral or triangle");

题目2:

五边形由于我还是沿用了前面的类和方法,所以写起来有点麻烦。在图形复杂的情况下,需要考虑的情况更多,前面的类和方法已经不适用了。

在选项三中:

由于在判断交点个数时,我没有考虑到交点不存在的情况,而此时会默认交点赋值(0,0)

所以测试点过不去,在疯狂测试数据后,发现了这个问题

在计算交点函数里加一个判断两条直线是否平行,

并在点类中增加一个exist属性用来标记点是否存在

public void jiaodian(Line l1,Line l2,Point O)//两条直线交点
    {
        if(l1.pingxing(l1,l2))
        {
            O.exist=0;
        }
        else
        {
            l1.L(l1);
            l2.L(l2);
            O.x=(l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l2.a*l1.b);
            O.y=(l2.a*l1.c-l1.a*l2.c)/(l1.a*l2.b-l2.a*l1.b);
            O.x=Math.round(O.x*1000000000)/(double)1000000000;
            O.y=Math.round(O.y*1000000000)/(double)1000000000;
        }
    }

题目3:

第五次作业第二题求多边形相交面积式

在求两个五边形所有交点并去重后,没有用向量法将得到的点进行排序

使其按序能够组成多边形,结果导致求面积的结果错误

后来才专门写了排序算法,根据相邻两个交点与重心组成的边的向量的内积结果来判断点的位置

最终再将结果代入求面积的方法,求得正确面积。

期中:

remove的index超界



*解决方法:如下:



心得:注意边界问题。

 ***********************************************************************************************************************************************

四、代码改进建议

1.第四次作业的第二题需要重新构建代码逻辑,增加多边形抽象类,提取公共属性和公共方法作为强制实现方法,同时使三角形、四边形、五边形继承多边形类,裁撤judge类,将方法整合到多边形类中,删除多余的同种功能代码,使用重载实现同种方法的不同实现,同理,也可以这么修改第五次作业的第一题。
2.将过于长的且使用频率相当高的变量名,例如point,triangle等使用其缩写代替,比如p、tr等等,在保证能看懂代码的前提下尽量减少文本所占内存。
3.尽量多用继承与多态实现代码逻辑,并且减少main类中的实现方法,将方法分配给工具类完成,main类只作为程序开始的接口。

*****************************************************************************************************************************************************

五、总结

经过7-10周的学习,我认为我主要还是提升了主在各种数据的处理方面,对类和对象的理解,逻辑思维能力,考虑问题全面能力。PTA作业。

说实话作业的时间是够写的,但是我感觉有难度,pta作业图形界面迭代作业有一定难度,我有好几题没有满分;超星链表题目我也慢慢地写,经过询问多次同学才解决部分;期中考试比较而言更简单,但是最后还是差一点。考察了我们对面向对象的思考了,不再只是写在一个主类了,不只是考察我们的基本写一些代码的问题了,更多的是考察我们对面向对象这一实质的思考与研究,利用数据的私有和不同类之间的关联,考虑问题的全面性。我以后一定要更加努力。

希望老师能开放多一些测试点供我们学习,没有在规定时间写完也能出一下不计分的原题,可以让没有及时解决问题的同学继续尝试解决,老师也可以讲一讲PTA的题目(在规定时间之后)。

 

 

相关