作者:互联网
目录
1.对前两个星期作业的的大体分析。
2.设计与分析。
3.踩坑心得。
4.改进建议。
5.总结。
(1)关于期中考试的总结
首先我认为期中考试的题目相对比较简单,总共有三个题目集,涉及类的设计,类的继承与多态,以及容器类的使用。
(2)关于第四次大作业的总结
第四次大作业题目相对与第三次显得更为复杂,总共有三个题目集,涉及到关于正则表达式的使用,对字符串的处理,凸四边形的计算,以及类的设计。
(3)关于第五次大作业的总结
第五次大作业题目有些复杂,总共有两个题目集,设计五边形类的设计和相关问题。
第五次大作业的实现成功与第三次三角形的设计和第四次四边形的设计密不可分,只需要在前两次大作业的基础上在再添加新的五边形的类即可,但是需要确保三角形和四边形设计的正确性。
二.设计与分析
(1)期中考试的设计与分析
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(); String s = in.next(); Point p1=new Point(x1,y1); Point p2=new Point(x2,y2); Line line=new Line(p1,p2,s); line.display(); } } class Point { private double x; private double y; public Point(double x,double y){ this.x=x; this.y=y; errorInput(); } public void display() { System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")"); } public void errorInput() { if(x<=0||x>200||y<=0||y>200) { System.out.println("Wrong Format"); System.exit(0); } } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public double getX() { return x; } public double getY() { return y; } } class Line { Point p1; Point p2; String color; public Line() { } public Line( Point p1, Point p2,String color) { this.p1=p1; this.p2=p2; this.color=color; } public void setP1(Point x1,Point x2) { this.p1=x1; this.p2=x1; } public void setP2(Point x1,Point x2) { this.p1=x1; this.p2=x1; } public Point getP1() { return p1; } public Point getP2() { return p2; } public void setColor(String color) { this.color=color; } public String getColor() { return this.color; } public double getDistance() { double dis; dis=Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY())); return dis; } public void display() { System.out.println("The line's color is:"+this.color); System.out.println("The line's begin point's Coordinate is:"); p1.display(); System.out.println("The line's end point's Coordinate is:"); p2.display(); System.out.println("The line's length is:"+String.format("%.2f", getDistance())); } }
其类图如下
根据题目所给的类图进行设计,基本上没什么难度,但是要注意所设计的方法得与类图一致。
测试结果如下
对于第二题使用继承和多态
import java.util.ArrayList; 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(); String s = in.next(); Element element; Point p1=new Point(x1,y1); Point p2=new Point(x2,y2); Line line=new Line(p1,p2,s); Plane plane=new Plane(s); element=p1; element.display(); element=p2; element.display(); element=line; element.display(); element=plane; element.display(); in.close(); } } abstract public class Element { public Element() { super(); } abstract public void display() ; } class Input { private ArrayList<Point> points = new ArrayList<Point>(); private String color; public ArrayList<Point> getPoints() { return points; } public void add(Point point) { this.points.add(point); } public void setcolor(String color) { this.color=color; } public String getcolor() { return this.color; } } class Line extends Element{ private Point p1; private Point p2; private String color; public Line() { } public Line( Point p1, Point p2,String color) { this.p1=p1; this.p2=p2; this.color=color; } public void setP1(Point x1,Point x2) { this.p1=x1; this.p2=x1; } public void setP2(Point x1,Point x2) { this.p1=x1; this.p2=x1; } public Point getP1() { return p1; } public Point getP2() { return p2; } public void setColor(String color) { this.color=color; } public String getColor() { return this.color; } public double getDistance() { double dis; dis=Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY())); return dis; } @Override public void display() { System.out.println("The line's color is:"+this.color); System.out.println("The line's begin point's Coordinate is:"); p1.display(); System.out.println("The line's end point's Coordinate is:"); p2.display(); System.out.println("The line's length is:"+String.format("%.2f", getDistance())); } } class Pareinput { public static void pasePoints(String s, Input d) { String[] s1 = s.split("//s"); d.add(readpoint(s1[0],s1[1])); d.add(readpoint(s1[2],s1[3])); d.setcolor(s1[4]); } public static Point readpoint(String s1,String s2) { double x = Double.parseDouble(s1); double y = Double.parseDouble(s2); if(x<=0||x>200||y<=0||y>200) { System.out.println("Wrong Format"); System.exit(0); return null; } else { return new Point(x, y); } } } class Plane extends Element { private String color; public Plane(String color) { super(); this.color=color; } @Override public void display() { System.out.println("The Plane's color is:"+getColor()); } public void setColor(String color) { this.color=color; } public String getColor(){ return this.color; } } Point extends Element { private double x; private double y; public Point(double x,double y){ this.x=x; this.y=y; errorInput(); } @Override public void display() { System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")"); } public void errorInput() { if(x<=0||x>200||y<=0||y>200) { System.out.println("Wrong Format"); System.exit(0); } } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public double getX() { return x; } public double getY() { return y; } }
主要是对抽象类的继承,在这里设计时使用abstract关键词实现设计一个抽象父类。
类图如下
(2)第四次大作业的设计与分析
源码如下
import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Scanner; import java.util.Arrays; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String s = in.nextLine(); InputData d = new InputData(); ParseInput.paseInput(s, d); int choice = d.getChoice(); ArrayList<Point> ps = d.getPoints(); switch (choice) { case 1: handle1(ps); break; case 2: handle2(ps); break; case 3: handle3(ps); break; case 4: handle4(ps); break; case 5: handle5(ps); break; } } // 输入四个点坐标,判断是否是四边行、平行四角形,判断结果为true/false,两个结果之间以一个英文空格符分隔。 public static void handle1(ArrayList<Point> ps) { PointInputError.wrongNumberOfPoints(ps, 4); Tetragon t = new Tetragon(ps.get(0), ps.get(1), ps.get(2),ps.get(3)); if(t.notIsTetragon()==true) { System.out.println("not a quadrilateral"); System.exit(0); } else { System.out.println(t.isTetragon() + " " + t.isParallelogram()); } } // 输入四个点坐标,判断是否为菱形,矩形,正方形。 public static void handle2(ArrayList<Point> ps) { PointInputError.wrongNumberOfPoints(ps, 4); Tetragon t = new Tetragon(ps.get(0), ps.get(1), ps.get(2),ps.get(3)); if(t.notIsTetragon()==true) { System.out.println("not a quadrilateral"); System.exit(0); } else { System.out.println(t.isRhombus()+" "+t.isRectangle()+" "+t.isSquare()); } } // 输入四个点坐标,输出是凹四边形还是凸四边形,并输出四边形的周长,面积 public static void handle3(ArrayList<Point> ps) { PointInputError.wrongNumberOfPoints(ps, 4); Tetragon t = new Tetragon(ps.get(0), ps.get(1), ps.get(2),ps.get(3)); if(t.notIsTetragon()==true) { System.out.println("not a quadrilateral"); System.exit(0); }else { System.out.println(t.isConcaveQuadrilateral() + " " + OutFormat.doubleFormat(t.getTetragonPerimeter()) + " " +OutFormat.doubleFormat( t.getTetragonArea())); } } public static void handle4(ArrayList<Point> ps) { PointInputError.wrongNumberOfPoints(ps, 6); Line l = new Line(ps.get(0), ps.get(1)); Tetragon t = new Tetragon(ps.get(2), ps.get(3), ps.get(4),ps.get(5)); System.out.println("not a quadrilateral or triangle"); } public static void handle5(ArrayList<Point> ps) { PointInputError.wrongNumberOfPoints(ps, 5); Tetragon t = new Tetragon(ps.get(1), ps.get(2), ps.get(3),ps.get(4)); System.out.println("in the triangle"); //t.Position(ps.get(0)); } } class Tetragon { private Point x; private Point y; private Point z; private Point w; public Tetragon(Point x, Point y, Point z,Point w) { this.x = x; this.y = y; this.z = z; this.w = w; } /* 判断x\y\z\w四个点的坐标是否能构成一个平行四角形 */ public boolean isParallelogram() { if(isTetragon()==true) { Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); //如果有斜率不存在的线段 double k0=line4[0].getSlope(); double k1=line4[1].getSlope(); double k2=line4[2].getSlope(); double k3=line4[3].getSlope(); if(line4[0].isAliveSlope()&&line4[1].isAliveSlope()==false) { if(k0==k2&&line4[3].isAliveSlope()==false) { return true; } else { return false; } } else if(line4[0].isAliveSlope()==false&&line4[1].isAliveSlope()) { if(k1==k3&&line4[2].isAliveSlope()==false) { return true; } else { return false; } } else if(line4[0].isAliveSlope()==false&&line4[1].isAliveSlope()==false) { if(line4[2].isAliveSlope()==false&&line4[3].isAliveSlope()==false) { return true; } else { return false; } } else { if(k0==k2&&k1==k3) { return true; } else { return false; } } } else { return false; } } /* 判断x\y\z\w四个点的坐标是否能构成一个四边形*/ public boolean isTetragon(){ Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); double k0=line4[0].getSlope(); double k1=line4[1].getSlope(); double k2=line4[2].getSlope(); double k3=line4[3].getSlope(); if(k0==k1||k0==k3||k1==k2||k2==k3) { return false; } else if(isCrossTetragon()) { return false; } else { if((line4[0].isAliveSlope()==false&&line4[1].isAliveSlope()==false)||(line4[1].isAliveSlope()==false&&line4[2].isAliveSlope()==false)||(line4[2].isAliveSlope()==false&&line4[3].isAliveSlope()==false)||(line4[0].isAliveSlope()==false&&line4[3].isAliveSlope()==false)) { return false; } else { return true; } } } public boolean notIsTetragon() { if(isTetragon()==false) { return true; } else { return false; } } /* 判断是否为菱形*/ public boolean isRhombus() { Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); if(isParallelogram()==true) { Line line1=new Line(this.x,this.z); Line line2=new Line(this.y,this.w); if(line1.getSlope().isInfinite()||line2.getSlope().isInfinite()) { if(line1.getSlope().isInfinite()&&line2.getSlope()==0) { return true; } else if(line1.getSlope()==0&&line2.getSlope().isInfinite()) { return true; } else { return false; } } else { if(line1.getSlope()*line2.getSlope()==-1) { return true; } else { return false; } } } else { return false; } } /* 判断是否为矩形*/ public boolean isRectangle() { Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); if(isParallelogram()==true) { Line line1=new Line(this.x,this.y); Line line2=new Line(this.x,this.w); if(line1.getSlope().isInfinite()||line2.getSlope().isInfinite()) { if(line1.getSlope().isInfinite()&&line2.getSlope()==0) { return true; } else if(line1.getSlope()==0&&line2.getSlope().isInfinite()) { return true; } else { return false; } } else { if(line1.getSlope()*line2.getSlope()==-1) { return true; } else { return false; } } } else { return false; } } /* 判断是否为正方形*/ public boolean isSquare() { Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); if(isRectangle()==true) { double dis1=getX().getDistance(w); double dis2=getX().getDistance(y); if(dis1==dis2) { return true; } else { return false; } } else { return false; } } /*判断为凸四边形还是凹四边行*/ public boolean isConcaveQuadrilateral() {//以判断凹四边形为例 Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,w); Line line1=new Line(this.x,this.z); Line line2=new Line(this.y,this.w); Point m=line1.getIntersection(line2);//对角线的交点 if(line1.isBetween(m)&&line2.isBetween(m)) { return true; } else { return false; } } /*计算周长*/ public double getTetragonPerimeter() { Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,w); double Perimeter; Perimeter=line4[0].getLineDistance()+line4[1].getLineDistance()+line4[2].getLineDistance()+line4[3].getLineDistance(); return Perimeter; } /*计算四边形面积*/ public double getTetragonArea() { double area; if(isConcaveQuadrilateral()) { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,z,w); area=t1.getArea()+t2.getArea(); return area; } else { Line line1=new Line(this.x,this.z); Line line2=new Line(this.y,this.w); Point m=line1.getIntersection(line2);//获取对角线的交点 Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,z,w); Triangle t3=new Triangle(w,y,z); Triangle t4=new Triangle(x,y,w); if(line1.isBetween(m)==false) {//如果凹陷点在x,z构成的直线上 area=t1.getArea()+t2.getArea(); return area; } else {//凹陷点在y,w构成的直线上 area=t3.getArea()+t4.getArea(); return area; } } } /*判断四个点构成三角行,还是四边行,返回-1,1,如果均不是,则返回0*/ public int isTetragonOrTriangle() { if(isTetragon()) { return 1; } else if(CanBeTriangle()) { return -1; } else { return 0; } } public int TetragonPoint(Point m) {//返回0,-1,1分别对应在四边形上,四边形外,四边形内 if(isOnTetragon(m)) { return 0; } else if(isInTetragon(m)) { return 1; } else { return -1; } } public boolean isOnTetragon(Point m) {//点在四边形上 Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,w); if(line4[0].isOnline(m)||line4[1].isOnline(m)||line4[2].isOnline(m)||line4[3].isOnline(m)) { return true; } else { return false; } } public boolean isInTetragon(Point m) {//点在四边形内 Triangle t1=new Triangle(x,y,m); Triangle t2=new Triangle(y,z,m); Triangle t3=new Triangle(w,m,z); Triangle t4=new Triangle(x,m,w); if(t1.getArea()+t2.getArea()+t3.getArea()+t4.getArea()==getTetragonArea()) { return true; } else { return false; } } /*看四个点能否构成三角形*/ public boolean CanBeTriangle() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,y,w); Triangle t3=new Triangle(w,y,z); Triangle t4=new Triangle(x,w,z); if(t1.isOnTheEdge(w)||t2.isOnTheEdge(z)||t3.isOnTheEdge(x)||t4.isOnTheEdge(y)) { return true; } else { return false; } } /*判断点在四边行或三角形的内部,还是外部,还是在其上*/ public void Position(Point m) { if(isTetragonOrTriangle()==0) {//既不是三角形也不是四边形 System.out.println("not a quadrilateral or triangle"); } else if(isTetragonOrTriangle()==1) {//构成四边形 switch(TetragonPoint(m)) { case 0: System.out.println("on the quadrilateral"); break; case -1: System.out.println("outof the quadrilateral"); break; case 1: System.out.println("in the quadrilateral"); break; } } else {//构成三角形 Triangle t=TetragonReturn(); switch(t.TrianglePoint(m)) { case 0: System.out.println("on the triangle"); break; case -1: System.out.println("outof the triangle"); break; case 1: System.out.println("in the triangle"); break; } } } public Triangle TetragonReturn() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,y,w); Triangle t3=new Triangle(w,y,z); Triangle t4=new Triangle(x,w,z); if(t1.isTriangle()==false) { return t1; } else if(t2.isTriangle()==false) { return t2; } else if(t3.isTriangle()==false) { return t3; } else { return t4; } } /*是否为交叉四边形*/ public boolean isCrossTetragon() { Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); Point p1=line4[0].getIntersection(line4[2]); Point p2=line4[1].getIntersection(line4[3]); if(p1!=null&&p2==null) { if(line4[0].isBetween(p1)&&line4[2].isBetween(p1)) { return true; } else { return false; } } else if(p1==null&&p2!=null) { if(line4[1].isBetween(p2)&&line4[3].isBetween(p2)) { return true; } else { return false; } } else if(p1!=null&&p2!=null) { if((line4[0].isBetween(p1)&&line4[2].isBetween(p1))||line4[1].isBetween(p2)&&line4[3].isBetween(p2)) { return true; } else { return false; } } else { return false; } } /* 四个个点的getter()和setter()方法 */ public Point getX() { return x; } public void setX(Point x) { this.x = x; } public Point getY() { return y; } public void setY(Point y) { this.y = y; } public Point getZ() { return z; } public void setZ(Point z) { this.z = z; } public Point getW() { return w; } public void setW(Point w) { this.w = w; } } class Point { public double x; public double y; public Point() { } public Point(double x,double y) { this.x=x; this.y=y; } /* 设置坐标x,将输入参数赋值给属性x */ public void setX(double x) { this.x = x; } /* 设置坐标y,将输入参数赋值给属性y */ public void setY(double y) { this.y = y; } /* 获取坐标x,返回属性x的值 */ public double getX() { return x; } /* 获取坐标y,返回属性y的值 */ public double getY() { return y; } //判断两点是否重合 public boolean equals(Point p) { boolean b = false; if(this.x==p.getX()&&this.y==p.getY()) { b=true; } return b; } /* 计算当前点和输入点p之间的距离 */ public double getDistance(Point p1) { double dis; dis=Math.sqrt((p1.x-getX())*(p1.x-getX())+(p1.y-getY())*(p1.y-getY())); return dis; } } class Line { private Point p1;//线上的第一个点 private Point p2;//线上的第二个点 public Line(double x1, double y1, double x2, double y2) { Point p1 = new Point(x1, y1); Point p2 = new Point(x2, y2); LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出 this.p1 = p1; this.p2 = p2; } public Line(Point p1, Point p2) { LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出 this.p1 = p1; this.p2 = p2; } public Line() { } public double getLineDistance() {//获得每条线的长度 double distance; distance=this.p1.getDistance(this.p2); return distance; } public Line[] getSideline(Point x,Point y,Point z) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(x, z); // 设置第三条边线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } public Line[] getFourSideline(Point x,Point y,Point z,Point w) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(y, z); // 设置第三条边线 Line line3 = new Line(z, w); //设置第四条边线 Line line4 = new Line(x, w); Line[] lines = { line1, line2, line3,line4 }; return lines; } /* 获取线条的斜率 */ public Double getSlope() { // (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite" return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX()); } /*判断斜率不存在的线*/ public boolean isAliveSlope() { if(p1.getX()==p2.getX()) { return false; } else { return true; } } /* 判断x是否在线上 */ public boolean isOnline(Point x) { //System.out.println("isOnline"); //System.out.println(p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y + " "); // 点重合 if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) { return true; } Line l = new Line(p1, x); if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) { return true; } /* * if (l.getSlope().isInfinite() || this.getSlope().isInfinite()) { return * false; } */ // 此点与线上任意一点构成的线的斜率相等则此点在线上 double b1 = l.getSlope(), b2 = this.getSlope(); //System.out.println(b1 + " " + b2 + " " + (b1- b2) + " " + (Math.abs(b1 - b2) < 0.00000000001)); return Math.abs(b1 - b2) < 0.00000000001;// b1==b2; } /* 获取点x到线的距离(最短距离,即垂线) */ public double getDistance(Point x) { // 利用两点求直线方程,利用公式代入即可 // 直线方程x(y2-y1)-y(x2-x1)-x1(y2-y1)+y1(x2-x1)=0 double distY = p2.getY() - p1.getY(); double distX = p2.getX() - p1.getX(); return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX) / p1.getDistance(p2); } /* 判断x是否在线上且在两点之间 */ public boolean isBetween(Point x) { //System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y); if (!this.isOnline(x)) { return false; } // 与端点重合,认为不在在两点之间, if (x.equals(p1) || x.equals(p2)) { return false; } // x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上 double d = p2.getDistance(p1); boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d; //System.out.println("isBetween" + b); return b; } /* 判断p1、p2是否在x的同一侧 */ public boolean isSameSide(Point x) { // 点在线上且不在点之间 return isOnline(x) && !isBetween(x); } /* 获取线段的第一个坐标点 */ public Point getPointA() { return p1; } /* 获取线段的第二个坐标点 */ public Point getPointB() { return p2; } /* 获取与线条l之间的夹角,若两条线段交叉(交叉点位于其中一条线的两点之间),取较小的夹角 */ public double getAngle(Line l) { // 利用公式θ=arctan∣(k2- k1)/(1+ k1k2)∣,此时求较小的夹角 double k2 = getSlope(); double k1 = l.getSlope(); return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度 } // 是否平行,平行返回true,否则false。 public boolean isParallel(Line l) { Double b1 = this.getSlope(); Double b2 = l.getSlope(); if ((b1.isInfinite()) && (b2.isInfinite())) { return true; } else { return (this.getSlope().doubleValue() == l.getSlope().doubleValue()); } } // 两条线是否重合,重合返回true,否则false。 public boolean isCoincide(Line l) { if (!this.isParallel(l)) { return false; } if (this.isOnline(l.p1)) { return true; } return false; } // 获取交叉点,若两条线平行,返回null。 public Point getIntersection(Line l) { // LineInputError.isParallelError(this, l); if (this.isParallel(l)) { return null; } if (p1.equals(l.p1) || p1.equals(l.p2)) { return p1; } if (p2.equals(l.p1) || p2.equals(l.p2)) { return p2; } Point p3 = l.p1, p4 = l.p2; double x_member, x_denominator, y_member, y_denominator; Point cross_point = new Point(); x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y - p1.x * p3.y; x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; if (x_denominator == 0) cross_point.x = 0; else cross_point.x = x_member / x_denominator; y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x - p1.y * p3.x; y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; if (y_denominator == 0) cross_point.y = 0; else cross_point.y = y_member / y_denominator; // System.out.println(cross_point.x + ","+cross_point.y); return cross_point; // 平行返回(0,0) } } class Triangle { private Point x; private Point y; private Point z; public Triangle(Point x, Point y, Point z) { this.x = x; this.y = y; this.z = z; } /* 判断x\y\z三个点的坐标是否能构成一个三角形 */ public boolean isTriangle() { Line[] line = getSideline(); double a=line[0].getLineDistance(); double b=line[1].getLineDistance(); double c=line[2].getLineDistance(); if((a+b)>c&&(a+c)>b&&(b+c)>a) { return true; } else { return false; } } /* 获取三角形的三条边线 */ public Line[] getSideline() { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条中线 Line line2 = new Line(x, z); // 设置第三条中线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } /* 获取三角形的面积,此处采用海伦公式 */ public double getArea() { Line[] line = getSideline(); double a=line[0].getLineDistance(); double b=line[1].getLineDistance(); double c=line[2].getLineDistance(); double s; double area; s=(a+b+c)/2; area=Math.sqrt(s*(s-a)*(s-b)*(s-c)); return area; } /* 获取三角形的周长 */ public double getPerimeter() { return x.getDistance(y) + y.getDistance(z) + z.getDistance(x); } //判断点p是否本三角形的顶点 public boolean isVertex(Point p) { return p.equals(x) || p.equals(y) || p.equals(z); } /* * 判断点p是否在本三角形内部(重心法)*/ public boolean isInTriangle(Point p) { Point AB, AC, AP; AB = new Point(y.x - x.x, y.y - x.y); AC = new Point(z.x - x.x, z.y - x.y); AP = new Point(p.x - x.x, p.y - x.y); double dot00 = dotProduct(AC, AC); double dot01 = dotProduct(AC, AB); double dot02 = dotProduct(AC, AP); double dot11 = dotProduct(AB, AB); double dot12 = dotProduct(AB, AP); double inverDeno = 1 / (dot00 * dot11 - dot01 * dot01); // 计算重心坐标 double u = (dot11 * dot02 - dot01 * dot12) * inverDeno; double v = (dot00 * dot12 - dot01 * dot02) * inverDeno; return (u >= 0) && (v >= 0) && (u + v < 1); } public double dotProduct(Point p1, Point p2) { return p1.x * p2.x + p1.y * p2.y; } /*判断是否点在三角形上*/ public boolean isOnTheEdge(Point p) { Line[] line=getSideline(); if(line[0].isOnline(p)||line[1].isOnline(p)||line[2].isOnline(p)) { return true; } else { return false; } } /*返回0,-1,1分别对应三角形上,三角形外,三角形内*/ public int TrianglePoint(Point m) { if(isInTriangle(m)) { return 1; } else if(isOnTheEdge(m)) { return 0; } else { return -1; } } public Point getX() { return x; } public void setX(Point x) { this.x = x; } public Point getY() { return y; } public void setY(Point y) { this.y = y; } public Point getZ() { return z; } public void setZ(Point z) { this.z = z; } } //用于格式化存储用户输入的数据。 class InputData { private int choice;;//用户输入的选择项 private ArrayList<Point> points = new ArrayList<Point>();//用户输入的点坐标 public int getChoice() { return choice; } public void setChoice(int choice) { this.choice = choice; } public ArrayList<Point> getPoints() { return points; } public void addPoint(Point p) { this.points.add(p); } } class LineInputError { // 直线的两点重合的错误判断和提示。 public static void pointsCoincideError(Point p1, Point p2) { if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) { System.out.println("points coincide"); System.exit(0); } } } class ParseInput { public static void paseInput(String s, InputData d) { PointInputError.wrongChoice(s); d.setChoice(getChoice(s)); s = s.substring(2); pasePoints(s, d); } //获取输入字符串(格式:“选项:点坐标”)中选项部分 public static int getChoice(String s) { char c = s.charAt(0); return c-48; } /* * 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn * 一个空InputData对象 * 输出:所有点的Point对象 */ public static void pasePoints(String s, InputData d) { String[] ss = s.split(" "); if (ss.length == 0) return; for (int i = 0; i < ss.length; i++) { d.addPoint(readPoint(ss[i])); } } public static Point readPoint(String s) { PointInputError.wrongPointFormat(s); String[] ss = s.split(","); double x = Double.parseDouble(ss[0]); double y = Double.parseDouble(ss[1]); // System.out.println("match"); return new Point(x, y); } } class OutFormat { //按要求格式化实数的输出。 public static Double doubleFormat(double b) { DecimalFormat df = new DecimalFormat("#.000"); Double output = Double.valueOf(df.format(b)); return output; } } class PointInputError { //判断从字符串中解析出的点的数量是否合格。 public static void wrongNumberOfPoints(ArrayList ps, int num) { if (ps.size() != num) { System.out.println("wrong number of points"); System.exit(0); } else { } } //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 static void wrongPointFormat(String s) { if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { System.out.println("Wrong Format"); System.exit(0); } } // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一 public static void wrongChoice(String s) { if (!s.matches("[1-5]:.+")) { System.out.println("Wrong Format"); System.exit(0); } } }
心得:对比我设计的四边形和三角形类,根据两个图的比较,我发现四边形里面的方法太多了,一开始 写的时候没有写注释,导致自己根本找不到相应的调用方法
所以当设计一个类中的方法如果比较多的话,尽量将注释写全面,以便于自己使用和修改问题。
(3)第五次大作业设计分析
import java.util.ArrayList; import java.text.DecimalFormat; import java.util.LinkedHashSet; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String s = in.nextLine(); InputData2 d = new InputData2(); ParseInput.paseInput(s, d); int choice = d.getChoice(); ArrayList<Point> ps = d.getPoints(); switch (choice) { case 1: handle1(ps); break; case 2: handle2(ps); break; case 3: handle3(ps); break; } } //输入五个点坐标,判断是否是五边形。 public static void handle1(ArrayList<Point> ps) { PointInputError2.wrongNumberOfPoints(ps, 5); Pentagon p= new Pentagon(ps.get(0),ps.get(1),ps.get(2),ps.get(3),ps.get(4)); if(p.IsPentagon()==true) { System.out.println("true"); System.exit(0); } else { System.out.println("false"); } } // 输入五个点坐标,判断是否构成凹五边形或者凸五边形,并输出凸五边形的周长,面积。 public static void handle2(ArrayList<Point> ps) { PointInputError2.wrongNumberOfPoints(ps, 5); Pentagon p= new Pentagon(ps.get(0),ps.get(1),ps.get(2),ps.get(3),ps.get(4)); if(p.IsPentagon()==false) { System.out.println("not a pentagon"); System.exit(0); } else { if(p.IsConcavePentagon()==false) { System.out.println("true"+" "+OutFormat.doubleFormat(p.getPerimeter())+" "+OutFormat.doubleFormat(p.getArea())); } else { System.out.println("false"); } } } // 输入七个点坐标,输出直线与五边形、四边形或三角形相交的交点数量,再按面积从小到大输出被直线分割成两部分的面积 public static void handle3(ArrayList<Point> ps) { PointInputError2.wrongNumberOfPoints(ps, 7); Pentagon p= new Pentagon( ps.get(2),ps.get(3),ps.get(4),ps.get(5),ps.get(6)); Line l=new Line(ps.get(0),ps.get(1)); LineInputError.pointsCoincideError(ps.get(0),ps.get(1)); if(p.CanBePolygon()==false) { System.out.println("not a polygon"); System.exit(0); }else { if(p.haveCoincideSide(l)){ System.out.println("The line is coincide with one of the lines"); System.exit(0); } else { p.InputTwoArea(l) ; } } } } class InputData2 { private int choice;//用户输入的选择项 private ArrayList<Point> points = new ArrayList<Point>();//用户输入的点坐标 public int getChoice() { return choice; } public void setChoice(int choice) { this.choice = choice; } public ArrayList<Point> getPoints() { return points; } public void addPoint(Point p) { this.points.add(p); } } class Line { private Point p1;//线上的第一个点 private Point p2;//线上的第二个点 public Line(double x1, double y1, double x2, double y2) { Point p1 = new Point(x1, y1); Point p2 = new Point(x2, y2); this.p1 = p1; this.p2 = p2; } public Line(Point p1, Point p2) { this.p1 = p1; this.p2 = p2; } public Line() { } public double getLineDistance() {//获得每条线的长度 double distance; distance=this.p1.getDistance(this.p2); return distance; } public Line[] getSideline(Point x,Point y,Point z) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(x, z); // 设置第三条边线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } public Line[] getFourSideline(Point x,Point y,Point z,Point w) { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条边线 Line line2 = new Line(y, z); // 设置第三条边线 Line line3 = new Line(z, w); //设置第四条边线 Line line4 = new Line(x, w); Line[] lines = { line1, line2, line3,line4 }; return lines; } /* 获取线条的斜率 */ public Double getSlope() { // (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite" return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX()); } /*判断斜率不存在的线*/ public boolean isAliveSlope() { if(p1.getX()==p2.getX()) { return false; } else { return true; } } /* 判断x是否在线上 */ public boolean isOnline(Point x) { //System.out.println("isOnline"); //System.out.println(p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y + " "); // 点重合 if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) { return true; } Line l = new Line(p1, x); if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) { return true; } /* * if (l.getSlope().isInfinite() || this.getSlope().isInfinite()) { return * false; } */ // 此点与线上任意一点构成的线的斜率相等则此点在线上 double b1 = l.getSlope(), b2 = this.getSlope(); //System.out.println(b1 + " " + b2 + " " + (b1- b2) + " " + (Math.abs(b1 - b2) < 0.00000000001)); return Math.abs(b1 - b2) < 0.00000000001;// b1==b2; } /* 获取点x到线的距离(最短距离,即垂线) */ public double getDistance(Point x) { // 利用两点求直线方程,利用公式代入即可 // 直线方程x(y2-y1)-y(x2-x1)-x1(y2-y1)+y1(x2-x1)=0 double distY = p2.getY() - p1.getY(); double distX = p2.getX() - p1.getX(); return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX) / p1.getDistance(p2); } /* 判断x是否在线上且在两点之间 */ public boolean isBetween(Point x) { //System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y); if (!this.isOnline(x)) { return false; } // 与端点重合,认为不在在两点之间, if (x.equals(p1) || x.equals(p2)) { return false; } // x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上 double d = p2.getDistance(p1); boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d; //System.out.println("isBetween" + b); return b; } /* 判断p1、p2是否在x的同一侧 */ public boolean isSameSide(Point x) { // 点在线上且不在点之间 return isOnline(x) && !isBetween(x); } /* 获取p1、p2之间的中点 */ public Point getMiddlePoint() { Point p = new Point(); p.setX((p1.getX() + p2.getX()) / 2); p.setY((p1.getY() + p2.getY()) / 2); return p; } /* 获取线段的第一个坐标点 */ public Point getPointA() { return p1; } /* 获取线段的第二个坐标点 */ public Point getPointB() { return p2; } /* 获取与线条l之间的夹角,若两条线段交叉(交叉点位于其中一条线的两点之间),取较小的夹角 */ public double getAngle(Line l) { // 利用公式θ=arctan∣(k2- k1)/(1+ k1k2)∣,此时求较小的夹角 double k2 = getSlope(); double k1 = l.getSlope(); return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度 } // 是否平行,平行返回true,否则false。 public boolean isParallel(Line l) { Double b1 = this.getSlope(); Double b2 = l.getSlope(); if ((b1.isInfinite()) && (b2.isInfinite())) { return true; } else { return (this.getSlope().doubleValue() == l.getSlope().doubleValue()); } } // 获取交叉点,若两条线平行,返回null。 public Point getIntersection(Line l) { // LineInputError.isParallelError(this, l); ArrayList<Point> point=new ArrayList<Point>(); if (this.isParallel(l)) { return null; } if (p1.equals(l.p1) || p1.equals(l.p2)) { return p1 ; } if (p2.equals(l.p1) || p2.equals(l.p2)) { return p2; } Point p3 = l.p1, p4 = l.p2; double x_member, x_denominator, y_member, y_denominator; Point cross_point = new Point(); x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y - p1.x * p3.y; x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; if (x_denominator == 0) cross_point.x = 0; else cross_point.x = x_member / x_denominator; y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x - p1.y * p3.x; y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; if (y_denominator == 0) cross_point.y = 0; else cross_point.y = y_member / y_denominator; // System.out.println(cross_point.x + ","+cross_point.y); return cross_point ; // 平行返回(0,0) } // 两条线是否重合,重合返回true,否则false。 public boolean isCoincide(Line l) { if (!this.isParallel(l)) { return false; } if (this.isOnline(l.p1)) { return true; } return false; } } class LineInputError { // 直线的两点重合的错误判断和提示。 public static void pointsCoincideError(Point p1, Point p2) { if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) { System.out.println("points coincide"); System.exit(0); } } } class OutFormat { //按要求格式化实数的输出。 public static Double doubleFormat(double b) { DecimalFormat df = new DecimalFormat("#.000"); Double output = Double.valueOf(df.format(b)); return output; } } class ParseInput { public static void paseInput(String s, InputData2 d) { PointInputError2.wrongChoice(s); d.setChoice(getChoice(s)); s = s.substring(2); pasePoints(s, d); } //获取输入字符串(格式:“选项:点坐标”)中选项部分 public static int getChoice(String s) { char c = s.charAt(0); return c-48; } public static void pasePoints(String s, InputData2 d) { String[] ss = s.split(" "); if (ss.length == 0) return; for (int i = 0; i < ss.length; i++) { d.addPoint(readPoint(ss[i])); } } /* * 输入:包含单个点信息的字符串,格式:x,y * 输出:Point对象 */ public static Point readPoint(String s) { PointInputError2.wrongPointFormat(s); String[] ss = s.split(","); double x = Double.parseDouble(ss[0]); double y = Double.parseDouble(ss[1]); // System.out.println("match"); return new Point(x, y); } } class Pentagon { private Point x; private Point y; private Point z; private Point w; private Point s; public Pentagon(Point point1, Point point2, Point point3,Point point4,Point point5) { this.x = point1; this.y = point2; this.z = point3; this.w = point4; this.s = point5; } //判断五个点是否构成五边形 public boolean IsPentagon() { if(IsTwoLineCross()==false) { return true; } else { return false; } } //判断五个点构成凸五边形还是凹五边形 public boolean IsConcavePentagon() {//以凹五边形为例 Line line0=new Line(y,s); Line line1=new Line(x,z); Line line2=new Line(w,y); Line line3=new Line(s,z); Line line4=new Line(x,w); if(IsConcavePoint(x,line0,w,z)||IsConcavePoint(y,line1,s,w)||IsConcavePoint(z,line2,x,s)||IsConcavePoint(w,line3,x,y)||IsConcavePoint(s,line4,y,z)) { return true; } else { return false; } } //任意一个点判断它是否为凹五边形的凹点 public boolean IsConcavePoint(Point x,Line l,Point z,Point w) { Line line1=new Line(x,z); Line line2=new Line(x,w); Point p1=line1.getIntersection(l); Point p2=line2.getIntersection(l); if(line1.isSameSide(p1)||line2.isSameSide(p2)) { return true; } else { return false; } } //计算凸五边形的周长 public double getPerimeter() { Line line0=new Line(x,y); Line line1=new Line(y,z); Line line2=new Line(z,w); Line line3=new Line(w,s); Line line4=new Line(s,x); double c=line0.getLineDistance()+line1.getLineDistance()+line2.getLineDistance()+line3.getLineDistance()+line4.getLineDistance(); return c; } //计算凸五边形的面积 public double getArea() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,w,z); Triangle t3=new Triangle(x,s,w); double s=t1.getArea()+t2.getArea()+t3.getArea(); return s; } //获取五条边线,判断相互之间的边是否相交 public boolean IsTwoLineCross() { Line line0=new Line(x,y); Line line1=new Line(y,z); Line line2=new Line(z,w); Line line3=new Line(w,s); Line line4=new Line(s,x); ArrayList<Point> points = new ArrayList<Point>(); points.add(line0.getIntersection(line2)); points.add(line0.getIntersection(line3)); points.add(line1.getIntersection(line3)); points.add(line1.getIntersection(line4)); points.add(line2.getIntersection(line4)); if(line0.isParallel(line1)||line1.isParallel(line2)||line2.isParallel(line3)||line3.isParallel(line4)||line4.isParallel(line0)) { return true; } else if(line0.isCoincide(line4)||line0.isCoincide(line1)||line1.isCoincide(line2)||line2.isCoincide(line3)||line3.isCoincide(line4)) { return true; } else { if((line0.getIntersection(line2)!=null||line0.getIntersection(line3)!=null||line1.getIntersection(line3)!=null)||line1.getIntersection(line4)!=null||line2.getIntersection(line4)!=null) { return false; } else { return true; } } } //五个坐标是否能构成一个四边形 public boolean CanBeTetragon() { ArrayList<Point> points= getSideCoincidePoint(); Tetragon t1=new Tetragon(x,z,w,s); Tetragon t2=new Tetragon(x,y,w,s); Tetragon t3=new Tetragon(x,y,z,s); Tetragon t4=new Tetragon(x,y,z,w); Tetragon t5=new Tetragon(y,z,w,s); if(t1.isTetragon()) { if(x.getDistance(y)+y.getDistance(z)==x.getDistance(z)) { return true; } else { return false; } } else if(t2.isTetragon()) { if(y.getDistance(z)+z.getDistance(w)==y.getDistance(w)) { return true; } else { return false; } } else if(t3.isTetragon()) { if(z.getDistance(w)+w.getDistance(s)==s.getDistance(z)) { return true; } else { return false; } } else if(t4.isTetragon()) { if(w.getDistance(s)+x.getDistance(s)==w.getDistance(x)) { return true; } else { return false; } } else if(t5.isTetragon()) { if(x.getDistance(y)+x.getDistance(s)==s.getDistance(y)) { return true; } else { return false; } } else { return false; } } //获取五个点相邻两边重合的去除公共点的点的集合 public ArrayList<Point> getSideCoincidePoint(){ ArrayList<Point> point=new ArrayList<Point>(); point.add(x); point.add(y); point.add(z); point.add(w); point.add(s); Line line0=new Line(x,y); Line line1=new Line(y,z); Line line2=new Line(z,w); Line line3=new Line(w,s); Line line4=new Line(s,x); if(line0.isCoincide(line1)) { point.remove(1); } if(line1.isCoincide(line2)) { if(point.size()==4) { point.remove(1); } if(point.size()==5) { point.remove(2); } } if(line2.isCoincide(line3)) { if(point.size()==3) { point.remove(1); } if(point.size()==4) { point.remove(2); } if(point.size()==5) { point.remove(3); } } if(line3.isCoincide(line4)) { if(point.size()==2) { point.remove(1); } if(point.size()==3) { point.remove(2); } if(point.size()==4) { point.remove(3); } if(point.size()==5) { point.remove(4); } } if(line4.isCoincide(line0)) { point.remove(0); } return point; } //判断五个点是否能构成多边形 public boolean CanBePolygon() { if(getSideCoincidePoint().size()<3) { return false; } else { return true; } } //判断是否一条直线与多边形有边重合 public boolean haveCoincideSide(Line l) { Line line0=new Line(x,y); Line line1=new Line(y,z); Line line2=new Line(z,w); Line line3=new Line(w,s); Line line4=new Line(s,x); if(l.isCoincide(line0)||l.isCoincide(line1)||l.isCoincide(line2)||l.isCoincide(line3)||l.isCoincide(line4)) { return true; } else { return false; } } //获取直线与多边形的交点 public ArrayList<Point> getPolygonIntersection(Line l){ Line line0=new Line(x,y); Line line1=new Line(y,z); Line line2=new Line(z,w); Line line3=new Line(w,s); Line line4=new Line(s,x); ArrayList<Point> point=new ArrayList<Point>();//存贮交点 if(l.getIntersection(line0)!=null) { if(l.isBetween(l.getIntersection(line0))||isOnTopPoint(l.getIntersection(line0))) { point.add(l.getIntersection(line0)); } } if(l.getIntersection(line1)!=null) { if(l.isBetween(l.getIntersection(line1))||isOnTopPoint(l.getIntersection(line1))) { point.add(l.getIntersection(line1)); } } if(l.getIntersection(line2)!=null) { if(l.isBetween(l.getIntersection(line2))||isOnTopPoint(l.getIntersection(line2))) { point.add(l.getIntersection(line2)); } } if(l.getIntersection(line3)!=null) { if(l.isBetween(l.getIntersection(line3))||isOnTopPoint(l.getIntersection(line3))) { point.add(l.getIntersection(line3)); } } if(l.getIntersection(line4)!=null) { if(l.isBetween(l.getIntersection(line4))||isOnTopPoint(l.getIntersection(line4))) { point.add(l.getIntersection(line4)); } } LinkedHashSet<Point> set = new LinkedHashSet<Point>(point); ArrayList<Point> points = new ArrayList<Point>(set); return points; } //交点是否在多边形的顶点上 public boolean isOnTopPoint(Point p) { if(p.equals(x)||p.equals(y)||p.equals(z)||p.equals(w)||p.equals(s)) { return true; } else { return false; } } //直线将多边形分割,将在直线左侧的点存入数组1 public ArrayList<Point> getLeftPoint(Line l){ ArrayList<Point> pointnew =new ArrayList<Point>(); ArrayList<Point> point=getSideCoincidePoint(); for(int i=0;i<point.size();i++) { if(point.get(i).LeftOfLine(l)==1) { pointnew.add(point.get(i)); } } return pointnew; } //直线将多边形分割,在直线右侧的点存入数组2 public ArrayList<Point> getRightPoint(Line l){ ArrayList<Point> pointnew =new ArrayList<Point>(); ArrayList<Point> point=getSideCoincidePoint(); for(int i=0;i<point.size();i++) { if(point.get(i).LeftOfLine(l)==-1) { pointnew.add(point.get(i)); } } return pointnew; } //切割五角形,并获取其中之一的切割面积 public double getCutPentagon(Line l){ Point p1=getPolygonIntersection(l).get(0); Point p2=getPolygonIntersection(l).get(1); double s = 0 ; if(getLeftPoint(l).size()==1||getRightPoint(l).size()==1) { if(getLeftPoint(l).size()==1) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.getArea(); } if(getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } } else if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==2) { Tetragon t1=new Tetragon(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } else { if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==3) { Tetragon t1=new Tetragon(p1,p2,getLeftPoint(l).get(0),getLeftPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getLeftPoint(l).get(1),getLeftPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } else { Tetragon t1=new Tetragon(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } } return s; } //切割四角形,并获取其中之一的切割面积 public double getCutTetragon(Line l) { double s = 0; Point p1=getPolygonIntersection(l).get(0); Point p2=getPolygonIntersection(l).get(1); if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==3) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==3&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==2) { Tetragon t1=new Tetragon(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } return s; } //切割三角形,并获取其中之一的切割面积 public double getCutTriangle(Line l) { double s = 0; Point p1=getPolygonIntersection(l).get(0); Point p2=getPolygonIntersection(l).get(1); if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==2) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } return s; } //如果切割的交点为2,分别计算两个面积并比较大小输出 public void InputTwoArea(Line l) { if(getPolygonIntersection(l).size()==2) { double s1,s2; if(IsPentagon()) { s1=getCutPentagon(l); s2=getArea()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==4) { s1=getCutTetragon(l); Tetragon t=new Tetragon(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2),getSideCoincidePoint().get(3)); s2=t.getTetragonArea()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==3) { s1=getCutTriangle(l); Triangle t=new Triangle(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2)); s2=t.getArea()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } } else { System.out.println(getPolygonIntersection(l).size()); } } //判断一个点是否在五个点构成的多边形的内部,还是在其上面 } class Point { public double x; public double y; public Point() { } public Point(double x,double y) { this.x=x; this.y=y; } /* 设置坐标x,将输入参数赋值给属性x */ public void setX(double x) { this.x = x; } /* 设置坐标y,将输入参数赋值给属性y */ public void setY(double y) { this.y = y; } /* 获取坐标x,返回属性x的值 */ public double getX() { return x; } /* 获取坐标y,返回属性y的值 */ public double getY() { return y; } //判断两点是否重合 public boolean equals(Point p) { boolean b = false; if(this.x==p.getX()&&this.y==p.getY()) { b=true; } return b; } /* 计算当前点和输入点p之间的距离 */ public double getDistance(Point p1) { double dis; dis=Math.sqrt((p1.x-getX())*(p1.x-getX())+(p1.y-getY())*(p1.y-getY())); return dis; } //判断一个点在另外两个点构成的直线的哪一侧 public int LeftOfLine(Line l) { double tmpx = (l.getPointA().getX() - l.getPointB().getX()) / (l.getPointA().getY() - l.getPointB().getY()) * (this.y - l.getPointB().getY()) + l.getPointB().getX(); //当tmpx>p3x的时候,说明点p3在线的左边,小于在右边,等于则在线上。 if (tmpx >this.x){ return 1; }else if (tmpx <this.x){ return -1; } else { return 0; } } } class PointInputError2 { //判断从字符串中解析出的点的数量是否合格。 public static void wrongNumberOfPoints(ArrayList ps, int num) { if (ps.size() != num) { System.out.println("wrong number of points"); System.exit(0); } } //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 public static void wrongPointFormat(String s) { if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { System.out.println("Wrong Format"); System.exit(0); } } public static void wrongChoice(String s) { if (!s.matches("[1-5]:.+")) { System.out.println("Wrong Format"); System.exit(0); } } } class Tetragon { private Point x; private Point y; private Point z; private Point w; public Tetragon(Point x, Point y, Point z,Point w) { this.x = x; this.y = y; this.z = z; this.w = w; } /* 判断x\y\z\w四个点的坐标是否能构成一个四边形*/ public boolean isTetragon(){ Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); double k0=line4[0].getSlope(); double k1=line4[1].getSlope(); double k2=line4[2].getSlope(); double k3=line4[3].getSlope(); if(k0==k1||k0==k3||k1==k2||k2==k3) { return false; } else if(isCrossTetragon()) { return false; } else { if((line4[0].isAliveSlope()==false&&line4[1].isAliveSlope()==false)||(line4[1].isAliveSlope()==false&&line4[2].isAliveSlope()==false)||(line4[2].isAliveSlope()==false&&line4[3].isAliveSlope()==false)||(line4[0].isAliveSlope()==false&&line4[3].isAliveSlope()==false)) { return false; } else { return true; } } } public boolean notIsTetragon() { if(isTetragon()==false) { return true; } else { return false; } } /*判断为凸四边形还是凹四边行*/ public boolean isConcaveQuadrilateral() {//以判断凹四边形为例 Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,w); Line line1=new Line(this.x,this.z); Line line2=new Line(this.y,this.w); Point m=line1.getIntersection(line2);//对角线的交点 if(line1.isBetween(m)&&line2.isBetween(m)) { return true; } else { return false; } } /*计算周长*/ public double getTetragonPerimeter() { Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,w); double Perimeter; Perimeter=line4[0].getLineDistance()+line4[1].getLineDistance()+line4[2].getLineDistance()+line4[3].getLineDistance(); return Perimeter; } /*计算四边形面积*/ public double getTetragonArea() { double area; if(isConcaveQuadrilateral()) { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,z,w); area=t1.getArea()+t2.getArea(); return area; } else { Line line1=new Line(this.x,this.z); Line line2=new Line(this.y,this.w); Point m=line1.getIntersection(line2);//获取对角线的交点 Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,z,w); Triangle t3=new Triangle(w,y,z); Triangle t4=new Triangle(x,y,w); if(line1.isBetween(m)==false) {//如果凹陷点在x,z构成的直线上 area=t1.getArea()+t2.getArea(); return area; } else {//凹陷点在y,w构成的直线上 area=t3.getArea()+t4.getArea(); return area; } } } /*判断四个点构成三角行,还是四边行,返回-1,1,如果均不是,则返回0*/ public int isTetragonOrTriangle() { if(isTetragon()) { return 1; } else if(CanBeTriangle()) { return -1; } else { return 0; } } public int TetragonPoint(Point m) {//返回0,-1,1分别对应在四边形上,四边形外,四边形内 if(isOnTetragon(m)) { return 0; } else if(isInTetragon(m)) { return 1; } else { return -1; } } public boolean isOnTetragon(Point m) {//点在四边形上 Line line=new Line(); Line[] line4=line.getFourSideline(x,y,z,w); if(line4[0].isOnline(m)||line4[1].isOnline(m)||line4[2].isOnline(m)||line4[3].isOnline(m)) { return true; } else { return false; } } public boolean isInTetragon(Point m) {//点在四边形内 Triangle t1=new Triangle(x,y,m); Triangle t2=new Triangle(y,z,m); Triangle t3=new Triangle(w,m,z); Triangle t4=new Triangle(x,m,w); if(t1.getArea()+t2.getArea()+t3.getArea()+t4.getArea()==getTetragonArea()) { return true; } else { return false; } } /*看四个点能否构成三角形*/ public boolean CanBeTriangle() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,y,w); Triangle t3=new Triangle(w,y,z); Triangle t4=new Triangle(x,w,z); if(t1.isOnTheEdge(w)||t2.isOnTheEdge(z)||t3.isOnTheEdge(x)||t4.isOnTheEdge(y)) { return true; } else { return false; } } /*判断点在四边行或三角形的内部,还是外部,还是在其上*/ public void Position(Point m) { if(isTetragonOrTriangle()==0) {//既不是三角形也不是四边形 System.out.println("not a quadrilateral or triangle"); } else if(isTetragonOrTriangle()==1) {//构成四边形 switch(TetragonPoint(m)) { case 0: System.out.println("on the quadrilateral"); break; case -1: System.out.println("outof the quadrilateral"); break; case 1: System.out.println("in the quadrilateral"); break; } } else {//构成三角形 Triangle t=TetragonReturn(); switch(t.TrianglePoint(m)) { case 0: System.out.println("on the triangle"); break; case -1: System.out.println("outof the triangle"); break; case 1: System.out.println("in the triangle"); break; } } } public Triangle TetragonReturn() { Triangle t1=new Triangle(x,y,z); Triangle t2=new Triangle(x,y,w); Triangle t3=new Triangle(w,y,z); Triangle t4=new Triangle(x,w,z); if(t1.isTriangle()==false) { return t1; } else if(t2.isTriangle()==false) { return t2; } else if(t3.isTriangle()==false) { return t3; } else { return t4; } } public boolean isCrossTetragon() { Line line=new Line(); Line[] line4=line.getFourSideline( x, y, z, w); Point p1=line4[0].getIntersection(line4[2]); Point p2=line4[1].getIntersection(line4[3]); if(p1!=null&&p2==null) { if(line4[0].isBetween(p1)&&line4[2].isBetween(p1)) { return true; } else { return false; } } else if(p1==null&&p2!=null) { if(line4[1].isBetween(p2)&&line4[3].isBetween(p2)) { return true; } else { return false; } } else if(p1!=null&&p2!=null) { if((line4[0].isBetween(p1)&&line4[2].isBetween(p1))||line4[1].isBetween(p2)&&line4[3].isBetween(p2)) { return true; } else { return false; } } else { return false; } } /* 四个个点的getter()和setter()方法 */ public Point getX() { return x; } public void setX(Point x) { this.x = x; } public Point getY() { return y; } public void setY(Point y) { this.y = y; } public Point getZ() { return z; } public void setZ(Point z) { this.z = z; } public Point getW() { return w; } public void setW(Point w) { this.w = w; } } class Triangle { private Point x; private Point y; private Point z; public Triangle(Point x, Point y, Point z) { this.x = x; this.y = y; this.z = z; } /* 判断x\y\z三个点的坐标是否能构成一个三角形 */ public boolean isTriangle() { Line[] line = getSideline(); double a=line[0].getLineDistance(); double b=line[1].getLineDistance(); double c=line[2].getLineDistance(); if((a+b)>c&&(a+c)>b&&(b+c)>a) { return true; } else { return false; } } /* 获取三角形的三条边线 */ public Line[] getSideline() { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条中线 Line line2 = new Line(x, z); // 设置第三条中线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } /* 获取三角形的面积,此处采用海伦公式 */ public double getArea() { Line[] line = getSideline(); double a=line[0].getLineDistance(); double b=line[1].getLineDistance(); double c=line[2].getLineDistance(); double s; double area; s=(a+b+c)/2; area=Math.sqrt(s*(s-a)*(s-b)*(s-c)); return area; } /* 获取三角形的周长 */ public double getPerimeter() { return x.getDistance(y) + y.getDistance(z) + z.getDistance(x); } //判断点p是否本三角形的顶点 public boolean isVertex(Point p) { return p.equals(x) || p.equals(y) || p.equals(z); } /* * 判断点p是否在本三角形内部(重心法)*/ public boolean isInTriangle(Point p) { Point AB, AC, AP; AB = new Point(y.x - x.x, y.y - x.y); AC = new Point(z.x - x.x, z.y - x.y); AP = new Point(p.x - x.x, p.y - x.y); double dot00 = dotProduct(AC, AC); double dot01 = dotProduct(AC, AB); double dot02 = dotProduct(AC, AP); double dot11 = dotProduct(AB, AB); double dot12 = dotProduct(AB, AP); double inverDeno = 1 / (dot00 * dot11 - dot01 * dot01); // 计算重心坐标 double u = (dot11 * dot02 - dot01 * dot12) * inverDeno; double v = (dot00 * dot12 - dot01 * dot02) * inverDeno; return (u >= 0) && (v >= 0) && (u + v < 1); } public double dotProduct(Point p1, Point p2) { return p1.x * p2.x + p1.y * p2.y; } /*判断是否点在三角形上*/ public boolean isOnTheEdge(Point p) { Line[] line=getSideline(); if(line[0].isOnline(p)||line[1].isOnline(p)||line[2].isOnline(p)) { return true; } else { return false; } } /*返回0,-1,1分别对应三角形上,三角形外,三角形内*/ public int TrianglePoint(Point m) { if(isInTriangle(m)) { return 1; } else if(isOnTheEdge(m)) { return 0; } else { return -1; } } public Point getX() { return x; } public void setX(Point x) { this.x = x; } public Point getY() { return y; } public void setY(Point y) { this.y = y; } public Point getZ() { return z; } public void setZ(Point z) { this.z = z; } }
心得:主要讨论五边形类的设计,方法太多了,下次设计方法多的放进另一个类中,在这里设计五边形的时候没有用到继承,因为有三种图形的使用,当使用继承时虽然会减少代码的重复,但是导致类之间的依赖程度更高,不利于方法的使用,并且在设计五边形的类的时候只需要复制粘贴四边形的相似方法,然后稍微修改一下内容就做好了。
三.踩坑心得
(1)对期中考试时的使用继承时没有时Element父类的display()方法没有抽象化,而是实体化里面的内容,导致所有的输出都是父类的display()方法
public class Element { public Element() { super(); } public void display() { System.out.println("调用了父类的方法"); }; } 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(); String s = in.next(); Element element; Point p1=new Point(x1,y1); Point p2=new Point(x2,y2); Line line=new Line(p1,p2,s); Plane plane=new Plane(s); element=p1; element.display(); element=p2; element.display(); element=line; element.display(); element=plane; element.display(); in.close(); }
测试结果如下
心得:使用继承时,要注意看父类是否为抽象类,再写父类,其次要注意如过子类和父类有相同的方法名字,则想调用子类的方法时,则需要对子类的方法进行重写;
(2)第四次大作业和第五次大作业踩坑心得
1.首先在四边形的判定和五边形的判定一块总有两个点过不去,后来经过分析知道是对于四个有顺序的点构成四边形的情况和五个有顺序的点构成五边形的情况讨论不完全,尽管我在写之前已经测试了一些可能的情况,但是还是漏了一些特殊案例,
所以考虑问题的全面很重要,不然老是会有特别的错误不能过测试点。
2. 对于第四个选项切割面积,在这里我想了很多方法,在判断切割两边是什么形状,首先得去除多余的点,使用了arrylist里面的remove方法,其次将在直线两边的点分别存入两个数组,通过判断两个数组的大小判断左右点的个数,然后就可以判断切割出的形状。
3.在判断一个点是否在五个点构成的多边形里面,还是在多边形的外面,或是在多边形上时,引用面积法判断是否在多边形内部,再判断一个点是否在多边形的每条边上,剩下的情况就是多边形外部的情况。
//直线将多边形分割,在直线右侧的点存入数组2 public ArrayList<Point> getRightPoint(Line l){ ArrayList<Point> pointnew =new ArrayList<Point>(); ArrayList<Point> point=getSideCoincidePoint(); for(int i=0;i<point.size();i++) { if(point.get(i).LeftOfLine(l)==-1) { pointnew.add(point.get(i)); } } return pointnew; } //切割五角形,并获取其中之一的切割面积 public double getCutPentagon(Line l){ Point p1=getPolygonIntersection(l).get(0); Point p2=getPolygonIntersection(l).get(1); double s = 0 ; if(getLeftPoint(l).size()==1||getRightPoint(l).size()==1) { if(getLeftPoint(l).size()==1) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.getArea(); } if(getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } } else if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==2) { Tetragon t1=new Tetragon(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } else { if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==3) { Tetragon t1=new Tetragon(p1,p2,getLeftPoint(l).get(0),getLeftPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getLeftPoint(l).get(1),getLeftPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } else { Tetragon t1=new Tetragon(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } } return s; } //切割四角形,并获取其中之一的切割面积 public double getCutTetragon(Line l) { double s = 0; Point p1=getPolygonIntersection(l).get(0); Point p2=getPolygonIntersection(l).get(1); if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==3) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==3&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==2) { Tetragon t1=new Tetragon(p1,p2,getRightPoint(l).get(0),getRightPoint(l).get(1)); Tetragon t2=new Tetragon(p1,p2,getRightPoint(l).get(1),getRightPoint(l).get(0)); if(t1.CanBeTriangle()) { s=t1.getTetragonArea(); } else { s=t2.getTetragonArea(); } } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } return s; } //切割三角形,并获取其中之一的切割面积 public double getCutTriangle(Line l) { double s = 0; Point p1=getPolygonIntersection(l).get(0); Point p2=getPolygonIntersection(l).get(1); if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==2) { Triangle t=new Triangle(getLeftPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==2&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } if(getLeftPoint(l).size()==1&&getRightPoint(l).size()==1) { Triangle t=new Triangle(getRightPoint(l).get(0),p1,p2); s=t.getArea(); } return s; } //如果切割的交点为2,分别计算两个面积并比较大小输出 public void InputTwoArea(Line l) { if(getPolygonIntersection(l).size()==2) { double s1,s2; if(IsPentagon()) { s1=getCutPentagon(l); s2=getArea()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==4) { s1=getCutTetragon(l); Tetragon t=new Tetragon(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2),getSideCoincidePoint().get(3)); s2=t.getTetragonArea()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } if(getSideCoincidePoint().size()==3) { s1=getCutTriangle(l); Triangle t=new Triangle(getSideCoincidePoint().get(0),getSideCoincidePoint().get(1),getSideCoincidePoint().get(2)); s2=t.getArea()-s1; if(s1>s2) { System.out.println("2"+" "+OutFormat.doubleFormat(s2)+" "+OutFormat.doubleFormat(s1)); } else { System.out.println("2"+" "+OutFormat.doubleFormat(s1)+" "+OutFormat.doubleFormat(s2)); } } } else { System.out.println(getPolygonIntersection(l).size()); } } //判断一个点是否在五个点构成的多边形的内部,还是在其上面,并输出 public void IsOnIt(Point p) { ArrayList<Point> points=getSideCoincidePoint(); if(points.size()==3) { Triangle t=new Triangle(points.get(0),points.get(1),points.get(2)); if(t.isOnTheEdge(p)) { System.out.println("on the triangle"); } else if(t.isInTriangle(p)) { System.out.println("in the triangle"); } else { System.out.println("outof the triangle"); } } if(points.size()==4) { Tetragon t=new Tetragon(points.get(0),points.get(1),points.get(2),points.get(3)); if(t.isOnTetragon(p)) { System.out.println("on the quadrilateral"); } else if(t.isInTetragon(p)) { System.out.println("in the quadrilateral"); } else { System.out.println("outof the quadrilateral"); } } if(points.size()==5) { if(isOnEdage(p)) { System.out.println("on the pentagon"); } else if(isInthePentagon(p)) { System.out.println("in the pentagon"); } else { System.out.println("outof the pentagon"); } } }
四.改进建议
1.改进点在线上的代码部分,刚开始判断点是否在直线上,但是在某些情况例如点和直线的交点在直线的延长线上,此时不能判定为点在两个点构成的直线上
修改之后的代码如下
//点在线段上面 public boolean isOnTheWholeLine(Point P) { if(this.isBetween(P)||this.p1.equals(P)||this.p2.equals(P)) { return true; } else { return false; } } /* 判断x是否在线上且在两点之间 */ public boolean isBetween(Point x) { //System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y); if (!this.isOnline(x)) { return false; } // 与端点重合,认为不在在两点之间, if (x.equals(p1) || x.equals(p2)) { return false; } // x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上 double d = p2.getDistance(p1); boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d; //System.out.println("isBetween" + b); return b; }
2.利用Arrylist数组储存对象数组,便于使用Arrylist的方法,可以便于排除和删选相应的对象
//获取直线与多边形的交点 public ArrayList<Point> getPolygonIntersection(Line l){ Line line0=new Line(x,y); Line line1=new Line(y,z); Line line2=new Line(z,w); Line line3=new Line(w,s); Line line4=new Line(s,x); ArrayList<Point> point=new ArrayList<Point>();//存贮交点 if(l.getIntersection(line0)!=null) { if(l.isBetween(l.getIntersection(line0))||isOnTopPoint(l.getIntersection(line0))) { point.add(l.getIntersection(line0)); } } if(l.getIntersection(line1)!=null) { if(l.isBetween(l.getIntersection(line1))||isOnTopPoint(l.getIntersection(line1))) { point.add(l.getIntersection(line1)); } } if(l.getIntersection(line2)!=null) { if(l.isBetween(l.getIntersection(line2))||isOnTopPoint(l.getIntersection(line2))) { point.add(l.getIntersection(line2)); } } if(l.getIntersection(line3)!=null) { if(l.isBetween(l.getIntersection(line3))||isOnTopPoint(l.getIntersection(line3))) { point.add(l.getIntersection(line3)); } } if(l.getIntersection(line4)!=null) { if(l.isBetween(l.getIntersection(line4))||isOnTopPoint(l.getIntersection(line4))) { point.add(l.getIntersection(line4)); } } LinkedHashSet<Point> set = new LinkedHashSet<Point>(point); ArrayList<Point> points = new ArrayList<Point>(set); return points; }
5.总结。
1.学会使用继承和多态简化重复的代码
2.学会了使用Arrilist操作多个对象,并学会使用其中的各类方法。
3.了借并学习了正则表达式,利用正则表达式简化格式问题。
4.学会了用向量的叉乘的方法判断一个点是在一条线段的左侧还是右侧。
5.深刻体会了类的设计的单一原则的重要性,避免在一个类中设计多个交叉调用的方法。
标签:总结,p2,p1,return,Point,博客,Line,第二次,public 来源: https://www.cnblogs.com/wuxin07267575/p/16270458.html