• 第二次博客作业


    目录

    前言

    设计与分析

    采坑心得

    改进建议

    总结

    (1)前言:总结之前所涉及到的知识点、题量、难度等情况

    期中考试的难度是逐渐提高的,但是因为给了类图,难度总的来说比较适中。

    第四次的pta作业中第一题和第三题难度比较简单,第二题的难度挺高的,很考验编程能力和对正则表达式的使用。

    第五次的pta作业难度是最高的一次作业。

    (2)设计与分析:重点对题目的提交源码进行分析,可参考SourceMonitor的生成报表内容以及PowerDesigner的相应类图,要有相应的解释和心得(做到有图有真相),本次Blog必须分析PTA中的图形类设计的题目、超星中链表类练习题目以及期中考试的三道题目

    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"。

    输入格式:

    基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

    输出格式:

    基本输出格式见每种选项的描述。
    异常情况输出:
    如果不符合基本格式,输出"Wrong Format"。
    如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
    注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

    选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
    选项4中,若前两个输入线的点重合,输出"points coincide"。

    输入样例1:

    选项1,点重合。例如:

    1:-1,-1 -1,-1 1,2 1,-2

    输出样例:

    在这里给出相应的输出。例如:

    points coincide

    输入样例2:

    不符合基本格式。例如:

    1:-1,-1 1,2 -1,1 ++1,0

    输出样例:

    在这里给出相应的输出。例如:

    Wrong Format

    输入样例3:

    选项1,输入点数量不对。例如:

    1:-1,-1 -1,2 

    输出样例:

    在这里给出相应的输出。例如:

    wrong number of points

    输入样例4:

    选项1,正确输入判断。例如:

    1:-1,-1 -1,1 1,2 1,-2

    输出样例:

    在这里给出相应的输出。例如:

    true false

    输入样例5:

    选项2,输入点不构成四边形。例如:

    2:10,10 1,1 0,0 1,20

    输出样例:

    在这里给出相应的输出。例如:

    not a quadrilateral

    输入样例6:

    选项2,正方形。例如:

    2:0,0 0,80 80,80 80,0

    输出样例:

    在这里给出相应的输出。例如:

    true true true

    输入样例7:

    选项2。例如:

    2:0,0 -10,80 0,160 -10,80

    输出样例:

    在这里给出相应的输出。例如:

    not a quadrilateral

    输入样例8:

    选项3,凸四边形。例如:

    3:-1,-1 -1,1 1,2 1,-2

    输出样例:

    在这里给出相应的输出。例如:

    true 10.472 6.0

    输入样例9:

    选项3,。例如:

    3:0,0 -10,100 0,99 10,100

    输出样例:

    在这里给出相应的输出。例如:

    false 221.097 990.0
    
     

    其余样例,详见附件:

    点线形系列4-四边形题目说明.pdf

    类图:

     

     

    代码软件分析:

     

     

     

     

    代码主要类:

    复制代码
    class Judge {
        ArrayList pt = new ArrayList<>();
        private int number;
        public int getIndex() {
            return number;
        }
    
        public void judge(String s) {
            int flag =0;
            String regex = "[1-5]:([+-]?(0|(0\\.[0-9]+)|([1-9][0-9]*(\\.[0-9]+)?)),[+-]?(0|(0\\.[0-9]+)|([1-9][0-9]*(\\.[0-9]+)?))\\s?)+$";
            if(s.matches(regex)) {
                String[] string01 = s.split(":");
                number = Integer.parseInt(string01[0]);
                String[] strings = string01[1].split(" ");
                for (int i = 0; i < strings.length; i++) {
                    Point pot = new Point();
                    String[] s1 = strings[i].split(",");
                    pot.setX(Double.parseDouble(s1[0]));
                    pot.setY(Double.parseDouble(s1[1]));
                    pt.add(pot);
                }
            }
            else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
    
        }
        public boolean number(){
            if((pt.size() == 4 && (this.number >= 1 && this.number < 4 )) || (pt.size() == 6 && this.number == 4 ) || (pt.size() == 5 && this.number == 5)) {
                return true;
            }
            else
                return false;
        }
        //判断点是否重合
        public boolean coincidence(ArrayList a) {
            for (int i = 0; i < a.size(); i+=2) {
                for (int j = i+1; j < a.size(); j++) {
                    if(a.get(i).getX() == a.get(j).getX() && a.get(i).getY() == a.get(j).getY()) {
                        System.out.println("points coincide");
                        return false;
                    }
                }
            }
            return true;
        }
        //去冗余
        public void coincidence2() {
            if(pt.get(0).chonghe(pt.get(2)))
                pt.remove(0);
            else if(pt.get(1).chonghe( pt.get(3)))
                pt.remove(1);
            //判断重复的点
            for (int i = 0; i < pt.size() - 1; i++) {
                if(pt.get(i).chonghe(pt.get(i + 1))) {
                    pt.remove(i);
                }
            }
            if(pt.get(0).chonghe(pt.get(pt.size()-1))) {
                pt.remove(0);
            }
    
            //判断点在两点之间
            for (int i = 0; i < pt.size(); i++) {
                if(Line.threeline(pt.get(i%pt.size()),pt.get((i+1)%pt.size()),pt.get((i+2)%pt.size()))) {
                    pt.remove((i+1)%pt.size());
                }
            }
        }
        public static double sswr(double s) {
            String str=String.valueOf(s);
            String substring = str.substring(str.indexOf(".") + 1);
            int str_len;
            if(substring.length()>3)
            {
                str_len=3;
            }else {
                str_len=substring.length();
            }
            String formats="%."+str_len+"f";
            String out=String.format(formats,s);
            double res=Double.parseDouble(out);
            return res;
        }
    }
    class Point {
        private double x;
        private double 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 double distance(Point a) {
            double dis;
            dis = Math.sqrt(Math.pow((a.x - this.x),2) + Math.pow((a.y - this.y),2));
            return dis;
        }
        public boolean CheckPoint(Point p){
            if( Math.abs(this.getX() - p.getX() )< 0.000001  && Math.abs(this.getY() - p.getY() )< 0.000001){
                return true;
            }
            else
                return false;
        }
        public boolean chonghe(Point a){
            if(this.getX() == a.getX() && this.getY() == a.getY())
                return true;
            return false;
        }
    }
    
    class Line {
        private Point m,n;
        private double b;//y=kx+b
        private double k;
        private double A;
        private double B;
        private double C;
    
        public Line() {
    
        }
        public Line(Point m,Point n) {
            this.m = m;
            this.n = n;
            this.slope();
            this.equation(m,n);//求出直线方程
        }
        public void setMN(Point m,Point n) {
            this.m = m;
            this.n = n;
            this.slope();
            this.equation(m,n);//求出直线方程
        }
        public Point getM() {
            return m;
        }
        public Point getN() {
            return n;
        }
        public double getA() {
            return A;
        }
        public double getC() {
            return C;
        }
        public double getK() {
            return k;
        }
        public double getB() {
            return B;
        }
        //直线的斜率
        public void slope() {
            double se;
            if(m.getX() == n.getX())
                k = POSITIVE_INFINITY;
            else if(m.getY() == n.getY())
                k = 0;
            else {
                se = (m.getY()-n.getY())/(m.getX()-n.getX());
                k = se;
            }
        }
        public void equation(Point m,Point n) {
            double b;
            b = m.getY() - this.k * m.getX();
            A = n.getY() - m.getY();
            B = m.getX() - n.getX();
            C = n.getX() * m.getY() - m.getX() * n.getY();
        }
        //点到直线的距离
        double p_to_l(Point a,Line l) {
            //double dis = Math.abs(l.getA()*a.getX() + l.getB()*a.getY() + l.getC())/Math.sqrt(l.A * l.A + l.B* l.B);
            //return dis;
            if(l.k == 0) {
                return Math.abs(l.getM().getX()-a.getX());
            }
            else if(l.k == 1) {
                return Math.abs(l.getM().getY()-a.getY());
            }
            else {
                return Math.abs(l.getK()*a.getX()-a.getY()+ this.b)/(Math.sqrt(1+l.getK()*l.getK()));
            }
        }
        //判断三点一线,用于判断选项四的三角形情况
        public static boolean threeline(Point a, Point b, Point c) {
            Line line1 = new Line();
            line1.setMN(a,c);
            return line1.isallline(b) && line1.pointupline(b);
        }
        public boolean fourpoint(Line a) {
            if(Math.abs(a.k - this.k) < 0.000001)
                return true;
            else
                return false;
        }
        //求两直线交点坐标
        public Point intersection(Line a) {
            Point point = new Point();
            double det = this.getA() * a.getB() - a.getA() * this.getB();
            point.setX(( this.getB() * a.getC() - a.getB() * this.getC() )/det);
            point.setY(( a.getA() * this.getC() - this.getA() * a.getC() )/det);
            return point;
        }
        //点在线端内,点到线上两端点的距离==两端点距离
        public boolean pointupline(Point a) {
            if(Math.abs(a.distance(this.getM()) + a.distance(this.getN()) - this.distance()) < 0.000001)
                return true;
            else
                return false;
        }
        //点在线上不包含端点
        public boolean pointupline2(Point a) {
            if(this.pointupline(a) && !this.getM().chonghe(a) && !this.getN().chonghe(a))
                return true;
            return false;
        }
        //点是否在直线上
        public boolean isallline(Point a) {
            if(Math.abs( getA() * a.getX() + getB() * a.getY() + getC() ) < 0.000001)
                return true;
            return false;
        }
        //线段距离
        public double distance() {
            double dis;
            dis = Math.sqrt(Math.pow((m.getX() - n.getX()),2) + Math.pow((m.getY() - n.getY()),2));
            return dis;
        }
        //判断两点是否在直线一侧
        public boolean istongce(Point a,Point b) {
            double x1;
            double x2;
            x1 = this.getA() * a.getX() + this.getB() * a.getY() + this.getC();
            x2 = this.getA() * b.getX() + this.getB() * b.getY() + this.getC();
            if(x1 * x2 > 0)
                return true;
            else
                return false;
        }
        //判断两条线重合
        public boolean chonghe(Line l) {
            if(this.isallline(l.getM()) && this.isallline(l.getN())) {
                return true;
            }
            return false;
        }
    }
    class triangle {
        private Line l1 = new Line();
        private Line l2 = new Line();
        private Line l3 = new Line();
    
        public triangle(Line l1, Line l2, Line l3) {
            this.l1 = l1;
            this.l2 = l2;
            this.l3 = l3;
        }
    
        public triangle(Point a, Point b, Point c) {
            this.l1.setMN(a, b);
            this.l2.setMN(b, c);
            this.l3.setMN(c, a);
        }
    
        public Line getL1() {
            return l1;
        }
    
        public void setL1(Line l1) {
            this.l1 = l1;
        }
    
        public Line getL2() {
            return l2;
        }
    
        public void setL2(Line l2) {
            this.l2 = l2;
        }
    
        public Line getL3() {
            return l3;
        }
    
        public void setL3(Line l3) {
            this.l3 = l3;
        }
    
        //是否能构成三角形
        public boolean istriangle() {
    
            if (l1.isallline(l2.getN()) || l2.isallline(l3.getN()) || l3.isallline(l1.getN()))
                return false;
            return true;
        }
    
        //等腰三角形
        public boolean istwoline() {
            if (Math.abs(l1.distance() - l2.distance()) < 0.000001 || Math.abs(l2.distance() - l3.distance()) < 0.000001 || Math.abs(l2.distance() - l3.distance()) < 0.000001) {
                return true;
            } else
                return false;
        }
    
        //等边三角形
        public boolean threeline() {
            if (Math.abs(l1.distance() - l2.distance()) < 0.000001 && Math.abs(l1.distance() - l3.distance()) < 0.000001 && Math.abs(l2.distance() - l3.distance()) < 0.000001) {
                return true;
            } else
                return false;
        }
    
        //三角形周长
        public double Perimeter() {
    
            return l1.distance() + l2.distance() + l3.distance();
        }
    
        //三角形面积
        public double area() {
            double s = this.Perimeter() * 0.5;
            return Math.sqrt(s * (s - l1.distance()) * (s - l2.distance()) * (s - l3.distance()));
    
        }
        public double area3(){
            return l1.p_to_l(l1.getM(),l1) * l1.distance() *0.5;
        }
    
        public double area2(Point a, Point b, Point c) {
            double d1, d2, d3;
            d1 = a.distance(b);
            d2 = b.distance(c);
            d3 = a.distance(c);
            double s = 0.5 * (d1 + d2 + d3);
            return Math.sqrt(s * (s - d1) * (s - d2) * (s - d3));
        }
    
        //重心
        public Point focus() {
            Point weight = new Point();
            weight.setX((l1.getM().getX() + l1.getN().getX() + l2.getN().getX()) * 1.0 / 3);
            weight.setY((l1.getM().getY() + l1.getN().getY() + l2.getN().getY()) * 1.0 / 3);
            return weight;
        }
    
        //求余弦
        public double[] getcos() {
            double[] cos = new double[3];
            cos[0] = (l1.distance() * l1.distance() + l2.distance() * l2.distance() - l3.distance() * l3.distance()) / (2 * l1.distance() * l2.distance());
            cos[1] = (l1.distance() * l1.distance() + l3.distance() * l3.distance() - l2.distance() * l2.distance()) / (2 * l1.distance() * l3.distance());
            cos[2] = (l3.distance() * l3.distance() + l2.distance() * l2.distance() - l1.distance() * l1.distance()) / (2 * l3.distance() * l2.distance());
            return cos;
        }
    
        public double getcos(Point a, Point b, Point c) {
            double l1 = a.distance(b);
            double l2 = a.distance(c);
            double l3 = b.distance(c);
            return (l1 * l1 + l2 * l2 - l3 * l3) / (2 * l1 * l2);
    
        }
        // 点在三角形的边上
        public boolean pupline(Point a) {
            if(l1.pointupline(a) && l1.isallline(a)){
                return true;
            }
            else if(l2.isallline(a) && l2.pointupline(a)) {
                return true;
            }
            else if(l3.pointupline(a) && l3.isallline(a)) {
                return true;
            }
            else
                return false;
        }
        //点在三角形内
        public boolean pupin(Point a) {
            triangle tl1 = new triangle(l1.getM(), l1.getN(), a);
            triangle tl2 = new triangle(l2.getM(), l2.getN(), a);
            triangle tl3 = new triangle(l3.getM(), l3.getN(), a);
            if(!this.pupline(a) && Math.abs(tl1.area() + tl2.area() + tl3.area() - this.area()) < 0.0001)
                return true;
            return false;
        }
        public boolean chonghe(Line l) {
            if(l1.chonghe(l))
                return true;
            if(l2.chonghe(l))
                return true;
            if(l3.chonghe(l))
                return true;
            return false;
        }
        public void OneTriangle(Line line){
            List lineList = new ArrayList<>();
            lineList.add(l1);lineList.add(l2);lineList.add(l3);
            List list = new ArrayList<>();
            int cnt = 0;
            Point u;
            for(int i=0;i){
                u = lineList.get(i).intersection(line);
    
                boolean flag = false;
                if( u != null){
                    if(lineList.get(i).pointupline(u)){
                        flag = true;
                    }
    
                    for (Point p : list){
                        if( p.CheckPoint(u) ){
                            flag = false;
                            break;
                        }
                    }
    
                    if(flag){
                        list.add(u);
                        //System.out.println(u.getX() + " " + u.getY() );
                        cnt++;
                    }
                }
            }
            if(cnt < 2){
                System.out.println(cnt);
            }
            else {
                double s1,s2,s;
                System.out.print("2 ");
                Line lline = new Line(list.get(0), list.get(1));
                Point p1 = list.get(0),p2 = list.get(1);
                Point m;
                if(l1.isallline(p1) && l2.isallline(p2) || l2.isallline(p2) && l1.isallline(p1))
                    m = l1.getN();
                else if( l1.isallline(p1) && l3.isallline(p2) || l3.isallline(  p2) && l1.isallline(p1) )
                    m = l1.getM();
                else
                    m = l2.getN();
                triangle triangle1 = new triangle(m,list.get(0),list.get(1));
    
                s1 = triangle1.area();
                s1 = Judge.sswr(s1);
                s = this.area();
                s = Judge.sswr(s);
                s2 = s - s1;
                s2 = Judge.sswr(s2);
    
                System.out.println(Math.min(s1,s2) + " " + Math.max(s1,s2));
            }
        }
    }
    class quadrilateral {
        private Line line01;
        private Line line02;
        private Line line03;
        private Line line04;
        Point[] point = new Point[4];
        public quadrilateral(Point a,Point b,Point c,Point d) {
            point[0] = a;point[1] = b;point[2] = c; point[3] = d;
            Line line01 = new Line(a,b);
            this.line01 = line01;
            Line line02 = new Line(b,c);
            this.line02 = line02;
            Line line03 = new Line(c,d);
            this.line03 = line03;
            Line line04 = new Line(d,a);
            this.line04 = line04;
        }
        public boolean isquadrilateral() {
            if((line01.getK() == line02.getK()  || line02.getK() == line03.getK() || line03.getK() == line04.getK() || line04.getK() == line01.getK())
                    || (line01.pointupline(line01.intersection(line03)) && line03.pointupline(line01.intersection(line03)))
                    || (line02.pointupline(line02.intersection(line04)) && line04.pointupline(line02.intersection(line04)))) {
                return false;
            }
            else {
                return true;
            }
        }
        public boolean ispingxing() {
            if(line01.getK() == line03.getK() && line02.getK() == line04.getK()){
                return true;
            }
            else
                return false;
        }
        public boolean islingxing() {
            if(this.ispingxing() && this.line01.distance() == this.line02.distance() && this.line01.distance() == this.line03.distance()
                    && this.line01.distance() == this.line04.distance()) {
                return true;
            }
            else
                return false;
        }
        public boolean isjuxing() {
            if(this.ispingxing() && ( (this.line01.getK() == POSITIVE_INFINITY && this.line02.getK() == 0) || (this.line01.getK() == 0 && this.line02.getK() == POSITIVE_INFINITY) || this.line01.getK() * this.line02.getK() == -1)) {
                return true;
            }
            else
                return false;
        }
        public boolean iszhengfangxing() {
            if(this.isjuxing() && this.islingxing()) {
                return true;
            }
            else
                return false;
        }
        //判断凸四边形
        public boolean istusibainxing() {
            if(line01.istongce(line03.getM(),line03.getN()) && line02.istongce(line04.getM(),line04.getN())
                    && line03.istongce(line01.getM(),line01.getN()) && line04.istongce(line02.getM(),line02.getN())) {
                return true;
            }
            else
                return false;
        }
        //四边形周长
        public double perimeter() {
            return line01.distance() + line02.distance() + line03.distance() + line04.distance();
        }
        //四边形面积
        public double area() {
            triangle triangle01 = new triangle(line01.getM(), line01.getN(), line02.getN());
            triangle triangle02 = new triangle(line03.getM(), line03.getN(), line04.getN());
            triangle triangle03 = new triangle(line02.getM(), line02.getN(), line03.getN());
            triangle triangle04 = new triangle(line04.getM(), line04.getN(), line01.getN());
            double qarea01,qarea02;
            qarea01 = triangle01.area() + triangle02.area();
            qarea02 = triangle03.area() + triangle04.area();
            if(qarea02 < qarea01)//凹四边形面积比较特殊,要找凹点,这里偷懒直接判段小的输出
                return qarea02;
            else
                return qarea01;
        }
        //点在四边形边上
        public boolean pupline(Point a) {
            if(line01.pointupline(a) && line01.isallline(a))
                return true;
            else if(line02.pointupline(a) && line02.isallline(a))
                return true;
            else if(line03.pointupline(a) && line03.isallline(a))
                return true;
            else if(line04.pointupline(a) && line04.isallline(a))
                return true;
            else
                return false;
        }
        //点在四边形内部
        public boolean pupin(Point a) {
            triangle tl01 = new triangle(line01.getM(), line01.getN(), a);
            triangle tl02 = new triangle(line02.getM(), line02.getN(), a);
            triangle tl03 = new triangle(line03.getM(), line03.getN(), a);
            triangle tl04 = new triangle(line04.getM(), line04.getN(), a);
            if(!this.pupline(a) && Math.abs(tl01.area() + tl02.area() + tl03.area() + tl04.area() - this.area()) < 0.0001)
                return true;
            else
                return false;
        }
        public boolean chonghe(Line l) {
            if(line01.chonghe(l))
                return true;
            if(line02.chonghe(l))
                return true;
            if(line03.chonghe(l))
                return true;
            if(line04.chonghe(l))
                return true;
            return false;
        }
        //四边形分割成两个求面积,有两个交点
        public void fengeArea(Point a,Point b,Point c) {
            triangle tr1 = new triangle(a,b,c);
            double area1 = tr1.area();
            double area = this.area();
            double area2 = area - area1;
            area1 = Judge.sswr(area1);
            area2 = Judge.sswr(area2);
            System.out.println("2 " + Math.min(area1,area2) + " " + Math.max(area1,area2));
        }
        public void Onequarilateral(Line l) {
            Point[] points = new Point[4];
            ArrayList lines = new ArrayList<>();
            lines.add(line01);lines.add(line02);lines.add(line03);lines.add(line04);
            int[] p_in = new int[4];
    
            //判断交点在线上还是端点
            for (int i = 0; i < 4; i++) {
                p_in[i] = 0;
                //求直线与四边形的交点
                points[i] = lines.get(i).intersection(l);
                if(points[i]!=null) {
                    //判断交点是否在边上,不包括端点
                    if(lines.get(i).pointupline2(points[i]))
                        p_in[i] = 1;
                }
            }
            //有顶角在线上
            for (int i = 0; i < 4; i++) {
                if(l.isallline(point[i])) {
                    if(l.isallline((point[(i+2)%4]))) {
                        fengeArea(point[i], point[(i + 2) % 4], point[(i + 1) % 4]);
                        return;
                    }
                    else if(p_in[(i+1)%4] == 1) {
                        fengeArea(point[i], point[(i + 1) % 4], points[(i + 1) % 4]);
                        return;
                    }
                    else if(p_in[(i+2)%4] == 1) {
                        fengeArea(point[i], point[(i + 3) % 4], points[(i + 2) % 4]);
                        return;
                    }
                    else {
                        System.out.println("1");
                        return;
                    }
                }
            }
            //两个临边
            for (int i = 0; i < 4; i++) {
                if(p_in[i] == 1 && p_in[(i+1)%4] == 1) {
                    fengeArea(point[(i + 1) % 4], points[i], points[(i + 1) % 4]);
                    return;
                }
            }
            //两个对边
            for (int i = 0; i < 2; i++) {
                if(p_in[i] == 1 && p_in[i+2] == 1) {
                    triangle tr1 = new triangle(point[i], points[i], points[(i + 2) % 4]);
                    triangle tr2 = new triangle(point[(i+3)%4], point[i], points[(i + 2) % 4]);
                    double area1 = tr1.area() + tr2.area();
                    double area = this.area();
                    double area2 = area - area1;
                    area1 = Judge.sswr(area1);
                    area2 = Judge.sswr(area2);
                    System.out.println("2 " + Math.min(area1,area2) + " " + Math.max(area1,area2));
                    return;
                }
            }
            System.out.println("0");
            return;
        }
    }
    复制代码

     

    先利用check方法(正则表达式)检查一下输入进来的字符串,然后根据第一位是什么数字进入执行对应的方法。

     

     

     

    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

    输入格式:

    基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

    输出格式:

    基本输出格式见每种选项的描述。
    异常情况输出:
    如果不符合基本格式,输出"Wrong Format"。
    如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
    注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

    输入样例1:

    选项1,点重合。例如:

    1:-1,-1 1,2 -1,1 1,0
    
     

    输出样例:

    在这里给出相应的输出。例如:

    wrong number of points
    
     

    详细信息及样例请查看附件,本题包含附件中的选项1-3的功能:

    点线形系列5-五边形题目详情.pdf

    类图:

     

     

    代码软件分析:

     

     

     

     

     

    代码主要类:

     

    复制代码
        public static boolean geshi(String s){
    
            String s2= s.substring(0,2);
            if(!s2.matches("[1-6]\\:"))
            {
                System.out.println("Wrong Format");
                return false;
            }
            String s3 = s.substring(2);
            if(!s3.matches("([+|-]?(0|[1-9][0-9]*)(\\.\\d+)?,[+|-]?(0|[1-9][0-9]*)(\\.\\d+)?\\ ?)+"))
            {
                System.out.println("Wrong Format");
                return false;
            }
            return  true;
        }
        public static boolean dianshu(String s){
            String[] a = s.split(":");
            String[] b = a[1].split(" ");
            int n = b.length;
            if (s.charAt(0) == '1' && n != 5) {
                System.out.println("wrong number of points");
                return false;
            } else if (s.charAt(0) == '2' && n != 5) {
                System.out.println("wrong number of points");
                return false;
            } else if (s.charAt(0) == '3' && n != 7) {
                System.out.println("wrong number of points");
                return false;
            }
            else if (s.charAt(0) == '4' && n != 10) {
                System.out.println("wrong number of points");
                return false;
            }
            else if (s.charAt(0) == '6' && n != 6) {
                System.out.println("wrong number of points");
                return false;
            }
            return  true;
        }
        static class Wubianxing {
            Point a,b,c,d,e;
            Line ab,bc,cd,de,ea,ac,ad,bd,be,ce;
            Wubianxing(Point a,Point b,Point c,Point d,Point e){
                this.a=a;this.b=b;this.c=c;this.d=d;this.e=e;
                this.ab=new Line(a,b);
                this.bc=new Line(b,c);
                this.cd=new Line(c,d);
                this.de=new Line(d,e);
                this.ea=new Line(e,a);
                this.ac=new Line(a,c);
                this.ad=new Line(a,d);
                this.bd=new Line(b,d);
                this.be=new Line(b,e);
                this.ce=new Line(c,e);
            }
            public boolean iswubianxing(){
                if(ab.pingxing(bc)||bc.pingxing(cd)||cd.pingxing(de)||de.pingxing(ea)){
                    return false;
                }
                else if(Line.intersect(a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y)||Line.intersect(a.x,a.y,b.x,b.y,d.x,d.y,e.x,e.y)||
                        Line.intersect(b.x,b.y,c.x,c.y,d.x,d.y,e.x,e.y)||Line.intersect(b.x,b.y,c.x,c.y,e.x,e.y,a.x,a.y)||
                        Line.intersect(c.x,c.y,d.x,d.y,e.x,e.y,a.x,a.y))
                    return false;
    
                return true;
            }
            public boolean istuwubianxing(){
                if((((b.x-a.x)*(c.y-b.y))-((c.x-b.x)*(b.y-a.y))>0&&((c.x-b.x)*(d.y-c.y))-((d.x-c.x)*(c.y-b.y))>0&&
                        ((d.x-c.x)*(e.y-d.y))-((e.x-d.x)*(d.y-c.y))>0&&((e.x-d.x)*(a.y-e.y))-((a.x-e.x)*(e.y-d.y))>0)||
                        (((b.x-a.x)*(c.y-b.y))-((c.x-b.x)*(b.y-a.y))<0&&((c.x-b.x)*(d.y-c.y))-((d.x-c.x)*(c.y-b.y))<0&&
                                ((d.x-c.x)*(e.y-d.y))-((e.x-d.x)*(d.y-c.y))<0&&((e.x-d.x)*(a.y-e.y))-((a.x-e.x)*(e.y-d.y))<0))
                    return true;
                else
                    return false;
            }
            public double zhouchang(){
                double c=this.ab.length()+this.bc.length()+this.cd.length()+this.de.length()+this.ea.length();
                double C=outformat(c);
                return  C;
            }
            public double area(){
                Sanjiao san1=new Sanjiao(this.a,this.b,this.c);
                Sanjiao san2=new Sanjiao(this.a,this.c,this.d);
                Sanjiao san3=new Sanjiao(this.a,this.d,this.e);
                double mj= san1.mianji()+ san2.mianji()+ san3.mianji();
                double mianji=outformat(mj);
                return mianji;
            }
            public Double outformat(double num) {
                if(num*1e+3%10!=0) {
                    String num1=String.format("%.3f",num);
                    return Double.valueOf(num1);
                }
                return num;
            }
            public boolean bianchonghe (Line l){
                if(this.ab.xianchonghe(l)){
                    return true;
                }
                else if(this.bc.xianchonghe(l)){
                    return true;
                }
                else if(this.cd.xianchonghe(l)){
                    return true;
                }
                else if(this.de.xianchonghe(l)){
                    return true;
                }
                else if(this.ea.xianchonghe(l)){
                    return true;
                }
                return false;
            }
            public void fengewubainxing(Line l) {
                double area1=0,area2=0;
    
                if(this.ac.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.a,this.b,this.c);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    out(area1,area2);
                }
                else if(this.ad.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.a,this.d,this.e);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bd.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.b,this.d,this.c);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.be.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.a,this.b,this.e);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ce.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.c,this.d,this.e);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.bc.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.bc.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.ab.jiaodian(l),this.b,this.bc.jiaodian(l));
                    area1= ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.ab.jiaodian(l),this.b,this.c,this.cd.jiaodian(l));
                    ss1.otupanduan();
                    area1= ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.de.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.a,this.ab.jiaodian(l),this.de.jiaodian(l),this.e);
                    ss1.otupanduan();
                    area1= ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.ea.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.ab.jiaodian(l),this.a,this.ea.jiaodian(l));
                    area1= ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bc.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null&&this.bc.jiaodian(l)!=this.cd.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.bc.jiaodian(l),this.c,this.cd.jiaodian(l));
                    area1= ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bc.jiaodian(l)!=null&&this.de.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.bc.jiaodian(l),this.c,this.d,this.de.jiaodian(l));
                    ss1.otupanduan();
                    area1= ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bc.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.bc.jiaodian(l),this.ea.jiaodian(l),this.a,this.b);
                    ss1.otupanduan();
                    area1= ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.cd.jiaodian(l)!=null&&this.de.jiaodian(l)!=null&&this.cd.jiaodian(l)!=this.de.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.cd.jiaodian(l),this.d,this.de.jiaodian(l));
                    area1= ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.cd.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.cd.jiaodian(l),this.ea.jiaodian(l),this.e,this.d);
                    ss1.otupanduan();
                    area1= ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.de.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null&&this.ea.jiaodian(l)!=this.de.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.ea.jiaodian(l),this.e,this.de.jiaodian(l));
                    area1= ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else {
                    System.out.println(0);
                    System.exit(0);
                }
            }
            public void out(double m1,double m2){
                if(m1>=m2){
                    System.out.println(2+" "+m2+" "+m1);
                    System.exit(0);
                }
                else{
                    System.out.println(2+" "+m1+" "+m2);
                    System.exit(0);
                }
            }
            public boolean inwubianxing(Point p){
                Sanjiao ss1=new Sanjiao(this.a,this.b,p);Sanjiao ss2=new Sanjiao(this.b,this.c,p);
                Sanjiao ss3=new Sanjiao(this.c,this.d,p);Sanjiao ss4=new Sanjiao(this.d,this.e,p);
                Sanjiao ss5=new Sanjiao(this.e,this.a,p);
                if(Math.abs(this.area()-(ss1.mianji()+ss2.mianji()+ss3.mianji()+ss4.mianji()+ss5.mianji()))<0.0001)
                    return true;
               else  return false;
            }
        }
        static class Line {
            Point x,y;
    
            Line (Point a, Point b){
                this.x=a;
                this.y=b;
    
            }
            double length(){
                return this.x.juli(this.y);
            }
            double distance(Point p){//!!!
                if(this.x.x==this.y.x){
                    return  (p.x-this.x.x);
    
                }
                else{
                    double e=(this.x.y-this.y.y)/(this.x.x-this.y.x);
                    double b=this.x.y-(e*this.x.x);
                    return (e*p.x-p.y+b)/Math.sqrt(e*e+1);
                }
            }
            public static boolean intersect(double l1x1,double l1y1,double l1x2,double l1y2,double l2x1,double l2y1,double l2x2,double l2y2) {
    
                // 快速排斥实验 首先判断两条线段在 x 以及 y 坐标的投影是否有重合。 有一个为真,则代表两线段必不可交。
                if (Math.max(l1x1,l1x2) < Math.min(l2x1 ,l2x2)
                        || Math.max(l1y1,l1y2) < Math.min(l2y1,l2y2)
                        || Math.max(l2x1,l2x2) < Math.min(l1x1,l1x2)
                        || Math.max(l2y1,l2y2) < Math.min(l1y1,l1y2))
                {
                    return false;
                }
                // 跨立实验  如果相交则矢量叉积异号或为零,大于零则不相交
                else if ((((l1x1 - l2x1) * (l2y2 - l2y1) - (l1y1 - l2y1) * (l2x2 - l2x1))
                        * ((l1x2 - l2x1) * (l2y2 - l2y1) - (l1y2 - l2y1) * (l2x2 - l2x1))) > 0
                        || (((l2x1 - l1x1) * (l1y2 - l1y1) - (l2y1 - l1y1) * (l1x2 - l1x1))
                        * ((l2x2 - l1x1) * (l1y2 - l1y1) - (l2y2 - l1y1) * (l1x2 - l1x1))) > 0)
                {
                    return false;
                }
                return true;
            }
            public double duijiaoxian() {
                double duijiaoxian=Math.sqrt((this.x.x-this.y.x)*(this.x.x-this.y.x)+(this.x.y-this.y.y)*(this.x.y-this.y.y));
                return duijiaoxian;
            }
            public boolean xianchonghe (Line l){
                return this.pingxing(l)&&l.distance(this.x)==0;
            }
            boolean inline(Point p){
                if(this.x.x==this.y.x&&this.y.x==p.x)
                    return true;
                double e=(this.x.y-this.y.y)/(this.x.x-this.y.x);
                double b=this.x.y-(e*this.x.x);
                if((((e*p.x-p.y+b)==0&&(p.x>=min(x.x,y.x)&&p.x<=max(x.x,y.x)))&&((e*p.x-p.y+b)==0&&(p.y>=min(x.y,y.y)&&p.y<=max(x.y,y.y)))))
                    return true;
                else
                    return false;
            }
            Point jiaodian(Line l){
                Point v=sub(l.y,l.x);
                Point w=sub(this.y,this.x);
                Point p=l.x;
                Point q=this.x;
                Point u=sub(p,q);
                double t=cross(w,u)/cross(v,w);
                Point ans =new Point( p.x+v.x*t,p.y+v.y*t);
                double y0=ans.y;
                double x0=ans.x;
                if(((x0)>=min(x.x,y.x)&&(x0)<=max(x.x,y.x))&&((y0)>=min(x.y,y.y)&&(y0)<=max(x.y,y.y)))
                    return ans;
                return null;
    
            }
            public static double cross (Point a, Point b){
                return a.x*b.y-a.y*b.x;
            }
            public static Point sub(Point a, Point b){
                return new Point(a.x-b.x,a.y-b.y);
            }
            boolean pingxing  (Line a){
                if((a.x.x==a.y.x )&&(this.x.x==this.y.x))
                    return true;
                if((a.x.x==a.y.x)&&(this.x.x!=this.y.x))
                    return false;
                if((a.x.x!=a.y.x)&&(this.x.x==this.y.x))
                    return false;
                double e=a.x.xilv(a.y);
                double e1=this.x.xilv(this.y);
                if(e==e1)
                    return true;
                else return false;
            }
    
        }
        static class Point {
            double x,y;
            Point(double a,double b){
                this.x=a;
                this.y=b;
            }
            public double getx(){
                return x;
            }
            public double gety(){
                return y;
            }
            public double juli(Point p){
                return Math.sqrt((this.x-p.x )*(this.x-p.x )+(this.y-p.y )*(this.y-p.y));
            }
            public double xilv(Point p){
                if(this.x==p.x){
                    System.out.println("Slope does not exist");
                    System.exit(0);
                }
                return (this.y-p.y)/(this.x-p.x);
            }
        }
        static class Sanjiao {
            Main.Point sx,sy,sz;
            Main.Line sa,sb,sc;
            Sanjiao (Main.Point a, Main.Point b, Main.Point c){
                this.sx=a;
                this.sy=b;
                this.sz=c;
                this.sa=new Main.Line(b,c);
                this.sb=new Main.Line(a,c);
                this.sc=new Main.Line(a,b);
            }
            public boolean gouchengsanjiao(){
                if(((this.sa.length()+this.sb.length())<=this.sc.length())||((this.sa.length()+this.sc.length())<=this.sb.length())||((this.sb.length()+this.sc.length())<=this.sa.length())){
                    return false;
                }
                else return true;
            }
    
            public double zhouchang(){
                return (this.sa.length()+this.sb.length()+this.sc.length());
            }
            public double mianji(){
                double area=0;
                double s=(this.sa.length()+this.sb.length()+this.sc.length())/2;
                return area=Math.sqrt(s*(s-this.sa.length())*(s-this.sb.length())*(s-this.sc.length()));
            }
            public int type(){
                double[] num = new double[3];
                num[0] = this.sa.length();num[1] = this.sb.length();num[2] = this.sc.length();
                Arrays.sort(num);
                double tmp = Math.pow(num[0],2) + Math.pow(num[1],2) - Math.pow(num[2],2);
                if(Math.abs(tmp) < 0.0000001) return 1;
                if(tmp < 0) return 2;
                return 0;
            }
            public boolean insanjiao(Main.Point p){
                Sanjiao san1=new Sanjiao(p,sx,sy);
                Sanjiao san2=new Sanjiao(p,sy,sz);
                Sanjiao san3=new Sanjiao(p,sz,sx);
                double m1=san1.mianji();
                double m2=san2.mianji();
                double m3=san3.mianji();
                if(Math.abs(this.mianji()-(m1+m2+m3))<0.0001)
                    return true;
                else return false;
            }
            public void fengesanjiaoxing(Line l){
                double area1=0,area2=0;
                if(this.sc.jiaodian(l)!=null&&this.sa.jiaodian(l)!=null&&this.sc.jiaodian(l)!=this.sa.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.sc.jiaodian(l),this.sy,this.sa.jiaodian(l));
                    area1=ss1.mianji();
                    area2=this.mianji()-area1;
                    double mj1=outformat( area1);
                    double mj2=outformat( area2);
                    out(mj1,mj2);
                }
                else if(this.sc.jiaodian(l)!=null&&this.sb.jiaodian(l)!=null&&this.sc.jiaodian(l)!=this.sb.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.sc.jiaodian(l),this.sb.jiaodian(l),this.sx);
                    area1=ss1.mianji();
                    area2=this.mianji()-area1;
                    double mj1=outformat( area1);
                    double mj2=outformat( area2);
                    out(mj1,mj2);
                }
                else if(this.sa.jiaodian(l)!=null&&this.sb.jiaodian(l)!=null&&this.sa.jiaodian(l)!=this.sb.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.sa.jiaodian(l),this.sz,this.sb.jiaodian(l));
                    area1=ss1.mianji();
                    area2=this.mianji()-area1;
                    double mj1=outformat( area1);
                    double mj2=outformat( area2);
                    out(mj1,mj2);
                }
                else {
                    System.out.println(0);
                    System.exit(0);
                }
            }
            public Double outformat(double num) {
                if(num*1e+3%10!=0) {
                    String num1=String.format("%.3f",num);
                    return Double.valueOf(num1);
                }
                return num;
            }
            public void out(double m1,double m2){
                if(m1>=m2){
                    System.out.println(2+" "+m2+" "+m1);
                    System.exit(0);
                }
                else{
                    System.out.println(2+" "+m1+" "+m2);
                    System.exit(0);
                }
            }
            public boolean bianchonghe(Line l){
                if(this.sa.xianchonghe(l))
                    return false;
                else if(this.sb.xianchonghe(l))
                    return false;
                else if(this.sc.xianchonghe(l))
                    return  false;
                else
                    return true;
            }
        }
        static class Sibian {
            Main.Point a,b,c,d;
            Main.Line ab,bc,cd,da,ac,bd;
            private boolean judge1=false;//0,2
            private boolean judge2=false;//1,3
            Sibian(Main.Point a, Main.Point b, Main.Point c, Main.Point d){
                this.a=a;this.b=b;this.c=c;this.d=d;
                this.ab=new Main.Line(a,b);
                this.bc=new Main.Line(b,c);
                this.cd=new Main.Line(c,d);
                this.da=new Main.Line(d,a);
                this.ac=new Main.Line(a,c);
                this.bd=new Main.Line(b,d);
            }
            public void sibianxing(){
                if(Math.abs((a.y-c.y)*(a.x-b.x)-(a.y-b.y)*(a.x-c.x))<1e-6||
                        Math.abs((a.y-d.y)*(a.x-b.x)-(a.y-b.y)*(a.x-d.x))<1e-6||
                        Math.abs((a.y-d.y)*(a.x-c.x)-(a.y-c.y)*(a.x-d.x))<1e-6||
                        Math.abs((b.y-d.y)*(b.x-c.x)-(b.y-c.y)*(b.x-d.x))<1e-6)System.out.print("false ");
                else {
                    if(!Main.Line.intersect(a.x,a.y,d.x,d.y,b.x,b.y,c.x,c.y)) {
                        System.out.print("true ");
                    }
                    else System.out.print("false ");
                }
            }
            public void pingxingsibianxing(){
                if(this.ab.length()==this.cd.length()&&this.bc.length()==this.da.length())System.out.print("true");
                else System.out.print("false");
            }
            public boolean nengfougoucheng(){
                if(Math.abs((a.y-c.y)*(a.x-b.x)-(a.y-b.y)*(a.x-c.x))<1e-6||
                        Math.abs((a.y-d.y)*(a.x-b.x)-(a.y-b.y)*(a.x-d.x))<1e-6||
                        Math.abs((a.y-d.y)*(a.x-c.x)-(a.y-c.y)*(a.x-d.x))<1e-6||
                        Math.abs((b.y-d.y)*(b.x-c.x)-(b.y-c.y)*(b.x-d.x))<1e-6) {
                    return false;
                }
                else return !Main.Line.intersect(a.x, a.y, d.x, d.y, b.x, b.y, c.x, c.y) && !Main.Line.intersect(a.x, a.y, b.x, b.y, d.x, d.y, c.x, c.y);
            }
            public boolean lingxing(){
                return (this.ab.length()==this.cd.length()&&this.bc.length()==this.da.length());
            }
            public boolean changfangxing(){
                Main.Line l1=new Main.Line(a,c);
                double ac=l1.duijiaoxian();
                Main.Line l2=new Main.Line(b,d);
                double bd=l2.duijiaoxian();
                return (ac==bd&&this.ab.length()==this.cd.length()&&this.bc.length()==this.da.length());
            }
            public boolean zhengfangxing(){
                return (lingxing()&& changfangxing());
            }
            public boolean otupanduan() {
                Main.Line l1=new Main.Line(a,c);
                double distance1=l1.distance(b);
                double distance2=l1.distance(d);
                Main.Line l2=new Main.Line(b,d);
                double distance3=l2.distance(a);
                double distance4= l2.distance(c);
                if(distance1*distance2<0)judge1=true;
                if(distance3*distance4<0)judge2=true;
                if(judge1==true&&judge2==true) {
                    return true;
                }
                return false;
            }
            public double zhouchang() {
                double ab=this.ab.length();
                double bc=this.bc.length();
                double cd=this.cd.length();
                double da=this.da.length();
                double c=ab+bc+cd+da;
                double C=outformat(c);
                return C;
            }
            public double area() {
                double area=0;
                double area1=0;
                double area2=0;
                double are=0;
                //凸四边形
                if(judge1==true&&judge2==true) {
                    area1=Math.abs((b.x*c.y+c.x*d.y+d.x*b.y-b.x*d.y-c.x*b.y-d.x*c.y)/2);
                    area2=Math.abs((b.x*a.y+a.x*d.y+d.x*b.y-b.x*d.y-a.x*b.y-d.x*a.y)/2);
                    area=area1+area2;
                    are= outformat(area);
                }
                else if(judge1==false) {
                    area1=Math.abs((b.x*d.y+d.x*a.y+a.x*b.y-b.x*a.y-d.x*b.y-a.x*d.y)/2);
                    area2=Math.abs((d.x*c.y+c.x*b.y+b.x*d.y-d.x*b.y-c.x*d.y-b.x*c.y)/2);
                    area=area1+area2;
                    are= outformat(area);
                }
                else if(judge2==false) {
                    area1=Math.abs((b.x*c.y+c.x*a.y+a.x*b.y-b.x*a.y-c.x*b.y-a.x*c.y)/2);
                    area2=Math.abs((d.x*c.y+c.x*a.y+a.x*d.y-d.x*a.y-c.x*d.y-a.x*c.y)/2);
                    area=area1+area2;
                    are=outformat(area);
                }
                return are;
            }
            public Double outformat(double num) {
                if(num*1e+3%10!=0) {
                    String num1=String.format("%.3f",num);
                    return Double.valueOf(num1);
                }
                return num;
            }
            public boolean bianchonghe (Main.Line l){
                if(this.ab.xianchonghe(l)){
                    return true;
                }
                else if(this.bc.xianchonghe(l)){
                    return true;
                }
                else if(this.cd.xianchonghe(l)){
                    return true;
                }
                else if(this.da.xianchonghe(l)){
                    return true;
                }
                return false;
            }
            public boolean insibian(Main.Point p){
                double m=0;
                if(otupanduan()){
                    m=area();
                }
    
                Main.Sanjiao ss1=new Main.Sanjiao(p,a,b);
                Main.Sanjiao ss2=new Main.Sanjiao(p,b,c);
                Main.Sanjiao ss3=new Main.Sanjiao(p,c,d);
                Main.Sanjiao ss4=new Main.Sanjiao(p,d,a);
                double m1=ss1.mianji();
                double m2=ss2.mianji();
                double m3=ss3.mianji();
                double m4=ss4.mianji();
                if(Math.abs(m-(m1+m2+m3+m4))<0.0001)/*注意一定要三位小数或更多,不然通不过测试点*/
                    return true;
                else return false;
            }
            public void fengesibianxing(Line l){
                double area1=0,area2=0;
                if(this.ac.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.a,this.b,this.c);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bd.xianchonghe(l)){
                    Sanjiao ss1=new Sanjiao(this.a,this.b,this.d);
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.bc.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.bc.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.ab.jiaodian(l),this.b,this.bc.jiaodian(l));
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.a,this.ab.jiaodian(l),this.cd.jiaodian(l),this.d);
                    area1=ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.ab.jiaodian(l)!=null&&this.da.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.da.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.a,this.ab.jiaodian(l),this.da.jiaodian(l));
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bc.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null&&this.bc.jiaodian(l)!=this.cd.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.bc.jiaodian(l),this.c,this.cd.jiaodian(l));
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.bc.jiaodian(l)!=null&&this.da.jiaodian(l)!=null){
                    Sibian ss1=new Sibian(this.a,this.b,this.bc.jiaodian(l),this.da.jiaodian(l));
                    area1=ss1.area();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else if(this.cd.jiaodian(l)!=null&&this.da.jiaodian(l)!=null&&this.da.jiaodian(l)!=this.cd.jiaodian(l)){
                    Sanjiao ss1=new Sanjiao(this.da.jiaodian(l),this.d,this.cd.jiaodian(l));
                    area1=ss1.mianji();
                    area2=this.area()-area1;
                    double mj1= outformat(area1);
                    double mj2= outformat(area2);
                    out(mj1,mj2);
                }
                else {
                    System.out.println(0);
                    System.exit(0);
                }
            }
            public void out(double m1,double m2){
                if(m1>=m2){
                    System.out.println(2+" "+m2+" "+m1);
                    System.exit(0);
                }
                else{
                    System.out.println(2+" "+m1+" "+m2);
                    System.exit(0);
                }
            }
        }
    }
    复制代码

    思路是是先判断多边形多个点分别在线的哪一侧,让在同一侧的点与线的交点组成多边形,任何运用多边形类里面的方法,求出相应结果。

     

    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

    输入格式:

    基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

    输出格式:

    输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

    输入样例:

    在这里给出一组输入。例如:

    4:0,0 6,0 7,1 8,3 6,6 0,0 6,0 7,1 8,3 6,6
    
     

    输出样例:

    在这里给出相应的输出。例如:

    the previous pentagon coincides with the following pentagon
    
     

    更多样例请查看附件:
    点线形系列5-五边形题目详情.pdf

     
    类图:

     

     

    代码软件分析:
     

     

     


     

     

     
     
    代码主要类:
     
    复制代码
    class Point{
        public double x, y;
    
        public Point(){
            this.x = 0;
            this.y = 0;
        }
        public Point(double a,double b){
            this.x = a;
            this.y = b;
        }
    
        public void print(){
            String x = String.format("%.6f",this.x);
            String y = String.format("%.6f",this.y);
            x = x.replaceAll("0+?$", "");
            y = y.replaceAll("0+?$", "");
            System.out.printf("(%s , %s)\n",this.x,this.y);
        }
    
        //两点坐标相同
        public boolean isSameTo(Point a){
            return (this.x == a.x)&&(this.y == a.y);
        }
        //两点距离
        public double disToPoint(Point another){
            return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2));
        }
        //点到直线的垂直距离
        public double disToLine(Line l){
            return Math.abs(l.a*this.x+l.b*this.y+l.c) / Math.sqrt(Math.pow(l.a,2)+Math.pow(l.b,2));
        }
        //判断是否在直线之上
        public boolean inLine(Line l){
            return Math.abs(l.a*this.x + l.b*this.y + l.c) < 0.000001;
        }
        //判断是否在线段之内(包括端点)
        public boolean inLineSegment_close(Line l){
            if(!this.inLine(l)) return false;
            double res = this.disToPoint(l.sta) + this.disToPoint(l.ed) - l.length();
            return Math.abs(res) < 0.000001;
        }
        //判断是否在线段之内(不包括端点)
        public boolean inLineSegment(Line l){
            return this.inLineSegment_close(l) &&
                    (!this.isSameTo(l.sta)) &&
                    (!this.isSameTo(l.ed));
        }
        public Point deepCopy(){
            Point res = new Point();
            res.x = this.x;
            res.y = this.y;
            return res;
        }
    
        public Point add(Point another){
            Point res = this.deepCopy();
            res.x += another.x;
            res.y += another.y;
            return res;
        }
    
        public Point sub(Point another){
            Point res = this.deepCopy();
            res.x -= another.x;
            res.y -= another.y;
            return res;
        }
    
    
        //求点集重心
        public static Point focusPoint(Point[] points ){
            Point res = new Point(0,0);
            for(Point item:points){
                res = res.add(item);
            }
            res.x /= points.length;
            res.y /= points.length;
            return res;
        }
    
    }
    class Graphical {
        public int len=0,status=1;    //多边形边数,状态
        public Point[] points;
        public Line[] lines;
        public double sideLength = 0,area = 0;   //边长,面积
        public boolean isConvexGraphical = true;
        public  String message = "init"; //信息
    
        public Graphical(Point[] points){
            this.points = new Point[points.length];
    
            points = this.removeMulti(points);  //去除重复点
            if(points.length <=2 ){
                this.status = -1;
                this.message = "Not enough points";
                return;
            }
    
            //相邻边夹角0则去除中间点,夹角180则status:-1
            for(int i=0;i){
                int first = i , second = (i+1)%points.length, third = (i+2)%points.length;
                try{
                    Line l1 = new Line(points[first],points[second]);
                    Line l2 = new Line(points[second],points[third]);
                    if( Math.abs(l1.vectorAngle(l2) - Math.PI) < 0.000001 ){    //夹角180
                        this.status = -1;
                        this.message = "lines reverse coincidence";
                        return;
                    }
                    else if(Math.abs(l1.vectorAngle(l2)) > 0.000001){   //夹角不为0
                        this.points[this.len++] = points[second].deepCopy();
                    }
                }catch (Exception e){}
            }
    
            this.points = Arrays.copyOf(this.points,this.len);
            this.lines = new Line[this.len];
    
            //初始化边
            for(int i=0;i<this.len;i++){
                try {
                    int first = i, second = (i+1)%this.len;
                    this.lines[i] = new Line(this.points[first], this.points[second]);
                }catch (Exception e){}
            }
    
            //判断任意不相邻边(线段交点)是否有交点
            checkEdge();
    
            Graphical.area(this);
            Graphical.sideLength(this);
            Graphical.checkConvex(this);
        }
        public void print(){
            if(this.status == -1){
                System.out.println(this.message);
                return;
            }
            System.out.println("点数为:"+this.len);
            for(int i=0;i<this.len;i++){
                this.points[i].print();
            }
            for(int i=0;i<this.len;i++){
                this.lines[i].print();
            }
            System.out.println("周长为:"+this.sideLength);
            System.out.println("面积为:"+this.area);
            System.out.println("凹凸性:"+this.isConvexGraphical);
        }
        //判断图形是否包含某个点返回值-1,0,1 (内部,边缘,外部)
        //由于只考虑凸多边形,用面积法就行
        public int isContainPoint(Point p){
            for(int i=0;i<this.len;i++){    //位于边之上
                if(p.inLineSegment_close(this.lines[i])) return 0;
            }
    
            double s = 0;
            for(int i=0;i<this.len;i++){
                s += Triangle.area(p,this.points[i], this.points[(i+1)%this.len]);
            }
            return Math.abs(s-this.area) < 0.000001 ? -1:1;
        }
        //判断两个图形类之间的关系()
        public String relationshipWith(Graphical g){
            String[] name = new String[]{"triangle", "quadrilateral", "pentagon"};
            //分离
            if(this.isSeparatedFrom(g)){
                return "no overlapping area between the previous "+name[this.len-3]+ " and the following "+name[g.len-3];
            }
            //完全重合
            if(this.isSameTo(g))
                return "the previous "+name[this.len-3]+ " coincides with the following "+name[g.len-3];
            //包含
            if(this.isContainGra(g)){
                return "the previous "+name[this.len-3]+ " contains the following "+name[g.len-3];
            }
            //被包含
            if(g.isContainGra(this)){
                return "the previous "+name[this.len-3]+ " is inside the following "+name[g.len-3];
            }
    
            //连接
            if(this.overlappingArea(g) == 0){
                return "the previous "+name[this.len-3]+ " is connected to the following "+name[g.len-3];
            }
    
            //交错
            return "the previous "+name[this.len-3]+ " is interlaced with the following "+name[g.len-3];
    
        }
    
        //判断和另一个图形完全分离(重叠面积为0,并且任意点都在this之外)
        public boolean isSeparatedFrom(Graphical g){
            boolean ok = true;
            int[] check2 = new int[g.len];
            for(int i=0;i){
                check2[i] = this.isContainPoint(g.points[i]);
            }
            for(int item:check2){
                if(item != 1) ok = false;
            }
            if(this.overlappingArea(g) !=0) ok = false;
            return ok;
        }
        //判断完全包含另一个图形(任意点都在this之内)
        public boolean isContainGra(Graphical g){
            boolean ok = true;
            int[] check2 = new int[g.len];
            for(int i=0;i){
                check2[i] = this.isContainPoint(g.points[i]);
            }
            for(int item:check2){
                if(item == 1) ok = false;
            }
            return ok;
        }
    
        //判断两个图形是否一模一样(点完全重合)
        public boolean isSameTo(Graphical g){
            if(this.len != g.len) return false;
            for(int i=0;i<this.len;i++){
                boolean ok = false;
                for(int j=0;j){
                    if(this.points[i].isSameTo(g.points[j])) ok = true;
                }
                if(!ok) return false;
            }
            return true;
        }
    
        //计算两个图形的重叠面积(交点加内部顶点构成重叠多边形)
        public double overlappingArea(Graphical g){
            Point[] intersection = new Point[100];
            int intersection_len = 0;
    
    
            for(Line item1:this.lines){   //求出两多边形的交点
                for(Line item2: g.lines){
                    Point tmp = item1.lsi(item2);
                    if(tmp != null){
                        intersection[intersection_len++] = tmp.deepCopy();
                    }
                }
            }
    
    
            for(Point item:g.points){   //顶点包含在内部
                if(this.isContainPoint(item) == -1) intersection[intersection_len++] = item.deepCopy();
            }
            for(Point item:this.points){   //顶点包含在内部
                if(g.isContainPoint(item) == -1) intersection[intersection_len++] = item.deepCopy();
            }
    
            //if(intersection_len == 0) return 0;    //交点为0,分离
            //-2分
    
            /*排序交点数组*/
            intersection = Arrays.copyOf(intersection,intersection_len);
            intersection = this.removeMulti(intersection);
            Point focus = Point.focusPoint(intersection);
            Point sta = intersection[0].deepCopy();
    
            Arrays.sort(intersection,1,intersection.length, new Comparator()  {
                @Override
                public int compare(Point o1, Point o2) {
                    try{
                        Line origin =new Line(focus,sta);
                        Line l1 = new Line(focus,o1);
                        Line l2 = new Line(focus,o2);
                        double angle1 = origin.vectorAngle(l1);
                        double angle2 = origin.vectorAngle(l2);
                        if(origin.vectorCrossMul(l1) < 0) angle1 = 2*Math.PI - angle1;
                        if(origin.vectorCrossMul(l2) < 0) angle2 = 2*Math.PI - angle2;
                        if(angle1-angle2 > 0.000001) return 1;
                        if(Math.abs(angle1-angle2) < 0.000001) return 0;
                        return -1;
                    }catch (Exception reason){}
                    return 0;
                }
            });
    
            Graphical graphical = new Graphical(intersection);
            return  graphical.area;
    
        }
    
        //去除所有重复点
        private Point[] removeMulti(Point[] points){
            Point[] tmp_points = new Point[points.length];
            int tmp_len = 0;
    
            for(int i=0;i){
                boolean ok = true;
                for(int j=0;j){
                    if(points[i].isSameTo(tmp_points[j])){
                        this.message = "points coincide";
                        ok = false;
                        break;
                    }
                }
                if(ok) tmp_points[tmp_len++] = points[i].deepCopy();
            }
            return Arrays.copyOf(tmp_points,tmp_len);
        }
        //判断不相邻边是否有交点
        private void checkEdge(){
            for(int i=0;i<this.len;i++){
                for(int j=i+2;j<this.len;j++){
                    if(i==0&&j==this.len-1) continue;
                    Point p = this.lines[i].getIntersection(this.lines[j]);
                    if(p==null) continue;
    
                    if(p.inLineSegment_close(this.lines[i]) && p.inLineSegment_close(this.lines[j])){
                        this.status = -1;
                        this.message = "Non adjacent edges have intersections";
                        return;
                    }
                }
            }
        }
        //多边形面积
        private static void area(Graphical e){
            double res = 0;
            Point origin = new Point(0,0);
            for(int i=0;i){
                try{
                    Line l1 = new Line(origin,e.points[i]);
                    Line l2 = new Line(origin,e.points[(i+1)%e.len]);
                    res += 0.5 * l1.vectorCrossMul(l2);
                }catch (Exception reason){}
    
            }
            e.area = Math.abs(res);
        }
        //多边形周长
        private static void sideLength(Graphical e){
            double res = 0;
            for(int i=0;i){
                res += e.points[i].disToPoint(e.points[(i+1)%e.len]);
            }
            e.sideLength = res;
        }
        //多边形凹凸性
        private static void checkConvex(Graphical e){
            if(e.len == 3) return;
            int v = 0;
            for(int i=0;i){
                int first = i, second = (i+1)%e.len, thrid = (i+2)%e.len;
                try{
                    Line l1 = new Line(e.points[first], e.points[second]);
                    Line l2 = new Line(e.points[first], e.points[thrid]);
                    if(v==0){
                        if(l1.vectorCrossMul(l2) > 0) v = 1;
                        else v = -1;
                    }
                    if(v == 1 && l1.vectorCrossMul(l2) < 0) e.isConvexGraphical = false;
                    if(v == -1 && l1.vectorCrossMul(l2) > 0) e.isConvexGraphical = false;
                }catch (Exception reason){}
            }
        }
        //是否一样
    
    }
    复制代码
     
     
    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

    ** 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的display()方法进行输出。**

    • 以下情况为无效作业
      • 无法运行
      • 设计不符合所给类图要求
      • 未通过任何测试点测试
      • 判定为抄袭

    输入格式:

    分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。

    输出格式:

    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:长度值
    
     

    输入样例1:

    在这里给出一组输入。例如:

    5
    9.4
    12.3
    84
    Red
    
     

    输出样例1:

    在这里给出相应的输出。例如:

    The line's color is:Red
    The line's begin point's Coordinate is:
    (5.00,9.40)
    The line's end point's Coordinate is:
    (12.30,84.00)
    The line's length is:74.96
    
     

    输入样例2:

    在这里给出一组输入。例如:

    80.2356
    352.12
    24.5
    100
    Black
    
     

    输出样例2:

    在这里给出相应的输出。例如:

    Wrong Format
    
    
    复制代码
    import java.util.Scanner;
    public class Main {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            double x1 = in.nextDouble();
            double y1 = in.nextDouble();
            double x2 = in.nextDouble();
            double y2 = in.nextDouble();
            Point a = new Point(x1,y1);
            Point b = new Point(x2,y2);
            a.judge(x1,y1);
            b.judge(x2,y2);
            String color = in.next();
            Line l = new Line(a,b,color);
            l.display();
        }
    }
    class Point {
        private double x;
        private double y;
    
        Point(double x, double y) {
            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() {
            System.out.printf("(%.2f,%.2f)", x, y);
        }
        public void judge(double x,double y)
        {
            if((x<=0||x>200)||(y<=0||y>200))
            {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
    
    }
    class Line{
        private Point point1;
        private Point point2;
        private String color;
        private double distance;
    
        Line() {
        }
        public Line(Point p1, Point p2,String color)
        {
            Point p3 = new Point(p1.getX(), p1.getY());
            Point p4 = new Point(p2.getX(), p2.getY());
            this.point1 = p3;
            this.point2 = p4;
            this.color = color;
        }
        public void setcolor()
        {
            this.color = color;
        }
        public String getcolor()
        {
            return color;
        }
        public double getdistance()
        {
            distance = Math.sqrt(Math.abs((point1.getX() - point2.getX())* (point1.getX() - point2.getX())+(point1.getY() - point2.getY())* (point1.getY() - point2.getY())));
            this.distance = distance;
            return distance;
        }
        public void display()
        {
            double s;
            s = getdistance();
            System.out.println("The line's color is:"+ color);
            System.out.println("The line's begin point's Coordinate is:");
            point1.display();
            System.out.println("\nThe line's end point's Coordinate is:");
            point2.display();
            System.out.printf("\nThe line's length is:%.2f",distance);
        }
    }
    复制代码
    第一题的总体难度不难,因为一个创建点的时候传入数据问题导致第一次提交没有满分。
    
    
    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)方法。

    • 以下情况为无效作业
      • 无法运行
      • 设计不符合所给类图要求
      • 未通过任何测试点测试
      • 判定为抄袭

    输入格式:

    分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。

    输出格式:

    (x1,y1)
    (x2,y2)
    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:长度值
    The Plane's color is:颜色值
    
     

    输入样例1:

    在这里给出一组输入。例如:

    5
    9.4
    12.3
    84
    Red
    
     

    输出样例1:

    在这里给出相应的输出。例如:

    (5.00,9.40)
    (12.30,84.00)
    The line's color is:Red
    The line's begin point's Coordinate is:
    (5.00,9.40)
    The line's end point's Coordinate is:
    (12.30,84.00)
    The line's length is:74.96
    The Plane's color is:Red
    
     

    输入样例2:

    在这里给出一组输入。例如:

    5
    9.4
    12.3
    845
    Black
    
     

    输出样例2:

    在这里给出相应的输出。例如:

    Wrong Format


    代码:

    复制代码
    import java.text.DecimalFormat;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner in=new Scanner(System.in);
            Point p1=new Point();
            double x1=in.nextDouble();
            double y1=in.nextDouble();
            double x2=in.nextDouble();
            double y2=in.nextDouble();
            p1.setX(x1);
            p1.setY(y1);
            Point p2=new Point();
            p2.setX(x2);
            p2.setY(y2);
            String color=in.next();
            Line line=new Line();
            line.setPoint1(p1);
            line.setPoint2(p2);
            line.setColor(color);
            Plane plane=new Plane();
            plane.setColor(color);
            Element element=new Element() {
                @Override
                public void display() {
    
                }
            };
            if ((x1<=0||x1>200)||(y1<=0||y1>200)||(x2<=0||x2>200)||(y2<=0||y2>200))
                System.out.println("Wrong Format");
            else{
                element = p1;//起点Point
                element.display();
                element = p2;//终点Point
                element.display();
                element = line;//线段
                element.display();
                element = plane;//
                element.display();
            }
        }
    }
    
    abstract class Element{
        public abstract void display();
    }
    
    class Point extends Element{
        private double x;//横坐标
        private double y;//纵坐标
    
        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }
    
        public Point() {
        }
    
        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(){
            DecimalFormat two=new DecimalFormat("0.00");
            System.out.println("("+two.format(this.x)+","+two.format(this.y)+")");
        }
    }
    
    class Line extends Element{
        private Point point1 = new Point();
        private Point point2 = new Point();
        String color;
    
        public Line(Point point1, Point point2, String color) {
            this.point1 = point1;
            this.point2 = point2;
            this.color = color;
        }
    
        public Line() {
        }
    
        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 double getDistance(Point p1,Point p2){
    
            double a=p1.getX()-p2.getX();
            double b=p1.getY()-p2.getY();
    
            return Math.sqrt(a*a+b*b);
        }
        public void display(){
            Line line=new Line();
            DecimalFormat two=new DecimalFormat("0.00");
            System.out.println("The line's color is:"+getColor());
            System.out.println("The line's begin point's Coordinate is:");
            point1.display();
            System.out.println("The line's end point's Coordinate is:");
            point2.display();
            System.out.println("The line's length is:" + two.format(line.getDistance(point1,point2)));
        }
    }
    
    class Plane extends Element{
        private String color;
        public Plane(String color) {
            this.color = color;
        }
        public Plane() {
        }
        public String getColor() {
            return color;
        }
        public void setColor(String color) {
            this.color = color;
        }
        public void display(){
            System.out.println("The Plane's color is:"+this.color);
        }
    }
    复制代码

    第二题的难度比较适中

     

    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

    • 以下情况为无效作业
      • 无法运行
      • 设计不符合所给类图要求
      • 未通过任何测试点测试
      • 判定为抄袭

    输入格式:

    switch(choice) {
                case 1://insert Point object into list 
                  输入“点”对象的x,y值
                    break;
                case 2://insert Line object into list
                    输入“线”对象两个端点的x,y值
                    break;
                case 3://insert Plane object into list
                    输入“面”对象的颜色值
                    break;
                case 4://delete index - 1 object from list
                    输入要删除的对象位置(从1开始)
                    ...
                }
    
     

    输出格式:

    • Point、Line、Plane的输出参考题目2
    • 删除对象时,若输入的index超出合法范围,程序自动忽略该操作

    输入样例:

    在这里给出一组输入。例如:

    1
    3.4
    5.6
    2
    4.4
    8.0
    0.98
    23.888
    Red
    3
    Black
    1
    9.8
    7.5
    3
    Green
    4
    3
    0
    
     

    输出样例:

    在这里给出相应的输出。例如:

    (3.40,5.60)
    The line's color is:Red
    The line's begin point's Coordinate is:
    (4.40,8.00)
    The line's end point's Coordinate is:
    (0.98,23.89)
    The line's length is:16.25
    (9.80,7.50)
    The Plane's color is:Green
    代码:
    
    复制代码
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String []args) {
            Scanner in =new Scanner(System.in);
            int choice = in.nextInt();
            ArrayList ad = new ArrayList();
            while(choice != 0) {
                switch(choice) {
                    case 1:
                        Point point1= new Point(in.nextDouble(),in.nextDouble());
                        ad.add(point1);
                        break;
                    case 2:
                        Point point3= new Point(in.nextDouble(),in.nextDouble());
                        Point point2= new Point(in.nextDouble(),in.nextDouble());
                        Line line = new Line(point3,point2,in.next());
                        ad.add(line);
                        break;
                    case 3:
                        Plane plane=new Plane(in.next());
                        ad.add(plane);
                        break;
                    case 4:
                        int index = in.nextInt();
                        ad.remove(index-1);
                }
                choice = in.nextInt();
            }
            for (Element element : ad) {
                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.print("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 ad = new ArrayList();
        public GeometryObject() {
            super();
        }
        public void add(Element element) {
            ad.add(element);
        }
        public void remove(int index) {
            if(index>0)
                ad.remove(index);
        }
        public ArrayList getList(){
            return ad;
        }
    }
    复制代码
    第三个题目没有全部完成,其实思路还是挺简单的。
    
    

    (3)采坑心得:

    1.题目集4 7-2 判断四边形是否成型时,用了斜率相等判断平行,但是在样例中会出现类似分母为零的情况,改用了x1y2=x2y1判断。
    2.考虑相等问题的同时,需要判断是否需要考虑精度问题,有很多点是没加精度判断过不去的,精度不能设置太大也不能太小,合适就好,我的话精度1e-6或者1e-12,具体问题具体分析即可。
    3.我们在拿到题目时,不要一股脑的想着如何去实现功能,我们可以先将最终要设计出来的代码进行功能分解,进而设计出多个不同功能的类,每个类再根据应有的功能写出相应的代码。

    (4)改进建议:对相应题目的编码改进给出自己的见解,做到可持续改进

    1.计算几何方面知识有所欠缺

    2.我们可以参考一下别人代码的构造然后去自己模仿着写,不断改进自己的代码结构。

    (5)总结:

    这几次作业极大的提高了本人对面向对象编程的理解,且极大的提高了本人的代码能力。我对JAVA中常规类的使用习惯和构建方法更加清楚,可以很熟练地处理三角形、四边形、五边形其他类型的题目,也能通过较为合理的设计完成题目要求。

  • 相关阅读:
    【java核心技术】Java知识总结 -- 语法篇
    计算两幅图像的相似度(PSNR、SSIM、MSE、余弦相似度、MD5、直方图、互信息、Hash)& 代码实现 与举例
    查找 - 顺序、二分和哈希查找
    查字符串或者查对象值去重
    GB4806.7食品级塑料包装袋进出口监管要求
    solidworks底部状态栏显示不出来
    疫情期间闲来无事,我自制了一个按钮展示框特效来展示我的博客
    docker镜像创建、删除等相关操作
    Spring Data JPA系列5:让IDEA自动帮你写JPA实体定义代码
    【数据结构】图的深度优先遍历
  • 原文地址:https://www.cnblogs.com/lhh1604662631/p/16838184.html