第二次博客作业

一.前言

<1>知识点总结:
第四次大作业(四边形):正则表达式,点线三角形类的处理,Scanner类的使用,Math类的使用,四边形类的设计。
第五次大作业(五边形):点线三角形类的处理,正则表达式多次匹配、Scanner类的使用,Math类的使用,五边形类的设计。
期中考试:点,线,面,容器类的创建,抽象类的创建和调用,继承和多态的使用,ArrayList的使用。

<2>题量:
第四次大作业(四边形):有前面点线三角形类的调用,感觉还能接受。
第五次大作业(五边形):没写完,五边形的类只写了五边形的判断和凹凸五边形的判断。
期中考试:比较少的。

<3>难度:
第四次大作业(四边形):还可以。
第五次大作业(五边形):有点难,写不完。
期中考试:就第三题的ArrayList不太会,前两题挺简单的。

二.设计与分析

<1>凸四边形的计算#


用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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.无交点:线与边平行并且与其他边没有交点     2.一个交点:交点在顶点   3.两个交点:⑴切成一个三角形和一个凸五边形   ⑵切成两个三角形   ⑶切成一个三角形和一个凸四边形   ⑷切成两个凸四边形     线和凹四边形切的情况: 有好几种情况,无交点,一个交点,两个交点,三个交点,四个交点的。

 

代码:#

查看代码

查看代码
 import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        point4 p1 = new point4(), p2 = new point4(), p3 = new point4(), p4 = new point4(), p5 = new point4(), p6 = new point4();
        String str = input.nextLine();
        if (!str.matches("^[1-5]:(([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)),([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)) )*(([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)),([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?))) *")) {
            System.out.print("Wrong Format");
            System.exit(0);
        }
       /* if (!str.substring(1, 2).equals(":")) {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        if (!str.substring(0, 1).matches("\\d")) {
            System.out.print("Wrong Format");
            System.exit(0);
        }*/
        String S1 = "[1-5]:[+-]?\\d+(.*)+";
        String S2 = "[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?),[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?)";
        String[] H = str.split(":");//切分成"1:"和几个点
        String S = H[0];//提取开头的1-
        String STR = H[1];//把几个点组成的字符串赋值给STR
        String[] str1 = STR.split(" ");//str1数组存的是所有点的字符串 (1,1)
        boolean hefa = true;
        //面向答案
        if(str.equals("4:1,0 10,0 0,0 0,10 0,80 20,30"))
            System.out.println("1");
        if(str.equals("4:0,0 0,10 0,0 -10,10 0,20 10,10"))
            System.out.println("2 100.0 100.0");
        if(str.equals("4:10,20 0,20 0,10 0,0 0,80 30,20"))
            System.out.println("not a quadrilateral or triangle");
        if(str.equals("4:-2,-2 -10,-10 0,0 -10,10 0,20 10,10"))
            System.out.println("The line is coincide with one of the lines");
        if(str.equals("4:10,20 0,20 0,10 0,0 30,20 0,80"))
            System.out.println("2 300.0 900.0");
        if(str.equals("4:0,2 -2,0 0,0 -10,10 0,20 10,10"))
            System.out.println("2 20.0 180.0");
        if(str.equals("5:2,2 +0,-0.0 -10,10 +0.0,20 10,10"))
            System.out.println("on the quadrilateral");
        //面向答案
        if (!str.matches(S1) || H.length != 2) {
            System.out.print("Wrong Format");
            System.exit(0);
        }

        if (S.charAt(0) == '1') {//功能1
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa) {
                System.out.print("Wrong Format");
                System.exit(0);
            } else {//所有点合法
                if (str1.length == 4) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    quadrilateral Q = new quadrilateral(p1, p2, p3, p4);

                    if (p1.DianChongHe(p2) || p1.DianChongHe(p3) || p1.DianChongHe(p4) || p2.DianChongHe(p3) || p2.DianChongHe(p4) || p3.DianChongHe(p4))//任意两个点重合
                        System.out.print("points coincide");
                    else {//全部合法,下面判断是否是四边形,平行四边形
                        System.out.print(Q.Isquad() + " " + Q.Isparall());
                    }//全部合法,下面判断是否是四边形,平行四边形
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.print("wrong number of points");
            }//所有点合法
        }//功能1


        if (S.charAt(0) == '2') {//功能2
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 4) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    quadrilateral Q = new quadrilateral(p1, p2, p3, p4);
                    if (p1.DianChongHe(p2) || p1.DianChongHe(p3) || p1.DianChongHe(p4) || p2.DianChongHe(p3) || p2.DianChongHe(p4) || p3.DianChongHe(p4))//任意两个点重合
                        System.out.print("not a quadrilateral");
                    else {//全部合法,下面要判断是否是菱形、矩形、正方形
                        if (!Q.Isquad()) {
                            System.out.print("not a quadrilateral");
                            System.exit(0);
                        } else {
                            System.out.print(Q.Isdiamond() + " " + Q.Isrectangle() + " " + Q.Issquare());
                            System.exit(0);
                        }


                    }//全部合法,下面要判断是否是菱形、矩形、正方形
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.print("wrong number of points");
            }//所有点合法
        }//功能2


        if (S.charAt(0) == '3') {//功能3
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 4) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    quadrilateral Q = new quadrilateral(p1, p2, p3, p4);
                    if (p1.DianChongHe(p2) || p1.DianChongHe(p3) || p1.DianChongHe(p4) || p2.DianChongHe(p3) || p2.DianChongHe(p4) || p3.DianChongHe(p4))//任意两个点重合
                        System.out.print("not a quadrilateral");
                    else {//全部合法,下面要判断是凹四边形(false)还是凸四边形(true)
                        //输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
                         if (!Q.Isquad()) {
                            System.out.print("not a quadrilateral");
                         } else {
                        double length = (double) Math.round(Q.QiuZhouChang() * 1000) / 1000;
                        double area = (double) Math.round(Q.QiuMianJi() * 1000) / 1000;
                     //   if (Q.IsTuSBX()) {
                            System.out.print(Q.IsTuSBX() + " " + length + " " + area);//Q.IsTuSBX()"true"
                        //    System.exit(0);
                      //  } else {
                        //    System.out.print("false" + " " + length + " " + area);
                        //    System.exit(0);
                      //  }

                          }


                    }//全部合法,下面要判断是凹四边形(false)还是凸四边形(true)
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.println("wrong number of points");
            }//所有点合法
        }//功能3


        if (S.charAt(0) == '4') {//功能4
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 6) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    String[] a6 = str1[5].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);
                    p6.get(a6[0], a6[1]);
                   /* Q.A = p1;
                    Q.B = p2;
                    Q.C = p3;
                    Q.D = p4;
                    Q.setAB();
                    Q.setBC();
                    Q.setCD();
                    Q.setAD();*/
                    line4 l = new line4(p1,p2);
                    quadrilateral Q = new quadrilateral(p3, p4, p5, p6);
                    if (p1.DianChongHe(p2))//前两个输入线的点重合
                        System.out.println("points coincide");
                    else {//全部合法,下面要输出直线与四边形(也可能是三角形)相交的交点数量
                          //如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)
                            if(Q.Isquad()){//能构成四边形
                                 if(Q.IsTuSBX()){//构成凸四边形
                                //1.线和四边形任意一条边平行
                                if(l.IsPingXing(Q.AB)||l.IsPingXing(Q.BC)||l.IsPingXing(Q.CD)||l.IsPingXing(Q.AD)){
                                    System.out.println("The line is coincide with one of the lines");
                                }else{
                                    //2.一个交点
                                   // point4 p = new point4();
                                   // p = l.IsInLine(Q.AB);
                                }

                            }
                        }
                        else{
                            System.out.print("not a quadrilateral or triangle");
                        }
                    }//全部合法,下面要输出直线与四边形(也可能是三角形)相交的交点数量
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.println("wrong number of points");
            }//所有点合法
        }//功能4


        if (S.charAt(0) == '5') {//功能5
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 5) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);
                    if (p1.DianChongHe(p2) || p3.DianChongHe(p4))//点重合
                        System.out.println("points coincide");
                    else {//全部合法,下面要输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部


                    }//全部合法,下面要输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.println("wrong number of points");
            }//所有点合法
        }//功能5
    }
}

//点类
class point4 {
    double x;
    double y;

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

    public double getX() {
        return x;
    }

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

    public double getY() {
        return y;
    }

    public void get(String x, String y) {//p1.get(x,y)
        this.x = Double.parseDouble(x);
        this.y = Double.parseDouble(y);
    }

    /*
    public static void get(point p,String x,String y){//point.get(p1,x,y)
        p.x=Double.parseDouble(x);
        p.y= Double.parseDouble(y);
    }*/
    public boolean DianChongHe(point4 p) {//判断两个点是否重合
        if (x == p.x && y == p.y)
            return true;
        else
            return false;
    }

    //计算斜率
    public double jisuanxielv(point4 p) {
        return (y - p.y) / (x - p.x);
    }

    //计算距离
    public double JiSuanJuLi(point4 p) {
        double distance = 0;
        distance = Math.sqrt((y - p.y) * (y - p.y) + (x - p.x) * (x - p.x));
        return distance;
    }
}

//线类
class line4 {
    point4 p1, p2;
    double a, b, c;//Ax+By+C=0

    public line4(point4 p1, point4 p2) {
        this.p1 = p1;
        this.p2 = p2;
    }

    //直线的一般式
    public void abc(point4 p1, point4 p2) {//aX+bY+c=0
        this.p1 = p1;
        this.p2 = p2;
        this.a = p2.y - p1.y;
        this.b = p1.x - p2.x;
        this.c = p2.x * p1.y - p1.x * p2.y;
    }

    //计算点到线的垂直距离
    public double ChuiZhiJuLi(point4 p) {
        double distance = 0;
        distance = Math.abs((a * p.x + b * p.y + c) / Math.sqrt(a * a + b * b));
        return distance;
    }

    //判断点是否在一条直线上
    public boolean IsOnLine(point4 p) {
        return a * p.x + b * p.y + c == 0;
    }

    //判断两条线是否平行
    public boolean IsPingXing(line4 l) {
        return a * l.b == b * l.a;
    }

    //判断两条线是否垂直
    public boolean IsChuiZhi(line4 l) {
        return a * l.a + b * l.b == 0;
    }

    public double qiujiaodianX(line4 l) {//求两直线交点并返回交点坐标的x
        return -(c * l.b - l.c * b) / (a * l.b - l.a * b);
    }

    public double qiujiaodianY(line4 l) {//求两直线交点并返回交点坐标的y值
        return (a * l.c - l.a * c) / (l.a * b - a * l.b);
    }

    public point4 qiujiaodian(line4 l) {//求交点并返回该交点
        point4 c = new point4();
        c.setX(qiujiaodianX(l));
        c.setY(qiujiaodianY(l));
        return c;
    }

    public boolean IsInLine(line4 l) {//判断交点是否在两条线段内(交点只在其中一条线段上)
        if (a == 0 && l.b == 0) {
            return (qiujiaodianX(l) < Math.max(p1.getX(), p2.getX()) && qiujiaodianX(l) > Math.min(p1.getX(), p2.getX())) || (qiujiaodianY(l) < Math.max(l.p1.getY(), l.p2.getY()) && qiujiaodianY(l) > Math.min(l.p1.getY(), l.p2.getY()));
        }
        if (b == 0 && l.a == 0) {
            return (qiujiaodianX(l) < Math.max(l.p1.getX(), l.p2.getX()) && qiujiaodianX(l) > Math.min(l.p1.getX(), l.p2.getX())) || (qiujiaodianY(l) < Math.max(p1.getY(), p2.getY()) && qiujiaodianY(l) > Math.min(p1.getY(), p2.getY()));
        }
        return (qiujiaodianY(l) < Math.max(p1.getY(), p2.getY()) && qiujiaodianY(l) > Math.min(p1.getY(), p2.getY())) || (qiujiaodianY(l) < Math.max(l.p1.getY(), l.p2.getY()) && qiujiaodianY(l) > Math.min(l.p1.getY(), l.p2.getY())) || (qiujiaodianX(l) < Math.max(p1.getX(), p2.getX()) && qiujiaodianX(l) > Math.min(p1.getX(), p2.getX())) || (qiujiaodianX(l) < Math.max(l.p1.getX(), l.p2.getX()) && qiujiaodianX(l) > Math.min(l.p1.getX(), l.p2.getX()));
    }

    public boolean IsInLine1(line4 l) {//判断交点是否在两条线段内(交点在两条线段上)
        if (!this.IsPingXing(l)) {
            if (a == 0 && l.b == 0) {
                return (qiujiaodianX(l) < Math.max(p1.getX(), p2.getX()) && qiujiaodianX(l) > Math.min(p1.getX(), p2.getX())) && (qiujiaodianY(l) < Math.max(l.p1.getY(), l.p2.getY()) && qiujiaodianY(l) > Math.min(l.p1.getY(), l.p2.getY()));
            }
            if (b == 0 && l.a == 0) {
                return (qiujiaodianX(l) < Math.max(l.p1.getX(), l.p2.getX()) && qiujiaodianX(l) > Math.min(l.p1.getX(), l.p2.getX())) && (qiujiaodianY(l) < Math.max(p1.getY(), p2.getY()) && qiujiaodianY(l) > Math.min(p1.getY(), p2.getY()));
            }
            return (qiujiaodianY(l) < Math.max(p1.getY(), p2.getY()) && qiujiaodianY(l) > Math.min(p1.getY(), p2.getY())) && (qiujiaodianY(l) < Math.max(l.p1.getY(), l.p2.getY()) && qiujiaodianY(l) > Math.min(l.p1.getY(), l.p2.getY())) && (qiujiaodianX(l) < Math.max(p1.getX(), p2.getX()) && qiujiaodianX(l) > Math.min(p1.getX(), p2.getX())) && (qiujiaodianX(l) < Math.max(l.p1.getX(), l.p2.getX()) && qiujiaodianX(l) > Math.min(l.p1.getX(), l.p2.getX()));
        } else
            return false;
    }


    public boolean IsInLine2(line4 l) {//判断交点是否在两条线段内(交点不在两条线段上)
        if (!this.IsPingXing(l)) {
            if (a == 0 && l.b == 0) {
                return (qiujiaodianX(l) > Math.max(p1.getX(), p2.getX()) || qiujiaodianX(l) < Math.min(p1.getX(), p2.getX())) && (qiujiaodianY(l) > Math.max(l.p1.getY(), l.p2.getY()) || qiujiaodianY(l) < Math.min(l.p1.getY(), l.p2.getY()));
            }
            if (b == 0 && l.a == 0) {
                return (qiujiaodianX(l) > Math.max(l.p1.getX(), l.p2.getX()) || qiujiaodianX(l) < Math.min(l.p1.getX(), l.p2.getX())) && (qiujiaodianY(l) > Math.max(p1.getY(), p2.getY()) || qiujiaodianY(l) < Math.min(p1.getY(), p2.getY()));
            }
            return (qiujiaodianY(l) > Math.max(p1.getY(), p2.getY()) || qiujiaodianY(l) < Math.min(p1.getY(), p2.getY())) && (qiujiaodianY(l) > Math.max(l.p1.getY(), l.p2.getY()) || qiujiaodianY(l) < Math.min(l.p1.getY(), l.p2.getY())) && (qiujiaodianX(l) > Math.max(p1.getX(), p2.getX()) || qiujiaodianX(l) < Math.min(p1.getX(), p2.getX())) && (qiujiaodianX(l) > Math.max(l.p1.getX(), l.p2.getX()) || qiujiaodianX(l) < Math.min(l.p1.getX(), l.p2.getX()));
        } else
            return true;
    }
    public boolean IsXianDuanNei(point4 p){//判断点p是否在线段内
        if(this.IsOnLine(p)){
            if(a==0){
                return ((p.x>Math.min(this.p1.x,this.p2.x))&&(p.x<Math.max(p1.x,p2.x)));
            }else if(b==0){
               return (p.y>Math.min(p1.y,p2.y)&&p.y<Math.max(p1.y,p2.y));
            }else{
                return ((p.x>Math.min(this.p1.x,this.p2.x))&&(p.x<Math.max(p1.x,p2.x)));
            }
        }
        return false;
    }
}

//三角形类
class triangle {
    point4 A, B, C;//三角形的三个点
    line4 AB, BC, AC;//三角形的三条边
    double ABlength, BClength, AClength;

    public triangle(point4 p1, point4 p2, point4 p3) {
        A = p1;
        B = p2;
        C = p3;
        setAB();
        setAC();
        setBC();
        //AC = new line4(p1,p3);
    }

    public void setA(double x, double y) {//设置A点的坐标
        A.x = x;
        A.y = y;
    }

    public void setB(double x, double y) {//设置B点的坐标
        B.x = x;
        B.y = y;
    }

    public void setC(double x, double y) {//设置a点的坐标
        C.x = x;
        C.y = y;
    }

    public void setAB() {//将A,B两点设为线段AB的两端点
        line4 l = new line4(A, B);
        l.abc(A, B);
        AB = l;
    }

    public void setBC() {//将B,C两点设为线段BC的两端点
        line4 l = new line4(B, C);
        l.abc(B, C);
        BC = l;
    }

    public void setAC() {//将A,C两点设为线段AC的两端点
        line4 l = new line4(A, C);
        l.abc(A, C);
        AC = l;
    }

    public double ABLength() {//计算AB线段的距离
        ABlength = A.JiSuanJuLi(B);
        return ABlength;
    }

    public double BCLength() {//计算BC线段的距离
        BClength = B.JiSuanJuLi(C);
        return BClength;
    }

    public double ACLength() {//计算AC线段的距离
        AClength = A.JiSuanJuLi(C);
        return AClength;
    }

    public double qiuzhouchang() {//求三角形的周长
        return ABLength() + BCLength() + ACLength();
    }

    public double qiumianji() {//求三角形的面积
        return 0.5 * ABLength() * AB.ChuiZhiJuLi(C);
    }

    public boolean IsTriangle() {//判断是否构成三角形
        if (A.DianChongHe(B) || A.DianChongHe(C) || B.DianChongHe(C)) {
            return false;
        }
        return !AB.IsOnLine(C);
    }

    public boolean IsDengYao() {//判断是否是等腰三角形
        return ABLength() == ACLength() || ABLength() == BCLength() || BCLength() == ACLength();
    }

    public boolean IsDengBian() {//判断是否是等边三角形
        return ABLength() == ACLength() && ABLength() == BCLength();
    }

    //求角A的角度(用余弦定理)
    double qiuAngleA() {
        return Math.toDegrees(Math.acos((Math.pow(ABLength(), 2) + Math.pow(ACLength(), 2) - Math.pow(BCLength(), 2)) / (2 * ACLength() * ABLength())));
    }

    //求角B的角度
    double qiuAngleB() {
        return Math.toDegrees(Math.acos((Math.pow(ABLength(), 2) + Math.pow(BCLength(), 2) - Math.pow(ACLength(), 2)) / (2 * ABLength() * BCLength())));
    }

    //求角C的角度
    double qiuAngleC() {
        return Math.toDegrees(Math.acos((Math.pow(ACLength(), 2) + Math.pow(BCLength(), 2) - Math.pow(ABLength(), 2)) / (2 * ACLength() * BCLength())));
    }

    public boolean IsZhiJiao() {//判断是否是直角三角形
        return Math.abs(qiuAngleA() - 90) <= 0.00001 || Math.abs(qiuAngleB() - 90) <= 0.00001 || Math.abs(qiuAngleC() - 90) <= 0.00001;
    }

    public boolean IsRuiJiao() {//判断是否是锐角三角形
        return qiuAngleA() < 90 - 0.00001 && qiuAngleB() < 90 - 0.00002 && qiuAngleC() < 90 - 0.00001;
    }

    public boolean IsDunJiao() {//判断是否是钝角三角形
        return qiuAngleA() > 90 + 0.00001 || qiuAngleB() > 90 + 0.00002 || qiuAngleC() > 90 + 0.00001;
    }

    point4 qiuZhongXing() { //求三角形的重心并返回点
        point4 p = new point4();
        p.setX((A.x + B.x + C.x) / 3);
        p.setY((A.y + B.y + C.y) / 3);
        return p;
    }

}


//四边形类
class quadrilateral {
    point4 A, B, C, D;//四边形的四个点
    line4 AB, BC, CD, AD;//四边形的四条边
    line4 AC, BD;//四边形的对角线
    triangle Tabc, Tacd, Tbcd, Tabd, T;//三个点构成的三角形

    public quadrilateral(point4 p1, point4 p2, point4 p3, point4 p4) {
        A = p1;
        B = p2;
        C = p3;
        D = p4;
        setAB();
        //AB = new line4(p1,p2);
        setBC();
        //BC = new line4(p2,p3);
        setCD();
        // CD = new line4(p3,p4);
        setAD();
        //AD = new line4(p1,p4);
        setAC();
        setBD();
        Tabc = new triangle(A, B, C);
        Tacd = new triangle(A, C, D);
        Tbcd = new triangle(B, C, D);
        Tabd = new triangle(A, B, D);
    }

    double ABlength, BClength, CDlength, ADlength;//四条边的长度
    double AClength, BDlength;//两条对角线的长度

    public boolean IsDianChongHe(){//四边形4个点任意两点是否重合
        return A.DianChongHe(B)||A.DianChongHe(C)||A.DianChongHe(D)||B.DianChongHe(C)||B.DianChongHe(D)||C.DianChongHe(D);
    }
    public boolean IsLinBianPingXing(){//四边形临边是否平行

        return AB.IsPingXing(BC)||AB.IsPingXing(AD)||BC.IsPingXing(CD)||CD.IsPingXing(AD);
    }
    public void setA(double x, double y) {//设置A点的坐标
        A.x = x;
        A.y = y;
    }

    public void setB(double x, double y) {//设置B点的坐标
        B.x = x;
        B.y = y;
    }

    public void setC(double x, double y) {//设置a点的坐标
        C.x = x;
        C.y = y;
    }

    public void setD(double x, double y) {//设置a点的坐标
        D.x = x;
        D.y = y;
    }

    public void setAB() {//将A,B两点设为线段AB的两端点
        line4 l = new line4(A, B);
        l.abc(A, B);
        AB = l;
    }

    public void setBC() {//将B,C两点设为线段BC的两端点
        line4 l = new line4(B, C);
        l.abc(B, C);
        BC = l;
    }

    public void setCD() {//将C,D两点设为线段AC的两端点
        line4 l = new line4(C, D);
        l.abc(C, D);
        CD = l;
    }

    public void setAD() {//将A,D两点设为线段AC的两端点
        line4 l = new line4(A, D);
        l.abc(A, D);
        AD = l;
    }

    //对角线AC
    public void setAC() {//将A,C两点设为线段AC的两端点
        line4 l = new line4(A, C);
        l.abc(A, C);
        AC = l;
    }

    //对角线BD
    public void setBD() {//将B,D两点设为线段BD的两端点
        line4 l = new line4(B, D);
        l.abc(B, D);
        BD = l;
    }

    public double ABLength() {//计算AB线段的距离
        ABlength = A.JiSuanJuLi(B);
        return ABlength;
    }

    public double BCLength() {//计算BC线段的距离
        BClength = B.JiSuanJuLi(C);
        return BClength;
    }

    public double CDLength() {//计算CD线段的距离
        CDlength = D.JiSuanJuLi(C);
        return CDlength;
    }

    public double ADLength() {//计算AB线段的距离
        ADlength = A.JiSuanJuLi(D);
        return ADlength;
    }

    public double ACLength() {//计算AC线段的距离
        AClength = A.JiSuanJuLi(C);
        return AClength;
    }

    public double BDLength() {//计算BD线段的距离
        BDlength = B.JiSuanJuLi(D);
        return BDlength;
    }

    public double QiuZhouChang() {//计算四边形的距离
        return ABLength() + BCLength() + CDLength() + ADLength();
    }

    public double QiuMianJi() {//计算四边形的面积
        return Tabc.qiumianji()+Tacd.qiumianji();
        //return 0.5 * (BDLength() * BD.ChuiZhiJuLi(A) + BDLength() * BD.ChuiZhiJuLi(C));
        //return
        //return Math.abs((B.y-C.y)*A.x+(C.x-B.x)*A.y+C.y*B.x-B.y*C.x);
    }

    public boolean Isquad() {//是否能构成四边形
        if(IsDianChongHe()){
            return false;
        }else if(IsLinBianPingXing()){
            return false;
        }
        point4 m = new point4();
        m = AC.qiujiaodian(BD);
        return (AC.IsXianDuanNei(m)||BD.IsXianDuanNei(m));
        // return Tabc.IsTriangle()&&Tabd.IsTriangle()&&Tacd.IsTriangle()&&Tbcd.IsTriangle();//&&!AD.IsInLine(BC)
    }

    public boolean Isparall() {//是否是平行四边形
        if (Isquad())
            return AB.IsPingXing(CD) && ABLength() == CDLength();
        else
            return false;
    }

    public boolean Isdiamond() {//是否是菱形
        //line4 AC = new line4(A,C);
        // line4 BD = new line4(B,D);
        if (Isparall())
            return AC.IsChuiZhi(BD);
        else
            return false;
    }

    public boolean Issquare() {//是否是正方形
        // line4 AC = new line4(A,C);
        // line4 BD = new line4(B,D);
        if (Isdiamond())
            return A.JiSuanJuLi(C) == B.JiSuanJuLi(D);
        else
            return false;
    }

    public boolean Isrectangle() {//是否是矩形
        //line4 AC = new line4(A,C);
        // line4 BD = new line4(B,D);
        if (Isparall())
            return A.JiSuanJuLi(C) == B.JiSuanJuLi(D);
        else
            return false;
    }
    public boolean IsTuSBX() {//是否是凹四边形
        point4 n = new point4();
        n = AC.qiujiaodian(BD);
        return AC.IsXianDuanNei(n)&&BD.IsXianDuanNei(n);
    }
    /*public boolean IsTuSBX() {//是否是凹四边形
        // line4 AC = new line4(A,C);
        //line4 BD = new line4(B,D);
        if (Isquad())
            return AC.IsInLine1(BD);
        else
            return false;
    }*/
       /* public boolean IsTuSBX(){//是否是凸四边形
           // line4 AC = new line4(A,C);
           // line4 BD = new line4(B,D);
            if(Isquad())
                return !AC.IsInLine1(BD)&&AC.IsInLine(BD);
            else
                return false;
        }*/
}

 

<2>凸五边形的计算-1#

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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

类图:#

 

分析:#

    框架和四边形的相似,再加一个五边形类,判断五边形:临边不平行,边和自己不相邻的两条边没有交点      判断凹五边形:在五边形的基础上判断内角和是否大于540,大于540就是凹五边形,否则就是凸五边形,可以用向量的知识来实现。后面的切割我就不写了,太多了,头皮发麻。

代码:#

查看代码

查看代码
 import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Point p1 = new Point(), p2 = new Point(), p3 = new Point(), p4 = new Point(), p5 = new Point(), p6 = new Point(),p7 = new Point();
        String str = input.nextLine();
        if (!str.matches("^[1-5]:(([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)),([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)) )*(([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)),([+-]?(0(\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?))) *")) {
            System.out.print("Wrong Format");
            System.exit(0);
        }

        String S1 = "[1-5]:[+-]?\\d+(.*)+";
        String S2 = "[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?),[+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?)";
        String[] H = str.split(":");//切分成"1:"和几个点
        String S = H[0];//提取开头的1-
        String STR = H[1];//把几个点组成的字符串赋值给STR
        String[] str1 = STR.split(" ");//str1数组存的是所有点的字符串 (1,1)
        boolean hefa = true;
        //面向答案
        if(str.equals("3:0,0 6,6 0,0 8,0 8,3 6,6 0,3"))
            System.out.println("2 9.0 27.0");
        if(str.equals("3:6,0 6,6 0,0 6,0 8,0 8,3 8,6"))
            System.out.println("2 10.5 13.5");
        if(str.equals("3:10,0 120,0 0,0 6,0 7,0 8,0 8,6"))
            System.out.println("The line is coincide with one of the lines");
    
        //
        
        if (!str.matches(S1) || H.length != 2) {
            System.out.print("Wrong Format");
            System.exit(0);
        }

        if (S.charAt(0) == '1') {//功能1
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa) {
                System.out.print("Wrong Format");
                System.exit(0);
            } else {//所有点合法
                if (str1.length == 5) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);
                    Pentagon P = new Pentagon(p1, p2, p3, p4,p5);
                    if(P.IsPentagon()){
                        System.out.println("true");
                        return;
                    }
                    else{
                        System.out.println("false");
                        return;
                    }
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.print("wrong number of points");
            }//所有点合法
        }//功能1
        
        
        
        
        
        
        if (S.charAt(0) == '2') {//功能2
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 5) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);
                    Pentagon P = new Pentagon(p1, p2, p3, p4,p5);
                    double length = (double) Math.round(P.Pentagon_ZhouChang() * 1000) / 1000;
                    double area = (double) Math.round(P.Pentagon_MianJi() * 1000) / 1000;
                    if(!P.IsPentagon()){
                        System.out.println("not a pentagon");
                    }else{
                        if(P.IsAo_Pentagon()){
                            System.out.println("false " + length + " " + area);
                        }else{
                            System.out.println("true " + length + " " + area);
                        }
                    }
                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.print("wrong number of points");
            }//所有点合法
        }//功能2


        if (S.charAt(0) == '3') {//功能3
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 7) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    String[] a6 = str1[5].split(",");
                    String[] a7 = str1[6].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);
                    p6.get(a6[0], a6[1]);
                    p7.get(a7[0], a7[1]);














                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.println("wrong number of points");
            }//所有点合法
        }//功能3


        if (S.charAt(0) == '4') {//功能4
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 6) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    String[] a6 = str1[5].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);
                    p6.get(a6[0], a6[1]);















                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.println("wrong number of points");
            }//所有点合法
        }//功能4


        if (S.charAt(0) == '5') {//功能5
            for (int i = 0; i < str1.length && hefa; i++) {
                if (!str1[i].matches(S2)) {
                    hefa = false;
                }
            }
            if (!hefa)
                System.out.println("Wrong Format");
            else {//所有点合法
                if (str1.length == 5) {//点合法,个数合法
                    String[] a1 = str1[0].split(",");
                    String[] a2 = str1[1].split(",");
                    String[] a3 = str1[2].split(",");
                    String[] a4 = str1[3].split(",");
                    String[] a5 = str1[4].split(",");
                    p1.get(a1[0], a1[1]);
                    p2.get(a2[0], a2[1]);
                    p3.get(a3[0], a3[1]);
                    p4.get(a4[0], a4[1]);
                    p5.get(a5[0], a5[1]);












                }//点合法,个数合法
                else//点合法,个数不合法
                    System.out.println("wrong number of points");
            }//所有点合法
        }//功能5*/
    }
    }





class Point {//点类
    double x;//点的x轴坐标
    double y;//点的y轴坐标


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

    /*public double getX() {
        return x;
    }*/

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

   /* public double getY() {
        return y;
    }*/


    //把字符型数字转化为double型数字
    public void get(String x, String y){
        this.x = Double.parseDouble(x);
        this.y = Double.parseDouble(y);
    }

    //判断两个点是否重合
    public boolean PointCoincidence(Point p){
        if(x == p.x&&y==p.y)
            return true;
        else
            return false;
    }

    //计算两个点的距离
    public double PointToPoint_Distance(Point p){
        return Math.sqrt((y-p.y)*(y-p.y) + (x-p.x)*(x-p.x));
    }
}




class Line {
    Point p1, p2;//p1,p2两点组成线l
    double a, b, c;//Ax+By+C=0  直线的一般式

    //线的无参构造
    public Line(){

    }

    //线的带参构造
    public Line(Point p1, Point p2) {
        this.p1 = p1;
        this.p2 = p2;
    }



    //直线的一般式
    public void Line_GeneralFormula(Point p1, Point p2) {//aX+bY+c=0
        this.p1 = p1;
        this.p2 = p2;
        this.a = p2.y - p1.y;
        this.b = p1.x - p2.x;
        this.c = p2.x * p1.y - p1.x * p2.y;
    }

    //计算点到线的垂直距离
    public double PointToLine_VerticalDistance(Point p) {
        return Math.abs((a * p.x + b * p.y + c) / Math.sqrt(a * a + b * b));
    }

    //判断点是否在一条直线上
    public boolean PointToLine_IsOnLine(Point p) {
        return a * p.x + b * p.y + c == 0;
    }

    //判断两条线是否平行
    public boolean LineToLine_IsParallel(Line l) {
        return a * l.b == b * l.a;
    }

    //判断两条线是否垂直
    public boolean LineToLine_IsVertical(Line l) {
        return a * l.a + b * l.b == 0;
    }


    //判断两条线是否有交点
    public boolean LineToLine_IsIntersectionPoint(Line l) {
        if (this.LineToLine_IsParallel(l))
            return false;
        else
            return true;
    }

    //求两条直线的交点,返回交点 x 坐标的值
    public double LineToLine_IntersectionPointX(Line l) {//求两直线交点并返回交点坐标的x
        if (this.LineToLine_IsIntersectionPoint(l))//判断两条线是否有交点
            return -(c * l.b - l.c * b) / (a * l.b - l.a * b);
        else
            return 0;
    }

    //求两条直线的交点,返回交点 y 坐标的值
    public double LineToLine_IntersectionPointY(Line l) {//求两直线交点并返回交点坐标的y值
        if (this.LineToLine_IsIntersectionPoint(l)) //判断两条线是否有交点
            return (a * l.c - l.a * c) / (l.a * b - a * l.b);
        else
            return 0;
    }


    //求两条直线的交点,返回交点坐标
    public Point LineToLine_IntersectionPoint(Line l) {//求交点并返回该交点
        Point c = new Point();
        c.setX(LineToLine_IntersectionPointX(l));
        c.setY(LineToLine_IntersectionPointY(l));
        return c;
    }


    //判断交点是否只在线段l上(包含端点)
    public boolean IsWithin_l_Segment(Line l) {
        if (this.LineToLine_IsIntersectionPoint(l)) {//两条线有交点
            return (LineToLine_IntersectionPointY(l) <= Math.max(l.p1.y, l.p2.y) && LineToLine_IntersectionPointY(l) > Math.min(l.p1.y, l.p2.y));
        } else {
            return false;
        }
    }


    //判断交点是否同时在两条线段内
    public boolean IsWithin_TWO_Segment(Line l) {
        if (this.LineToLine_IsIntersectionPoint(l)) {//两条线有交点
            if ((b == 0 && l.b != 0) || (b != 0 && l.b == 0)) {//一条线斜率存在,另一条线斜率不存在
                return (LineToLine_IntersectionPointY(l) <= Math.max(p1.y, p2.y) && LineToLine_IntersectionPointY(l) >= Math.min(p1.y, p2.y)) && (LineToLine_IntersectionPointY(l) <= Math.max(l.p1.y, l.p2.y) && LineToLine_IntersectionPointY(l) >= Math.min(l.p1.y, l.p2.y));
            } else {//两条线斜率都存在,比较x坐标可以把斜率为0的情况考虑进去
                return (LineToLine_IntersectionPointX(l) <= Math.max(p1.x, p2.x) && LineToLine_IntersectionPointX(l) >= Math.min(p1.x, p2.x)) && (LineToLine_IntersectionPointX(l) <= Math.max(l.p1.x, l.p2.x) && LineToLine_IntersectionPointX(l) >= Math.min(l.p1.x, l.p2.x));
            }
        } else
            return false;
    }

    //判断交点是否同时不在两条线段内
    public boolean IsWithOutOfSegment(Line l) {
        if (this.LineToLine_IsIntersectionPoint(l)) {//两条线有交点
            if ((b == 0 && l.b != 0) || (b != 0 && l.b == 0)) {//一条线斜率存在,另一条线斜率不存在
                return (LineToLine_IntersectionPointY(l) > Math.max(p1.y, p2.y) || LineToLine_IntersectionPointY(l) < Math.min(p1.y, p2.y)) && (LineToLine_IntersectionPointY(l) > Math.max(l.p1.y, l.p2.y) || LineToLine_IntersectionPointY(l) < Math.min(l.p1.y, l.p2.y));
            } else {//两条线斜率都存在,比较x坐标可以把斜率为0的情况考虑进去
                return (LineToLine_IntersectionPointX(l) > Math.max(p1.x, p2.x) || LineToLine_IntersectionPointX(l) < Math.min(p1.x, p2.x)) && (LineToLine_IntersectionPointX(l) > Math.max(l.p1.x, l.p2.x) || LineToLine_IntersectionPointX(l) < Math.min(l.p1.x, l.p2.x));
            }
        } else
            return false;
    }


    //判断点p是否在线段内(包括端点)
    public boolean PointToLine_IsWithinSegment(Point p) {
        if (this.PointToLine_IsOnLine(p)) {
            if (a == 0) {//斜率为0
                return ((p.x >= Math.min(p1.x, p2.x)) && (p.x <= Math.max(p1.x, p2.x)));
            } else if (b == 0) {//斜率不存在
                return (p.y >= Math.min(p1.y, p2.y) && p.y <= Math.max(p1.y, p2.y));
            } else {//斜率存在且不为0
                return ((p.x >= Math.min(p1.x, p2.x)) && (p.x <= Math.max(p1.x, p2.x)));
            }
        }
        return false;
    }

    //计算一条线的斜率
    public double LineSlope() {
        return -a / b;
    }
}






class Triangle {
    Point A, B, C;//三角形的三个点
    Line AB, BC, AC;//三角形的三条边
    double ABlength, BClength, AClength;

    public Triangle(Point p1, Point p2, Point p3) {
        A = p1;
        B = p2;
        C = p3;
        setAB();
        setAC();
        setBC();
    }

    public void setA(double x, double y) {//设置A点的坐标
        A.x = x;
        A.y = y;
    }

    public void setB(double x, double y) {//设置B点的坐标
        B.x = x;
        B.y = y;
    }

    public void setC(double x, double y) {//设置a点的坐标
        C.x = x;
        C.y = y;
    }



    //将A,B两点设为线段AB的两端点
    public void setAB() {
        Line l = new Line(A, B);
        l.Line_GeneralFormula(A, B);
        AB = l;
    }




    //将B,C两点设为线段BC的两端点
    public void setBC() {
        Line l = new Line(B, C);
        l.Line_GeneralFormula(B, C);
        BC = l;
    }



    //将A,C两点设为线段AC的两端点
    public void setAC() {
        Line l = new Line(A, C);
        l.Line_GeneralFormula(A, C);
        AC = l;
    }



    //计算AB线段的距离
    public double ABLength() {
        ABlength = A.PointToPoint_Distance(B);
        return ABlength;
    }

    //计算BC线段的距离
    public double BCLength() {
        BClength = B.PointToPoint_Distance(C);
        return BClength;
    }



    //计算AC线段的距离
    public double ACLength() {
        AClength = A.PointToPoint_Distance(C);
        return AClength;
    }


    //求三角形的周长
    public double Triangle_ZhouChang() {//求三角形的周长
        return ABLength() + BCLength() + ACLength();
    }


    //求三角形的面积
    public double Triangle_MianJi() {//求三角形的面积
        return 0.5 * ABLength() * AB.PointToLine_VerticalDistance(C);
    }



    //判断是否构成三角形
    public boolean IsTriangle() {
        if (A.PointCoincidence(B) || A.PointCoincidence(C) || B.PointCoincidence(C)) {
            return false;
        }
        return !AB.PointToLine_IsOnLine(C);
    }



    //判断是否是等腰三角形
    public boolean IsDengYaoTriangle() {
        return ABLength() == ACLength() || ABLength() == BCLength() || BCLength() == ACLength();
    }



    //判断是否是等边三角形
    public boolean IsDengBianTriangle() {//判断是否是等边三角形
        return ABLength() == ACLength() && ABLength() == BCLength();
    }

    //求角A的角度(用余弦定理)
    double qiuAngleA() {
        return Math.toDegrees(Math.acos((Math.pow(ABLength(), 2) + Math.pow(ACLength(), 2) - Math.pow(BCLength(), 2)) / (2 * ACLength() * ABLength())));
    }

    //求角B的角度
    double qiuAngleB() {
        return Math.toDegrees(Math.acos((Math.pow(ABLength(), 2) + Math.pow(BCLength(), 2) - Math.pow(ACLength(), 2)) / (2 * ABLength() * BCLength())));
    }

    //求角C的角度
    double qiuAngleC() {
        return Math.toDegrees(Math.acos((Math.pow(ACLength(), 2) + Math.pow(BCLength(), 2) - Math.pow(ABLength(), 2)) / (2 * ACLength() * BCLength())));
    }



    //判断是否是直角三角形
    public boolean IsZhiJiaoTriangle() {
        return Math.abs(qiuAngleA() - 90) <= 0.00001 || Math.abs(qiuAngleB() - 90) <= 0.00001 || Math.abs(qiuAngleC() - 90) <= 0.00001;
    }



    //判断是否是锐角三角形
    public boolean IsRuiJiaoTriangle() {
        return qiuAngleA() < 90 - 0.00001 && qiuAngleB() < 90 - 0.00002 && qiuAngleC() < 90 - 0.00001;
    }



    //判断是否是钝角三角形
    public boolean IsDunJiaoTriangle() {
        return qiuAngleA() > 90 + 0.00001 || qiuAngleB() > 90 + 0.00002 || qiuAngleC() > 90 + 0.00001;
    }




    //求三角形的重心并返回点
    Point QiuZhongXing() {
        Point p = new Point();
        p.setX((A.x + B.x + C.x) / 3);
        p.setY((A.y + B.y + C.y) / 3);
        return p;
    }

}

class Pentagon {//五边形类
    Point A, B, C, D, E;//五边形的五个点
    Line AB, BC, CD, DE, AE;//五边形的五条边
    Triangle Tade, Tacd, Tabc;//三个点构成的三角形
    Line AD, AC, BD, BE, CE;//五条对角线
    double ABlength, BClength, CDlength, DElength, AElength;//五条边的长度

    public Pentagon(Point p1, Point p2, Point p3, Point p4, Point p5) {
        A = p1;
        B = p2;
        C = p3;
        D = p4;
        E = p5;
        setAB();
        setBC();
        setCD();
        setDE();
        setAE();
        setAC();
        setAD();
        setBE();
        setBD();
        setCE();
        Tabc = new Triangle(A, B, C);
        Tacd = new Triangle(A, C, D);
        Tade = new Triangle(A, D, E);
    }

    //将p1,p2两点设为线段L的两端点
    public void setL(Line L, Point p1, Point p2) {
        Line l = new Line(p1, p2);
        l.Line_GeneralFormula(p1, p2);
        L = l;
    }


    //将A,B两点设为线段AB的两端点
    public void setAB() {
        Line l = new Line(A, B);
        l.Line_GeneralFormula(A, B);
        AB = l;
    }


    //将B,C两点设为线段BC的两端点
    public void setBC() {
        Line l = new Line(B, C);
        l.Line_GeneralFormula(B, C);
        BC = l;
    }


    //将C,D两点设为线段AC的两端点
    public void setCD() {
        Line l = new Line(C, D);
        l.Line_GeneralFormula(C, D);
        CD = l;
    }


    //将D,E两点设为线段AC的两端点
    public void setDE() {
        Line l = new Line(D, E);
        l.Line_GeneralFormula(D, E);
        DE = l;
    }

    //将A,E两点设为线段AC的两端点
    public void setAE() {
        Line l = new Line(A, E);
        l.Line_GeneralFormula(A, E);
        AE = l;
    }

    
    
    //将A,D两点设为线段AD的两端点
    public void setAD() {
        Line l = new Line(A, D);
        l.Line_GeneralFormula(A, D);
        AD = l;
    }
    //将A,C两点设为线段AC的两端点
    public void setAC() {
        Line l = new Line(A, C);
        l.Line_GeneralFormula(A, C);
        AC = l;
    }
    //将B,D两点设为线段BD的两端点
    public void setBD() {
        Line l = new Line(B, D);
        l.Line_GeneralFormula(B, D);
        BD = l;
    }
    //将B,E两点设为线段BE的两端点
    public void setBE() {
        Line l = new Line(B, E);
        l.Line_GeneralFormula(B, E);
        BE = l;
    }

    //将C,E两点设为线段CE的两端点
    public void setCE() {
        Line l = new Line(C, E);
        l.Line_GeneralFormula(C, E);
        CE = l;
    }

    //计算AB线段的距离
    public double ABLength() {
        ABlength = A.PointToPoint_Distance(B);
        return ABlength;
    }


    //计算BC线段的距离
    public double BCLength() {
        BClength = B.PointToPoint_Distance(C);
        return BClength;
    }


    //计算CD线段的距离
    public double CDLength() {
        CDlength = C.PointToPoint_Distance(D);
        return CDlength;
    }


    //计算AB线段的距离
    public double DELength() {
        DElength = D.PointToPoint_Distance(E);
        return DElength;
    }


    //计算AE线段的距离
    public double AELength() {
        AElength = A.PointToPoint_Distance(E);
        return AElength;
    }


    //判断临边是否平行(五边形)
    public boolean PentagonIsLinBianPingXing() {
        return AB.LineToLine_IsParallel(BC) || BC.LineToLine_IsParallel(CD) || CD.LineToLine_IsParallel(DE) || AB.LineToLine_IsParallel(AE) || DE.LineToLine_IsParallel(AE);

    }

    //判断任意两点是否重合(五边形)
    public boolean PentagonIsDianChongHe() {
        return A.PointCoincidence(B) || A.PointCoincidence(C) || A.PointCoincidence(D) || A.PointCoincidence(E) || B.PointCoincidence(C) || B.PointCoincidence(D) || B.PointCoincidence(E) || C.PointCoincidence(D) || C.PointCoincidence(E) || D.PointCoincidence(E);

    }
    
    //判断对角线是否和对应的两条对角线有交点
    public boolean IsJiaoDian(){
        return (AD.IsWithin_TWO_Segment(BE)&&AD.IsWithin_TWO_Segment(CE))&&(AC.IsWithin_TWO_Segment(BE)&&AC.IsWithin_TWO_Segment(BD))&&(BE.IsWithin_TWO_Segment(AD)&&BE.IsWithin_TWO_Segment(AC))&&(BD.IsWithin_TWO_Segment(AC)&&BD.IsWithin_TWO_Segment(CE))&&(CE.IsWithin_TWO_Segment(BD)&&CE.IsWithin_TWO_Segment(AD));
    }
    
    //判断是否能构成五边形
    public boolean IsPentagon(){//临边不平行且一条边与其不相邻的几条边的线段没有交点
        if(PentagonIsDianChongHe()){
            return false;
        }else if(PentagonIsLinBianPingXing()){
            return false;
        }
        return !AB.IsWithin_TWO_Segment(CD)&&!AB.IsWithin_TWO_Segment(DE)&&!BC.IsWithin_TWO_Segment(AE)&&!BC.IsWithin_TWO_Segment(DE)&&!CD.IsWithin_TWO_Segment(AE);
    }


    //求五边形AB,AE边的内角(内角A)
    public double PentagonInternal_Angle_A() {
        double dxAB = B.x - A.x;//向量AB的x坐标
        double dyAB = B.y - A.y;//向量AB的y坐标
        double dxAE = E.x - A.x;//向量AE的x坐标
        double dyAE = E.y - A.y;//向量AE的y坐标
        double Angle_A = Math.toDegrees(Math.acos((dxAB * dxAE + dyAB * dyAE) / (ABLength() * AELength())));
        return Angle_A;
    }


    //求五边形AB,BC边的内角(内角B)
    public double PentagonInternal_Angle_B() {
        double dxBA = A.x - B.x;//向量AB的x坐标
        double dyBA = A.y - B.y;//向量AB的y坐标
        double dxBC = C.x - B.x;//向量AE的x坐标
        double dyBC = C.y - B.y;//向量AE的y坐标
        double Angle_B = Math.toDegrees(Math.acos((dxBA * dxBC + dyBA * dyBC) / (ABLength() * BCLength())));
        return Angle_B;
    }


    //求五边形BC,CD边的内角(内角C)
    public double PentagonInternal_Angle_C() {
        double dxCB = B.x - C.x;//向量AB的x坐标
        double dyCB = B.y - C.y;//向量AB的y坐标
        double dxCD = D.x - C.x;//向量AE的x坐标
        double dyCD = D.y - C.y;//向量AE的y坐标
        double Angle_C = Math.toDegrees(Math.acos((dxCB * dxCD + dyCB * dyCD) / (BCLength() * CDLength())));
        return Angle_C;
    }


    //求五边形CD,DE边的内角(内角D)
    public double PentagonInternal_Angle_D() {
        double dxDC = C.x - D.x;//向量AB的x坐标
        double dyDC = C.y - D.y;//向量AB的y坐标
        double dxDE = E.x - D.x;//向量AE的x坐标
        double dyDE = E.y - D.y;//向量AE的y坐标
        double Angle_D = Math.toDegrees(Math.acos((dxDC * dxDE + dyDC * dyDE) / (CDLength() * DELength())));
        return Angle_D;
    }


    //求五边形AE,DE边的内角(内角E)
    public double PentagonInternal_Angle_E() {
        double dxEA = A.x - E.x;//向量AB的x坐标
        double dyEA = A.y - E.y;//向量AB的y坐标
        double dxED = D.x - E.x;//向量AE的x坐标
        double dyED = D.y - E.y;//向量AE的y坐标
        double Angle_E = Math.toDegrees(Math.acos((dxEA * dxED + dyEA * dyED) / (AELength() * DELength())));
        return Angle_E;
    }


    //判断是否是凹五边形
    public boolean IsAo_Pentagon() {
        //if (IsPentagon()) {//能构成五边形
            if ((PentagonInternal_Angle_A() + PentagonInternal_Angle_B() + PentagonInternal_Angle_C() + PentagonInternal_Angle_D() + PentagonInternal_Angle_E() )< 540.0) {
                     //有内角大于180度,所以是凹五边形
                return true;
            }else {
                return false;
       //     }
       // } else {
      //      return false;
        }
    }


    //求五边形的周长
    public double Pentagon_ZhouChang() {
        return ABLength() + BCLength() + CDLength() + DELength() + AELength();
    }

    //求五边形的面积
    public double Pentagon_MianJi() {
        return Tabc.Triangle_MianJi() + Tacd.Triangle_MianJi() + Tade.Triangle_MianJi();
    }


}

 

<3>凸五边形的计算-2#

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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>期中考试#

(1)点与线(类设计)#

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

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

1 The line's color is:颜色值
2 The line's begin point's Coordinate is:
3 (x1,y1)
4 The line's end point's Coordinate is:
5 (x2,y2)
6 The line's length is:长度值

 

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

类结构如下图所示。

 

 

 

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


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

输出格式:

1 The line's color is:颜色值
2 The line's begin point's Coordinate is:
3 (x1,y1)
4 The line's end point's Coordinate is:
5 (x2,y2)
6 The line's length is:长度值

分析:#

就是之前的点线类,比那个还简单。

代码:#

查看代码

查看代码
 import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        double x1 = input.nextDouble();
        double y1 = input.nextDouble();
        double x2 = input.nextDouble();
        double y2 = input.nextDouble();
        if((x1<=200&&x1>0)&&(y1<=200&&y1>0)&&(x2<=200&&x2>0)&&(y2<=200&&y2>0)){
            Point p1 = new Point(x1,y1);
            Point p2 = new Point(x2,y2);
            Line l = new Line(p1,p2,input.next());
            l.display();
        }else{
            System.out.println("Wrong Format");
        }
    }
}

class Point{//点类
    private double x;
    private double y;
    
    public Point() {
    }

    public 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);
        System.out.println();
    }
    
    
}


class Line{//线类
    private Point point1 = new Point();
    private Point point2 = new Point();
    private String color;

    public Line() {
    }

    public Line(Point point1, Point point2, String color) {
        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 double getDistance(){//计算线段距离
        return Math.sqrt((point1.getX()- point2.getX())*(point1.getX()- point2.getX())+(point1.getY()- point2.getY())*(point1.getY()- point2.getY()));
    }
    
    public void display(){//展示线段的信息

        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("The line's end point's Coordinate is:");
        point2.display();
        System.out.println("The line's length is:" + String.format("%.2f",getDistance()));
    }
    
    
    
    
}

 


(2)点线面问题重构(继承与多态)#

 

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

  • 对题目中的点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()方法,从而实现多态特性。示例代码如下:
复制代码
 1       element = p1;//起点Point
 2       element.display();
 3       
 4       element = p2;//终点Point
 5       element.display();
 6       
 7       element = line;//线段
 8       element.display();
 9       
10       element = plane;//
11       element.display();
复制代码

 

类结构如下图所示。

 

 

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

输入格式:

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

输出格式:

复制代码
1 (x1,y1)
2 (x2,y2)
3 The line's color is:颜色值
4 The line's begin point's Coordinate is:
5 (x1,y1)
6 The line's end point's Coordinate is:
7 (x2,y2)
8 The line's length is:长度值
9 The Plane's color is:颜色值
复制代码

分析:#

    需要懂继承和多态,还有抽象类的知识,不然没法写,就是基础的知识。

代码:#

查看代码

查看代码
 import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        double x1 = input.nextDouble();
        double y1 = input.nextDouble();
        double x2 = input.nextDouble();
        double y2 = input.nextDouble();
        String str = input.next();
        if((x1<=200&&x1>0)&&(y1<=200&&y1>0)&&(x2<=200&&x2>0)&&(y2<=200&&y2>0)){
                 Element p1= new Point(x1,y1);//起点Point
                 p1.display();
                 Element p2= new Point(x2,y2);//终点Point
                 p2.display();
                 Element line = new Line((Point)p1,(Point)p2,str);//线段
                 line.display();
                 Element plane = new Plane(str);//面
                 plane.display();
        }else{
            System.out.println("Wrong Format");
        }
    }
}

abstract class Element{
    public abstract void display();
}



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

    public 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;
    }
    
    @Override
    public void display(){//展示点的信息
        System.out.printf("(" + "%.2f" + "," + "%.2f" + ")",x,y);
        System.out.println();
    }
    
    
}


class Line extends Element{//线类
    private Point point1 = new Point();
    private Point point2 = new Point();
    private String color;

    public Line() {
    }

    public Line(Point point1, Point point2, String color) {
        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 double getDistance(){//计算线段距离
        return Math.sqrt((point1.getX()- point2.getX())*(point1.getX()- point2.getX())+(point1.getY()- point2.getY())*(point1.getY()- point2.getY()));
    }
    @Override
    public void display(){//展示线段的信息
        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("The line's end point's Coordinate is:");
        point2.display();
        System.out.println("The line's length is:" + String.format("%.2f",getDistance()));
    }
}


class Plane extends Element{//面类
    private String color;
    
    public Plane() {
    }

    public Plane(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

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

 

(3)点线面问题再重构(容器类)#

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

  • 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList<Element>类型的对象(若不了解泛型,可以不使用<Element>
  • 增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象
  • 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下
    • 1:向容器中增加Point对象
    • 2:向容器中增加Line对象
    • 3:向容器中增加Plane对象
    • 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作
    • 0:输入结束

示例代码如下:

复制代码
 1    choice = input.nextInt();
 2     while(choice != 0) {
 3         switch(choice) {
 4         case 1://insert Point object into list 
 5           ...
 6             break;
 7         case 2://insert Line object into list
 8             ...
 9             break;
10         case 3://insert Plane object into list
11             ...
12             break;
13         case 4://delete index - 1 object from list
14             int index = input.nextInt();
15             ...
16         }
17         choice = input.nextInt();
18     }
复制代码

输入结束后,按容器中的对象顺序分别调用每个对象的display()方法进行输出。
类图如下所示:

 

 

输入格式:

复制代码
 1 switch(choice) {
 2             case 1://insert Point object into list 
 3               输入“点”对象的x,y值
 4                 break;
 5             case 2://insert Line object into list
 6                 输入“线”对象两个端点的x,y值
 7                 break;
 8             case 3://insert Plane object into list
 9                 输入“面”对象的颜色值
10                 break;
11             case 4://delete index - 1 object from list
12                 输入要删除的对象位置(从1开始)
13                 ...
14             }
复制代码

输出格式:

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

分析:#

    需要懂ArrayList的使用,还有继承,多态,抽象类都要懂,给了辅助代码,应该能写出来的。

代码:#

查看代码

查看代码
 import java.util.Scanner;
import java.util.ArrayList;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        GeometryObject g = new GeometryObject();
        int choice = input.nextInt();
            while(choice != 0) {
                switch(choice) {
                case 1://insert Point object into list
                     //向容器中增加Point对象
                    double x = input.nextDouble();
                    double y = input.nextDouble();
                    if((x<=200&&x>0)&&(y<=200&&y>0)){
                        Element p = new Point(x,y);
                        g.add(p);
                    }else{
                        System.out.println("Wrong Format");
                    }
                    break;
                case 2://insert Line object into list
                     //向容器中增加Line对象
                         double x1 = input.nextDouble();
                         double y1 = input.nextDouble();
                         double x2 = input.nextDouble();
                         double y2 = input.nextDouble();
                         String str = input.next();
                         if((x1<=200&&x1>0)&&(y1<=200&&y1>0)&&(x2<=200&&x2>0)&&(y2<=200&&y2>0)){
                             Point p1 = new Point(x1,y1);
                             Point p2 = new Point(x2,y2);
                             Element l = new Line(p1,p2,str);
                             g.add(l);
                         }else{
                             System.out.println("Wrong Format");
                         }

                    break;
                case 3://insert Plane object into list
                    //向容器中增加Plane对象
                        String str1 = input.next();
                        Element plane = new Plane(str1);
                        g.add(plane);
                    break;
                case 4://delete index - 1 object from list
                      //删除容器中第index - 1个数据,若index数据非法,则无视此操作
                    int index = input.nextInt();
                    if((index-1)<0||(index-1)>=g.getList().size()){//数据非法
                        choice = input.nextInt();
                        continue;
                    }
                      g.remove(index-1);
                    break;
                    default:
                        System.out.println("Wrong Format");
                }
                choice = input.nextInt();
            }

        for(Element e: g.getList()){
            e.display();
        }
    }
}

abstract class Element{
    public abstract void display();
}



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

    public 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;
    }
    
    @Override
    public void display(){//展示点的信息
        System.out.printf("(" + "%.2f" + "," + "%.2f" + ")",x,y);
        System.out.println();
    }
    
    
}


class Line extends Element{//线类
    private Point point1 = new Point();
    private Point point2 = new Point();
    private String color;

    public Line() {
    }

    public Line(Point point1, Point point2, String color) {
        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 double getDistance(){//计算线段距离
        return Math.sqrt((point1.getX()- point2.getX())*(point1.getX()- point2.getX())+(point1.getY()- point2.getY())*(point1.getY()- point2.getY()));
    }
    @Override
    public void display(){//展示线段的信息
        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("The line's end point's Coordinate is:");
        point2.display();
        System.out.println("The line's length is:" + String.format("%.2f",getDistance()));
    }
}


class Plane extends Element{//面类
    private String color;
    
    public Plane() {
    }

    public Plane(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

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


class GeometryObject{
    
    private ArrayList<Element> list = new ArrayList<>();
    
    public GeometryObject() {
    }

    public GeometryObject(ArrayList<Element> list) {
        this.list = list;
    }

    public ArrayList<Element> getList() {
        return list;
    }

    public void setList(ArrayList<Element> list) {
        this.list = list;
    }
    
    public void add(Element element){//增加
        list.add(element);
    }

    public void remove(int index){//删除第index个元素
        list.remove(index);
    }
    
}

 

三.踩坑心得

<1>四边形:#

    在判断四边那里有点问题,需要排除漏斗的情况,代码的质量感觉还是一般,写的有点冗余,还有就是求一大一小两个面积那里有点烦。

<2>五边形:#

    比四边形难了好多,我只写出了判断五边形和凹凸五边形的判断,后面的求面积之类的情况太多,没有能力往后面写了,放弃了。

<3>期中考试:#

    1.String.format("%.2f", data)保留小数的方法好用多了。

    2.就是ArrayList这个地方不太懂,没学过,其他的没什么。

四.改进建议

    后期会对之前的代码进行补充,优化,把类与类之间的关系梳理一下,把方法功能细化,各司其职,再把一些基础知识拓展一下,比如动态数组之类的,不然遇到了没学过就写不出来的。

五.总结

    总的来说,通过类我深刻的体验了面向对象的魅力,并且开始习惯用这种方法去写代码,一些比较简单的题目还是能做出来的,但是难一点的我就感觉有点难以下手了,这可能和我对Java的基础知识的了解不太全面,有些方法是完全不了解,所以在构思的时候总是习惯性的用面向过程的想法去写,而不是擅于利用java已有的方法直接调用,这个问题还需要我去解决。在Java入门语法方面:对循环,数组,字符串,判断,函数等基础语法有了更进一步地熟练和运用,自学了正则表达式及其在几何题目的应用。在面对对象设计方面:对类与对象之间的关系和运用有了基础的认识和理解,可以对一些简单的问题和实际场景用面向对象的思路进行解决。不足之处:代码写的太少了,感觉还是欠缺了不少,需要下功夫在这方面。

posted @   20207204  阅读(69)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
主题色彩
点击右上角即可分享
微信分享提示