­

第二次部落格作業

  • 2022 年 10 月 29 日
  • 筆記

目錄

前言

設計與分析

采坑心得

改進建議

總結

(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<Point> 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<Point> 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<Line> lineList = new ArrayList<>();
        lineList.add(l1);lineList.add(l2);lineList.add(l3);
        List<Point> list = new ArrayList<>();
        int cnt = 0;
        Point u;
        for(int i=0;i<lineList.size();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<Line> 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<points.length;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<g.len;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<g.len;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<g.len;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<Point>()  {
            @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<points.length;i++){
            boolean ok = true;
            for(int j=0;j<tmp_len;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<e.len;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<e.len;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<e.len;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<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:輸入結束

    示例程式碼如下:

       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<Element> ad = new ArrayList<Element>();
        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<Element> ad = new ArrayList<Element>();
    public GeometryObject() {
        super();
    }
    public void add(Element element) {
        ad.add(element);
    }
    public void remove(int index) {
        if(index>0)
            ad.remove(index);
    }
    public ArrayList<Element> getList(){
        return ad;
    }
}
第三個題目沒有全部完成,其實思路還是挺簡單的。

(3)采坑心得:

1.題目集4 7-2 判斷四邊形是否成型時,用了斜率相等判斷平行,但是在樣例中會出現類似分母為零的情況,改用了x1y2=x2y1判斷。
2.考慮相等問題的同時,需要判斷是否需要考慮精度問題,有很多點是沒加精度判斷過不去的,精度不能設置太大也不能太小,合適就好,我的話精度1e-6或者1e-12,具體問題具體分析即可。
3.我們在拿到題目時,不要一股腦的想著如何去實現功能,我們可以先將最終要設計出來的程式碼進行功能分解,進而設計出多個不同功能的類,每個類再根據應有的功能寫出相應的程式碼。

(4)改進建議:對相應題目的編碼改進給出自己的見解,做到可持續改進

1.計算幾何方面知識有所欠缺

2.我們可以參考一下別人程式碼的構造然後去自己模仿著寫,不斷改進自己的程式碼結構。

(5)總結:

這幾次作業極大的提高了本人對面向對象編程的理解,且極大的提高了本人的程式碼能力。我對JAVA中常規類的使用習慣和構建方法更加清楚,可以很熟練地處理三角形、四邊形、五邊形其他類型的題目,也能通過較為合理的設計完成題目要求。