一、前言:四、五边形以及期中考试总结
(1)点线形系列4-凸四边形的计算:该题是第四次作业的第二题,分值很高,难度比较大。本题中用到了正则表达式,数值与字符之间的转换,以及格式化format,异常处理,需要用到第三次作业中建立好的点,线,三角形的类。但之前做第三次作业时并不太会使用类的封装性思想,写出来的类很不全面,本次作业中还需要对之前写的类做修改才行。本题题目很长,要求很多,情况非常多非常麻烦,解决问题时还需要用到很多几何方面的数学方法,代码相当长。
(2)第五次作业-点线形系列5-凸五边形的计算:这次作业难度又又又升级了。分为两次小作业,第一次作业是五边形内部的的计算,第二次作业的难度还更大,主要是两个五边形之间的相关计算。主要涉及的知识包括数值与字符转换的应用,以及格式化format,异常处理以及相关数学知识,也需要使用点,线,三角形以及四边形的类,还要写五边形的类,最好写一个父类,可以大大缩减代码长度,不然代码将会巨长。本次作业我也是写了很久很久,最后还是没有的全分。
(3)期中考试:考试中的题目比较基础,也是点线系列系列的题目,分为三个小题。但这次需要改写之前写的类,加上抽象类或接口,涉及到ArrayList类,除此之外就是一些简单的分支,输入输出。题目要求比较简单,代码比较简单,但由于本人速度比较慢最后并没有做完,就差一点点!
二、设计与分析
(1)点线形系列4-凸四边形的计算
题目:用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The
line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a
quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in
the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof
the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the
quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
选项4中,若前两个输入线的点重合,输出"points coincide"。
设计分析:
源代码:(代码很长已折叠)
1 /* 2 *********点线形系列4-凸四边形的计算********** 3 */ 4 import java.util.*; 5 /**/ 6 public class Main{ 7 public static void main(String args[]){ 8 Scanner input = new Scanner(System.in); 9 String s = input.nextLine(); 10 //判断输入格式正误 11 //String[] n = s.split("[ ,]"); 12 if(!s.matches("^[1-5][:](([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))[,]([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))\\s?)+$")){ 13 System.out.println("Wrong Format"); 14 System.exit(0); 15 } 16 String[] point = s.split("[: ,]"); 17 if((point[0].matches("[1-3]")&&point.length != 9)||(point[0].matches("4")&&point.length != 13)||(point[0].matches("5")&&point.length != 11)){ 18 System.out.print("wrong number of points"); 19 return; 20 } 21 double a = Double.parseDouble(point[1]); 22 double b = Double.parseDouble(point[2]); 23 double c = Double.parseDouble(point[3]); 24 double d = Double.parseDouble(point[4]); 25 double e = Double.parseDouble(point[5]); 26 double f = Double.parseDouble(point[6]); 27 double g = Double.parseDouble(point[7]); 28 double h = Double.parseDouble(point[8]); 29 Point p1 = new Point(); 30 Point p2 = new Point(); 31 Point p3 = new Point(); 32 Point p4 = new Point(); 33 p1.setxy(a,b); 34 p2.setxy(c,d); 35 p3.setxy(e,f); 36 p4.setxy(g,h); 37 38 if(point[0].matches("[1-3]")){ 39 Line l1 = new Line(p1,p2); 40 Line l2 = new Line(p2,p3); 41 Line l3 = new Line(p3,p4); 42 Line l4 = new Line(p1,p4); 43 //选项一 44 if(point[0].equals("1")){ 45 //点重合 46 if(p1.pointsCoincide(p2)||p1.pointsCoincide(p3)||p1.pointsCoincide(p4)||p2.pointsCoincide(p3)||p2.pointsCoincide(p4)||p3.pointsCoincide(p4)){ 47 System.out.print("points coincide"); 48 return; 49 } 50 //对边交叉 51 Point xi = l1.intersection(l3); 52 Point xj = l2.intersection(l4); 53 if((xi.x>=Math.min(l2.a1.x,l2.a2.x)&&xi.x<=Math.max(l2.a1.x,l2.a2.x))||(xi.y>=Math.min(l2.a1.y,l2.a2.y)&&xi.y<=Math.max(l2.a1.y,l2.a2.y))|| 54 (xj.x>=Math.min(l2.a1.x,l2.a2.x)&&xj.x<=Math.max(l2.a1.x,l2.a2.x))||(xj.y>=Math.min(l2.a1.y,l2.a2.y)&&xj.y<=Math.max(l2.a1.y,l2.a2.y))){ 55 System.out.print("false false"); 56 return; 57 } 58 //相邻边连一线 59 if(l1.isSameTo(l2)||l3.isSameTo(l2)||l3.isSameTo(l4)||l1.isSameTo(l4)){ 60 System.out.print("false false"); 61 } 62 63 //边两两都平行 64 if(l1.isParallelOrNot(l3)&&l2.isParallelOrNot(l4)){ 65 System.out.print("true true"); 66 return; 67 } 68 System.out.print("true false"); 69 } 70 //选项2,3中不能组成四边形 71 if(point[0].equals("2")||point[0].equals("3")){ 72 //点重合 73 if (p1.pointsCoincide(p2) || p1.pointsCoincide(p3) || p1.pointsCoincide(p4) || p2.pointsCoincide(p3) || p2.pointsCoincide(p4) || p3.pointsCoincide(p4)) { 74 System.out.print("not a quadrilateral"); 75 return; 76 } 77 //相邻边连一线 78 if(l1.isSameTo(l2)||l3.isSameTo(l2)||l3.isSameTo(l4)||l1.isSameTo(l4)){ 79 System.out.print("not a quadrilateral"); 80 return; 81 } 82 //对边交叉 83 Point xi = l1.intersection(l3); 84 Point xj = l2.intersection(l4); 85 if((l1.inXian(xi)&&l3.inXian(xi))||(l2.inXian(xj)&&l4.inXian(xj))){ 86 System.out.print("not a quadrilateral"); 87 return; 88 } 89 } 90 // 91 if(point[0].equals("2")) { 92 //平行四边形 93 if (l1.isParallelOrNot(l3) && l2.isParallelOrNot(l4)) { 94 if (l1.getXianLength() == l2.getXianLength() || l3.getXianLength() == l4.getXianLength() || l3.getXianLength() == l2.getXianLength() || l1.getXianLength() == l4.getXianLength()) { 95 if (l1.isVertical(l2) || l2.isVertical(l3) || l1.isVertical(l4) || l3.isVertical(l4)) 96 System.out.print("true true true");//正方形 97 else 98 System.out.print("true false false");//菱形 99 } else { 100 System.out.print("false true false");//矩形 101 } 102 } 103 // 104 else{ 105 System.out.print("false false false"); 106 } 107 } 108 // 109 if(point[0].equals("3")){ 110 try { 111 Triangle t1 = new Triangle(p1, p2, p3); 112 Triangle t2 = new Triangle(p1, p3, p4); 113 Triangle t3 = new Triangle(p1, p2, p4); 114 Triangle t4 = new Triangle(p4, p2, p3); 115 //四边形顶点中有一个顶点在另外三个点组成的三角形内部 凹四边形 116 if(t1.inTriangle(p4)==1||t2.inTriangle(p2)==1||t3.inTriangle(p3)==1||t4.inTriangle(p1)==1){ 117 double ss = 0,cc; 118 //double s1 = 0,s2 = 0,s3 = 0,s4 = 0,s5 = 0; 119 cc = l1.getXianLength()+l2.getXianLength()+l3.getXianLength()+l4.getXianLength(); 120 if((cc * 1000) % 10 != 0){ 121 String CC = String.format("%.3f",cc); 122 System.out.print("false "+CC); 123 } 124 else 125 System.out.print("false "+cc); 126 //s5 = Math.max(); 127 if(t1.inTriangle(p4)==1||t2.inTriangle(p2)==1){ 128 ss = t3.area()+t4.area(); 129 } 130 if(t3.inTriangle(p3)==1||t4.inTriangle(p1)==1){ 131 ss = t2.area()+t1.area(); 132 } 133 if(ss * 1000 % 10 != 0) { 134 String SS = String.format("%.3f", ss); 135 System.out.print(" "+SS); 136 } 137 else 138 System.out.print(" "+ss); 139 } 140 else{ 141 double ss = 0,cc = 0; 142 ss = t1.area()+t4.area(); 143 cc = l1.getXianLength()+l2.getXianLength()+l3.getXianLength()+l4.getXianLength(); 144 if((cc * 1000) % 10 != 0){ 145 String CC = String.format("%.3f",cc); 146 System.out.print("true "+CC); 147 } 148 else 149 System.out.print("true "+cc); 150 if(ss * 1000 % 10 != 0) { 151 String SS = String.format("%.3f", ss); 152 System.out.print(" "+SS); 153 } 154 System.out.print(" "+ss); 155 } 156 }catch(Exception e2){} 157 } 158 } 159 if(point[0].equals("4")){ 160 double o = Double.parseDouble(point[9]); 161 double p = Double.parseDouble(point[10]); 162 double q = Double.parseDouble(point[11]); 163 double l = Double.parseDouble(point[12]); 164 Point p5 = new Point(); 165 Point p6 = new Point(); 166 p5.setxy(o,p); 167 p6.setxy(q,l); 168 /*Line l1 = new Line(p3,p4); 169 Line l2 = new Line(p4,p5); 170 Line l3 = new Line(p5,p6); 171 Line l4 = new Line(p3,p6);*/ 172 Quadrilateral q2 = null; 173 Line ll =null; 174 //直线是否存在 175 if(p1.pointsCoincide(p2)){ 176 System.out.print("points coincide"); 177 } 178 else { 179 ll = new Line(p1, p2); 180 try { 181 q2 = new Quadrilateral(p3, p4, p5, p6); 182 solve1(ll,q2); 183 return; 184 } catch (Exception e3) { 185 try { 186 if (!p3.pointsCoincide(p5)) {//能组成三角形 187 Line ll1 = new Line(p3, p5); 188 if (ll1.inXian1(p4) && !ll1.inXian1(p6)) { 189 Triangle s0 = new Triangle(p3, p5, p6); 190 solve(ll, s0); 191 return; 192 } 193 } else { 194 if (!p3.pointsCoincide(p4)) { 195 Line ll1 = new Line(p3, p4); 196 if (!ll1.inXian1(p5)) { 197 Triangle s0 = new Triangle(p3, p4, p5); 198 solve(ll, s0); 199 return; 200 } 201 } 202 203 } 204 //2号点为顶点 205 if (!p4.pointsCoincide(p6)) {//能组成三角形 206 Line ll1 = new Line(p4, p6); 207 if (ll1.inXian1(p5) && !ll1.inLine(p3)) { 208 Triangle s0 = new Triangle(p3, p5, p6); 209 solve(ll, s0); 210 return; 211 } 212 } else { 213 if (!p4.pointsCoincide(p5)) { 214 Line ll1 = new Line(p4, p5); 215 if (!ll1.inXian1(p3)) { 216 Triangle s0 = new Triangle(p3, p4, p5); 217 solve(ll, s0); 218 return; 219 } 220 } 221 } 222 //3号点为顶点 223 if (!p4.pointsCoincide(p6)) {//能组成三角形 224 Line ll1 = new Line(p4, p6); 225 if (ll1.inXian1(p3) && !ll1.inLine(p5)) { 226 Triangle s0 = new Triangle(p4, p5, p6); 227 solve(ll, s0); 228 return; 229 } 230 } 231 if (!p3.pointsCoincide(p5)) {//能组成三角形 232 Line ll1 = new Line(p3, p5); 233 if (ll1.inXian1(p6) && !ll1.inLine(p4)) { 234 Triangle s0 = new Triangle(p3, p4, p5); 235 solve(ll, s0); 236 return; 237 } 238 } 239 System.out.println("not a quadrilateral or triangle"); 240 241 } catch (Exception e4) { 242 } 243 } 244 } 245 } 246 //4:-2,-2 -10,-10 0,0 -10,10 0,20 10,10 247 //4:0,2 -2,0 0,0 -10,10 0,20 10,10 248 //4:10,20 0,20 0,10 0,0 30,20 0,80 249 //选项5 250 //5:2,2 +0,-0.0 -10,10 +0.0,20 10,10 251 if(point[0].equals("5")){ 252 double o = Double.parseDouble(point[9]); 253 double p = Double.parseDouble(point[10]); 254 Point p5 =new Point(); 255 p5.setxy(o,p); 256 try{ //四点构成四边形 257 Quadrilateral q1 = new Quadrilateral(p2,p3,p4,p5); 258 if(q1.isQuadrilateral(p1) == 1) System.out.println("in the quadrilateral"); 259 else if(q1.isQuadrilateral(p1) == -1) System.out.println("on the quadrilateral"); 260 else System.out.println("outof the quadrilateral"); 261 }catch(Exception e1){ 262 try{ 263 if(!p2.pointsCoincide(p4)){//能组成三角形 264 Line l = new Line(p2,p4); 265 if(l.inXian1(p3)&&!l.inXian1(p5)){ 266 Triangle s0 = new Triangle(p2,p4,p5); 267 inTrianglePut(p1,s0); 268 return; 269 } 270 } 271 else{ 272 if(!p2.pointsCoincide(p3)){ 273 Line l = new Line(p3,p2); 274 if(!l.inXian1(p5)){ 275 Triangle s0 = new Triangle(p2,p3,p5); 276 inTrianglePut(p1,s0); 277 return; 278 } 279 } 280 281 } 282 //2号点为顶点 283 if(!p3.pointsCoincide(p5)){//能组成三角形 284 Line l = new Line(p3,p5); 285 if(l.inXian1(p4)&&!l.inLine(p2)){ 286 Triangle s0 = new Triangle(p2,p3,p5); 287 inTrianglePut(p1,s0); 288 return; 289 } 290 } 291 else{ 292 if(!p3.pointsCoincide(p4)){ 293 Line l = new Line(p3,p4); 294 if(!l.inXian1(p2)){ 295 Triangle s0 = new Triangle(p2,p3,p4); 296 inTrianglePut(p1,s0); 297 return; 298 } 299 } 300 } 301 //3号点为顶点 302 if(!p3.pointsCoincide(p5)){//能组成三角形 303 Line l = new Line(p3,p5); 304 if(l.inXian1(p2)&&!l.inLine(p4)){ 305 Triangle s0 = new Triangle(p3,p4,p5); 306 inTrianglePut(p1,s0); 307 return; 308 } 309 } 310 if(!p2.pointsCoincide(p4)){//能组成三角形 311 Line l = new Line(p2,p4); 312 if(l.inXian1(p5)&&!l.inLine(p3)){ 313 Triangle s0 = new Triangle(p2,p3,p4); 314 inTrianglePut(p1,s0); 315 return; 316 } 317 } 318 System.out.println("not a quadrilateral or triangle"); 319 }catch(Exception e2){} 320 } 321 } 322 } 323 public static void inTrianglePut(Point p,Triangle t){ 324 int op = t.inTriangle(p); 325 if(op == 1) System.out.println("in the triangle"); 326 else if (op == -1) System.out.println("on the triangle"); 327 else System.out.println("outof the triangle"); 328 } 329 //三角形分隔求面积 330 public static void pr_area(Triangle t, Point a,Point b,Point c){ 331 double[] ans = new double[2]; 332 try { 333 Triangle ss = new Triangle(a,b,c); 334 ans[0] = ss.area(); 335 ans[1] = t.area() - ans[0]; 336 Arrays.sort(ans); 337 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 338 } catch (Exception e) { 339 throw new RuntimeException(e); 340 } 341 342 } 343 public static void pr_area(Quadrilateral q, Point a,Point b,Point c){ 344 double[] ans = new double[2]; 345 try { 346 Triangle ss = new Triangle(a,b,c); 347 ans[0] = ss.area(); 348 ans[1] = q.areaq() - ans[0]; 349 Arrays.sort(ans); 350 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 351 } catch (Exception e) { 352 throw new RuntimeException(e); 353 } 354 355 } 356 //输出 357 public static String changeFormat(double a){ 358 String res = String.format("%.3f",a); 359 res = res.replaceAll("0+?$", ""); 360 if(res.charAt(res.length()-1) == '.') { 361 res+='0'; 362 } 363 return res; 364 } 365 //三角形交点判断 366 public static void solve(Line l,Triangle t){ 367 //与任意一条边重合 368 if(l.isSameTo(t.l1) || l.isSameTo(t.l2) || l.isSameTo(t.l3)){ 369 System.out.println("The line is coincide with one of the lines"); 370 return; 371 } 372 //与三条边的交点(值可能为null) 373 Point p_ab = l.intersection(t.l1); 374 Point p_ac = l.intersection(t.l2); 375 Point p_bc = l.intersection(t.l3); 376 //三交点是否位于边之内 377 boolean p_ab_in=false, p_ac_in =false, p_bc_in=false; 378 if(p_ab != null) p_ab_in = t.l1.inXian(p_ab); 379 if(p_ac != null) p_ac_in = t.l2.inXian(p_ac); 380 if(p_bc != null) p_bc_in = t.l3.inXian(p_bc); 381 //任一顶点在直线之上(特判三角形的角) 382 if(l.inLine(t.A)){ 383 //与另一条边无交点或者交点在边之外 384 if(p_bc == null || !t.l3.inXian1(p_bc)){ 385 System.out.println("1"); 386 } 387 else pr_area(t,t.A,t.B,p_bc); 388 return; 389 } 390 if(l.inLine(t.B)){ 391 if(p_ac == null || !t.l2.inXian1(p_ac)){ 392 System.out.println("1"); 393 } 394 else pr_area(t,t.A,t.B,p_ac); 395 return; 396 } 397 if(l.inLine(t.C)){ 398 if(p_ab == null || !t.l1.inXian1(p_ab)){ 399 System.out.println("1"); 400 } 401 else pr_area(t,t.A,t.C,p_ab); 402 return; 403 } 404 405 //两个交点 406 if(p_ab_in && p_bc_in){ pr_area(t,t.B,p_ab,p_bc);return;} 407 if(p_ab_in && p_ac_in){ pr_area(t,t.A,p_ab,p_ac);return;} 408 if(p_bc_in && p_ac_in){ pr_area(t,t.C,p_bc,p_ac);return;} 409 //无交点 410 System.out.println("0"); 411 } 412 public static void solve1(Line l,Quadrilateral q){ 413 //与任意一条边重合 414 if(l.isSameTo(q.L1)||l.isSameTo(q.L2)||l.isSameTo(q.L3)||l.isSameTo(q.L4)){ 415 System.out.println("The line is coincide with one of the lines"); 416 return; 417 } 418 //与四条边的交点,可能为null; 419 Point p0 = l.intersection(q.L1); 420 Point p1 = l.intersection(q.L2); 421 Point p2 = l.intersection(q.L3); 422 Point p3 = l.intersection(q.L4); 423 //判断交点是否在边之上 424 boolean p0_on = false,p1_on = false,p2_on = false,p3_on = false; 425 if(p0 != null) p0_on = q.L1.inXian(p0); 426 if(p1 != null) p1_on = q.L2.inXian(p1); 427 if(p2 != null) p2_on = q.L3.inXian(p2); 428 if(p3 != null) p3_on = q.L4.inXian(p3); 429 430 //任一角在直线l之上 431 if(l.inLine(q.a)){ 432 //它的对角也在边之上 433 if(l.inLine(q.c)){ 434 pr_area(q,q.a,q.b,q.c); 435 } 436 //对角的邻边任一与直线有交点 437 else if (p2_on){ //邻边1 438 pr_area(q,q.a,p2,q.d); 439 } 440 else if (p1_on){ //邻边2 441 pr_area(q,q.a,p1,q.b); 442 } 443 else{ 444 System.out.println("1"); 445 } 446 return; 447 } 448 else if(l.inLine(q.b)){ 449 //它的对角也在边之上 450 if(l.inLine(q.d)){ 451 pr_area(q,q.b,q.c,q.d); 452 } 453 //对角的邻边任一与直线有交点 454 else if (p2_on){ //邻边1 455 pr_area(q,q.b,p2,q.c); 456 } 457 else if (p3_on){ //邻边2 458 pr_area(q,q.b,p3,q.a); 459 } 460 else{ 461 System.out.println("1"); 462 } 463 return; 464 } 465 else if (l.inLine(q.c)) { 466 //它的对角也在边之上 467 if(l.inLine(q.a)){ 468 pr_area(q,q.c,q.d,q.a); 469 } 470 //对角的邻边任一与直线有交点 471 else if (p3_on){ //邻边1 472 pr_area(q,q.c,p3,q.d); 473 } 474 else if (p0_on){ //邻边2 475 pr_area(q,q.c,p0,q.b); 476 } 477 else{ 478 System.out.println("1"); 479 } 480 return; 481 } 482 else if (l.inLine(q.d)) { 483 //它的对角也在边之上 484 if(l.inLine(q.b)){ 485 pr_area(q,q.d,q.a,q.b); 486 } 487 //对角的邻边任一与直线有交点 488 else if (p0_on){ //邻边1 489 pr_area(q,q.d,p0,q.a); 490 } 491 else if (p1_on){ //邻边2 492 pr_area(q,q.d,p1,q.c); 493 } 494 else{ 495 System.out.println("1"); 496 } 497 return; 498 } 499 500 //两个交点(邻边) 501 if(p0_on && p1_on){pr_area(q,p0,p1,q.b);return;} 502 if(p1_on && p2_on){pr_area(q,p1,p2,q.c);return;} 503 if(p2_on && p3_on){pr_area(q,p2,p3,q.d);return;} 504 if(p3_on && p0_on){pr_area(q,p3,p0,q.a);return;} 505 //对边 506 if(p0_on && p2_on){ 507 double[] ans = new double[2]; 508 ans[0] = Triangle.area(q.a,p0,p2) + Triangle.area(p0,p2,q.d); 509 ans[1] = Triangle.area(q.b,p0,p2) + Triangle.area(p0,p2,q.c); 510 Arrays.sort(ans); 511 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 512 return; 513 } 514 if(p1_on && p3_on){ 515 double[] ans = new double[2]; 516 ans[0] = Triangle.area(q.b,p1,p3) + Triangle.area(p1,p3,q.a); 517 ans[1] = Triangle.area(q.c,p1,p3) + Triangle.area(p1,p3,q.d); 518 Arrays.sort(ans); 519 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 520 return; 521 } 522 //没有交点 523 System.out.println("0"); 524 525 } 526 } 527 //点类 528 class Point{ 529 double x,y; 530 public Point(){ 531 x=0; 532 y=0; 533 } 534 public void setxy(double x,double y){ 535 this.x=x; 536 this.y=y; 537 } 538 public void print(){ 539 System.out.printf("%f,%f\n",this.x,this.y); 540 } 541 //两点之间的距离 542 public double distance(Point b1){ 543 return Math.sqrt((this.x-b1.x)*(this.x-b1.x)+(this.y-b1.y)*(this.y-b1.y)); 544 } 545 //两点是否重合 546 public boolean pointsCoincide(Point b2){ 547 return (this.x==b2.x)&&(this.y==b2.y); 548 } 549 //public boolean pointsToLine(Point b2,Point b3){ 550 551 // return 552 //} 553 } 554 //线类 555 class Line{ 556 Point a1; 557 Point a2; 558 double a,b,c; 559 public Line(Point a,Point b){ 560 this.a1=a; 561 this.a2=b; 562 this.a = (-(a.y-b.y)); 563 this.b = (a.x-b.x); 564 this.c = (-this.a*this.a1.x-this.b*this.a1.y); 565 } 566 public boolean notSlope() { 567 // 568 return this.a1.x == this.a2.x; 569 } 570 //线的长度 571 public double getXianLength(){ 572 return this.a1.distance(this.a2); 573 } 574 //求直线斜率 575 public double Slope(){ 576 return (this.a2.y-this.a1.y)/(this.a2.x-this.a1.x); 577 } 578 //判断点到直线的距离 579 public double distanceToLine(Point x0) { 580 return Math.abs((this.a2.y-this.a1.y)*x0.x+(this.a1.x-this.a2.x)*x0.y+this.a2.x*this.a1.y-this.a2.y*this.a1.x)/Math.sqrt((this.a2.y-this.a1.y)*(this.a2.y-this.a1.y)+(this.a2.x-this.a1.x)*(this.a2.x-this.a1.x)); 581 582 } 583 //判断线是否重合 584 public boolean isSameTo(Line l0) { 585 //两条直线平行且一条直线上的点到另一条直线的垂直距离为0 586 return this.isParallelOrNot(l0)&&(this.distanceToLine(l0.a1)==0); 587 } 588 589 //两条直线是否平行 590 public boolean isParallelOrNot(Line l0){ 591 //if(this.a1.pointsCoincide(this.a2)&&l0.a1.pointsCoincide(l0.a2)){//判断线的两点是否重合 592 if(this.a1.x!=this.a2.x&&l0.a1.x!=l0.a2.x){//斜率存在 593 if(this.Slope() == l0.Slope()) 594 return true; 595 } 596 else if(this.a1.x==this.a2.x&&l0.a1.x==l0.a2.x)//斜率都不存在 597 return true; 598 //} 599 //else 600 return false; 601 } 602 //两直线的交点 603 public Point intersection(Line l0){ 604 double x0,y0; 605 x0 = ((l0.a1.x-l0.a2.x)*(this.a1.y*this.a2.x-this.a1.x*this.a2.y)-(this.a1.x-this.a2.x)*(l0.a1.y*l0.a2.x-l0.a1.x*l0.a2.y))/((this.a1.y-this.a2.y)*(l0.a1.x-l0.a2.x)-(l0.a1.y-l0.a2.y)*(this.a1.x-this.a2.x)); 606 y0 = ((l0.a1.y-l0.a2.y)*(this.a1.y*this.a2.x-this.a1.x*this.a2.y)-(this.a1.y-this.a2.y)*(l0.a1.y*l0.a2.x-l0.a1.x*l0.a2.y))/((this.a1.y-this.a2.y)*(l0.a1.x-l0.a2.x)-(l0.a1.y-l0.a2.y)*(this.a1.x-this.a2.x)); 607 Point c0 = new Point(); 608 c0.setxy(x0,y0); 609 return c0; 610 } 611 //斜率不存在 612 public boolean isVertical(Line l0) { 613 // 614 return (this.Slope() * l0.Slope() == -1||(this.a1.x==this.a2.x&&l0.Slope()==0)||(l0.a1.x==l0.a2.x)&&this.Slope()==0); 615 } 616 //判断点是否在直线上 617 public boolean inLine(Point b1){ 618 return Math.abs(this.a*b1.x + this.b*b1.y + this.c) < 0.000001; 619 } 620 //判断点是否在线段上 621 public boolean inXian1(Point b1){ 622 if(!inLine(b1)) 623 return false; 624 double le = this.a1.distance(b1) + this.a2.distance(b1) - this.getXianLength(); 625 return Math.abs(le) < 0.000001; 626 } 627 //判断点是否在线段内 628 public boolean inXian(Point b1){ 629 if(!inLine(b1)) 630 return false; 631 return this.inXian1(b1)&&(!b1.pointsCoincide(this.a1))&&(!b1.pointsCoincide(this.a2)); 632 } 633 } 634 // 635 class Triangle{ 636 Point A,B,C; 637 Line l1,l2,l3; 638 // 639 public Triangle(Point a,Point b,Point c)throws Exception{ 640 try{ 641 A = a; 642 B = b; 643 C = c; 644 this.l1 = new Line(A, B); 645 this.l2 = new Line(A, C); 646 this.l3 = new Line(B, C); 647 if(this.l1.isParallelOrNot(this.l3)){ 648 throw new Exception("not a triangle"); 649 } 650 }catch(Exception e){ 651 throw e; 652 } 653 } 654 //求三角形的边长 655 public double sideLength(){ 656 return this.l1.getXianLength() + this.l2.getXianLength() + this.l3.getXianLength(); 657 } 658 //求三角形面积 659 public double area(){ 660 double leng1 = Math.abs((C.y-B.y)*A.x+(B.x-C.x)*A.y+C.x*B.y-C.y*B.x)/Math.sqrt((C.y-B.y)*(C.y-B.y)+(C.x-B.x)*(C.x-B.x)); 661 double ar = 0.5*leng1*l3.getXianLength(); 662 return ar; 663 } 664 //求三个点围成的图形面积(三点可能共线,面积为0) 665 public static double area(Point a,Point b,Point c){ 666 667 double len1 = a.distance(b); 668 double len2 = b.distance(c); 669 double len3 = c.distance(a); 670 double p = (len1 + len2 + len3) / 2; 671 return Math.sqrt(p * (p - len1) * (p - len2) * (p - len3)); 672 673 } 674 //等边三角形 675 public boolean shape1(){ 676 return A.distance(B)==B.distance(C)&&A.distance(B)==A.distance(C); 677 678 } 679 680 //等腰 681 public boolean shape2(){ 682 return A.distance(B)==A.distance(C)||A.distance(B)==B.distance(C)||A.distance(C)==B.distance(C); 683 } 684 //判断点是否在三角形内 1内 0外 -1在边上 685 public int inTriangle(Point b1){ 686 if(b1.pointsCoincide(A)||b1.pointsCoincide(B)||b1.pointsCoincide(C)||l1.inXian(b1)||l2.inXian(b1)||l3.inXian(b1)) 687 return -1; 688 double s1 =area(this.A,this.B,b1); 689 double s2 =area(this.A,this.C,b1); 690 double s3 =area(this.B,this.C,b1); 691 if(Math.abs(s1+s2+s3 - this.area())<0.000001) 692 return 1; 693 return 0; 694 } 695 } 696 class Quadrilateral{ 697 Point a,b,c,d; 698 Line L1,L2,L3,L4; 699 public Quadrilateral(Point b1,Point b2,Point b3,Point b4)throws Exception { 700 try { 701 a = b1; 702 b = b2; 703 c = b3; 704 d = b4; 705 this.L1 = new Line(b1, b2); 706 this.L2 = new Line(b2, b3); 707 this.L3 = new Line(b3, b4); 708 this.L4 = new Line(b1, b4); 709 Line jiaol1 = new Line(b1,b3); 710 Line jiaol2 = new Line(b2,b4); 711 if(L1.isParallelOrNot(L2)||L1.isParallelOrNot(L4)){ 712 throw new Exception("not a quadrilateral"); 713 714 } 715 //相邻边连一线 716 if(L3.isParallelOrNot(L2)||L3.isParallelOrNot(L4)){ 717 throw new Exception("not a quadrilateral"); 718 719 } 720 //对边交叉 721 Point xi = L1.intersection(L3); 722 Point xj = L2.intersection(L4); 723 if(xi != null && L1.inXian(xi)&&L3.inXian(xi)){ 724 throw new Exception("not a quadrilateral"); 725 } 726 if(xj != null&& L2.inXian(xj)&&L4.inXian(xj)){ 727 throw new Exception("not a quadrilateral"); 728 729 } 730 }catch (Exception e1){ 731 throw e1; 732 } 733 } 734 public double areaq(){ 735 double s1 = Triangle.area(this.a,this.b,this.c); 736 double s2 = Triangle.area(this.a,this.d,this.c); 737 return s1+s2; 738 } 739 //判断点是否在四边形中,不考虑凹四边形 740 public int isQuadrilateral(Point b1){ 741 if(b1.pointsCoincide(a)||b1.pointsCoincide(b)||b1.pointsCoincide(c)||b1.pointsCoincide(d)||this.L1.inXian(b1)||this.L2.inXian(b1)||this.L3.inXian(b1)||this.L4.inXian(b1)) 742 return -1; 743 double s1 = Triangle.area(this.a,this.b,b1); 744 double s2 = Triangle.area(this.b,this.c,b1); 745 double s3 = Triangle.area(this.c,this.d,b1); 746 double s4 = Triangle.area(this.a,this.d,b1); 747 double ss0 = areaq(); 748 if(Math.abs(ss0 - (s1+s2+s3+s4)) <0.000001) 749 return 1; 750 return 0; 751 } 752 }View Code
运行结果:
运行后还有一些点没有过。不知道是漏了哪些情况没有考虑到。
分析:由上图可知圈复杂度不是很大,最大深度和平均成本/方法比较高。相比之前不正宗的类封装,现在写的类圈复杂度减小了不少,不过平均成本和方法好像比较高,可能是我的方法设计的不是很巧妙吧,因为我确实有些方法写的比较繁琐了。
(2)第五次作业
7-1点线形系列5-凸五边形的计算1
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。
2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出"not a pentagon"
3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The
line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points
coincide"。
以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
代码如下:
1 /*凸五边形的计算-1*/ 2 import java.util.*; 3 import java.util.Arrays; 4 //点 5 class Point{ 6 double x, y; 7 public Point(){ 8 this.x = 0; 9 this.y = 0; 10 } 11 public Point(double a,double b){ 12 this.x = a; 13 this.y = b; 14 } 15 // public void print(){ 16 // String x = String.format("%.6f",this.x); 17 // String y = String.format("%.6f",this.y); 18 // x = x.replaceAll("0+?$", ""); 19 // y = y.replaceAll("0+?$", ""); 20 // System.out.printf("(%s , %s)\n",this.x,this.y); 21 // } 22 23 //两点坐标相同 24 public boolean pointsCoincide(Point b){ 25 return (this.x==b.x)&&(this.y==b.y); 26 } 27 //两点距离 28 public double disToPoint(Point b){ 29 return Math.sqrt(Math.pow(this.x-b.x,2) + Math.pow(this.y-b.y,2)); 30 } 31 //点到直线的垂直距离 32 public double disToLine(Line l){ 33 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)); 34 } 35 //判断是否在直线之上 36 public boolean inLine(Line l){ 37 return Math.abs(l.a*this.x + l.b*this.y + l.c) < 0.000001; 38 } 39 //判断是否在线段之内(包括端点) 40 public boolean inXian1(Line l){ 41 if(!this.inLine(l)) return false; 42 double res = this.disToPoint(l.sta) + this.disToPoint(l.ed) - l.getXianLength(); 43 return Math.abs(res) < 0.000001; 44 } 45 //判断是否在线段之内(不包括端点) 46 public boolean inXian(Line l){ 47 return this.inXian1(l) && (!this.pointsCoincide(l.sta)) && (!this.pointsCoincide(l.ed)); 48 } 49 50 public Point deepCopy(){ 51 Point res = new Point(); 52 res.x = this.x; 53 res.y = this.y; 54 return res; 55 } 56 public Point add(Point another){ 57 Point res = this.deepCopy(); 58 res.x += another.x; 59 res.y += another.y; 60 return res; 61 } 62 // 63 public Point sub(Point another){ 64 Point res = this.deepCopy(); 65 res.x -= another.x; 66 res.y -= another.y; 67 return res; 68 } 69 70 } 71 //线 72 class Line{ 73 Point sta, ed; 74 double a,b,c; 75 private final Point vector; 76 77 public Line(Point a,Point b)throws Exception{ 78 if(a.pointsCoincide(b)){ 79 throw new Exception("points coincide"); 80 } 81 this.sta = a; 82 this.ed = b; 83 this.a = (-(a.y-b.y)); 84 this.b = (a.x-b.x); 85 this.c = (-this.a*this.sta.x-this.b*this.sta.y); 86 this.vector = ed.sub(sta); 87 } 88 public void print(){ 89 System.out.printf("%fX + %fY + %f = 0\n",this.a,this.b,this.c); 90 } 91 92 //求线段长度 93 public double getXianLength(){ 94 return this.sta.disToPoint(this.ed); 95 } 96 //点到直线的距离 97 public double distanceToLine(Point x0) { 98 return Math.abs((this.ed.y-this.sta.y)*x0.x+(this.sta.x-this.ed.x)*x0.y+this.ed.x*this.sta.y-this.ed.y*this.sta.x)/Math.sqrt((this.ed.y-this.sta.y)*(this.ed.y-this.sta.y)+(this.ed.x-this.sta.x)*(this.ed.x-this.sta.x)); 99 } 100 //斜率不存在 101 public boolean isVertical(){ 102 return sta.x == ed.x; 103 } 104 //求线段斜率 105 public double Slope(){ 106 if(this.b == 0){ 107 return 2^48; 108 } 109 return -this.a / this.b; 110 } 111 112 //判断是否平行 113 public boolean isParallelOrNot(Line l0){ 114 if(this.b==0 || l0.b==0){ 115 return (this.b == 0 && l0.b == 0); 116 } 117 return ((this.a / this.b) == (l0.a / l0.b)); 118 } 119 120 //判断是否重合 121 public boolean isSameTo(Line l0){ 122 return this.isParallelOrNot(l0) && (this.sta.inLine(l0)); 123 } 124 125 //判断是否垂直 126 public boolean isVerticalOrNot(Line l0){ 127 return this.a * l0.a + this.b * l0.b == 0; 128 } 129 //求两条直线交点 130 public Point getIntersection(Line l0){ 131 if(this.isParallelOrNot(l0)) return null; 132 Point res = new Point(); 133 res.y = (l0.a*this.c-this.a*l0.c) / (this.a*l0.b-l0.a*this.b); 134 res.x = (this.b*l0.c-l0.b*this.c) / (this.a*l0.b-l0.a*this.b); 135 return res; 136 } 137 138 //LineSegmentIntersection 获取线段交点,返回值可能为null 139 public Point lsi(Line l0){ 140 Point res = this.getIntersection(l0); 141 if(res == null) return res; 142 boolean ok = (res.inXian1(this) && res.inXian1(l0)); 143 return ok ? res:null; 144 } 145 146 //求向量模 147 public double vectorLength(){ 148 return Math.sqrt( Math.pow(this.vector.x,2) + Math.pow(this.vector.y,2) ); 149 } 150 //求向量点积 151 public double vectorMul(Line another){ 152 return (this.vector.x * another.vector.x) + (this.vector.y * another.vector.y); 153 } 154 155 //求向量叉积 156 public double vectorCrossMul(Line another){ 157 return (this.vector.x * another.vector.y) - (another.vector.x * this.vector.y); 158 } 159 //求两向量夹角(非0向量) 160 public double vectorAngle(Line another){ 161 double cos_angle = this.vectorMul(another) / (this.vectorLength() * another.vectorLength()); 162 return Math.acos(cos_angle); 163 } 164 165 } 166 167 168 class Graph { 169 public int len=0,status=1; //多边形边数,状态 170 public Point[] points; 171 public Line[] lines; 172 public double sideLength = 0,area = 0; //边长,面积 173 public boolean isConvexGraphical = true; 174 public String message = "init"; //信息 175 176 public Graph(Point[] points){ 177 this.points = new Point[points.length]; 178 179 points = this.removeMulti(points); //去除重复点 180 if(points.length <=2 ){ 181 this.status = -1; 182 this.message = "Not enough points"; 183 return; 184 } 185 186 //相邻边夹角0则去除中间点,夹角180则status:-1 187 for(int i=0;i<points.length;i++){ 188 int first = i , second = (i+1)%points.length, third = (i+2)%points.length; 189 try{ 190 Line l1 = new Line(points[first],points[second]); 191 Line l2 = new Line(points[second],points[third]); 192 if( Math.abs(l1.vectorAngle(l2) - Math.PI) < 0.000001 ){ //夹角180 193 this.status = -1; 194 this.message = "lines reverse coincidence"; 195 return; 196 } 197 else if(Math.abs(l1.vectorAngle(l2)) > 0.000001){ //夹角不为0 198 this.points[this.len++] = points[second].deepCopy(); 199 } 200 }catch (Exception e){} 201 } 202 203 this.points = Arrays.copyOf(this.points,this.len); 204 this.lines = new Line[this.len]; 205 206 //初始化边 207 for(int i=0;i<this.len;i++){ 208 try { 209 int first = i, second = (i+1)%this.len; 210 this.lines[i] = new Line(this.points[first], this.points[second]); 211 }catch (Exception e){} 212 } 213 214 //判断任意不相邻边(线段交点)是否有交点 215 checkEdge(); 216 217 Graph.area(this); 218 Graph.sideLength(this); 219 Graph.checkConvex(this); 220 } 221 /*public void print(){ 222 if(this.status == -1){ 223 System.out.println(this.message); 224 return; 225 } 226 System.out.println("点数为:"+this.len); 227 for(int i=0;i<this.len;i++){ 228 this.points[i].print(); 229 } 230 for(int i=0;i<this.len;i++){ 231 this.lines[i].print(); 232 } 233 System.out.println("周长为:"+this.sideLength); 234 System.out.println("面积为:"+this.area); 235 System.out.println("凹凸性:"+this.isConvexGraphical); 236 }*/ 237 //判断图形是否包含某个点返回值-1,0,1 (内部,边缘,外部) 238 //由于只考虑凸多边形,用面积法就行 239 public int isContainPoint(Point p){ 240 for(int i=0;i<this.len;i++){ //位于边之上 241 if(p.inXian1(this.lines[i])) return 0; 242 } 243 244 double s = 0; 245 for(int i=0;i<this.len;i++){ 246 s += Triangle.area(p,this.points[i], this.points[(i+1)%this.len]); 247 } 248 return Math.abs(s-this.area) < 0.000001 ? -1:1; 249 } 250 251 //去除所有重复点 252 private Point[] removeMulti(Point[] points){ 253 Point[] tmp_points = new Point[points.length]; 254 int tmp_len = 0; 255 256 for(int i=0;i<points.length;i++){ 257 boolean ok = true; 258 for(int j=0;j<tmp_len;j++){ 259 if(points[i].pointsCoincide(tmp_points[j])){ 260 this.message = "points coincide"; 261 ok = false; 262 break; 263 } 264 } 265 if(ok) tmp_points[tmp_len++] = points[i].deepCopy(); 266 } 267 return Arrays.copyOf(tmp_points,tmp_len); 268 } 269 //判断不相邻边是否有交点 270 private void checkEdge(){ 271 for(int i=0;i<this.len;i++){ 272 for(int j=i+2;j<this.len;j++){ 273 if(i==0&&j==this.len-1) continue; 274 Point p = this.lines[i].getIntersection(this.lines[j]); 275 if(p==null) continue; 276 277 if(p.inXian1(this.lines[i]) && p.inXian1(this.lines[j])){ 278 this.status = -1; 279 this.message = "Non adjacent edges have intersections"; 280 return; 281 } 282 } 283 } 284 } 285 //多边形面积 286 private static void area(Graph e){ 287 double res = 0; 288 Point origin = new Point(0,0); 289 for(int i=0;i<e.len;i++){ 290 try{ 291 Line l1 = new Line(origin,e.points[i]); 292 Line l2 = new Line(origin,e.points[(i+1)%e.len]); 293 res += 0.5 * l1.vectorCrossMul(l2); 294 }catch (Exception reason){} 295 296 } 297 e.area = Math.abs(res); 298 } 299 //多边形周长 300 private static void sideLength(Graph e){ 301 double res = 0; 302 for(int i=0;i<e.len;i++){ 303 res += e.points[i].disToPoint(e.points[(i+1)%e.len]); 304 } 305 e.sideLength = res; 306 } 307 //多边形凹凸性 308 private static void checkConvex(Graph e){ 309 if(e.len == 3) return; 310 int v = 0; 311 for(int i=0;i<e.len;i++){ 312 int first = i, second = (i+1)%e.len, thrid = (i+2)%e.len; 313 try{ 314 Line l1 = new Line(e.points[first], e.points[second]); 315 Line l2 = new Line(e.points[first], e.points[thrid]); 316 if(v==0){ 317 if(l1.vectorCrossMul(l2) > 0) v = 1; 318 else v = -1; 319 } 320 if(v == 1 && l1.vectorCrossMul(l2) < 0) e.isConvexGraphical = false; 321 if(v == -1 && l1.vectorCrossMul(l2) > 0) e.isConvexGraphical = false; 322 }catch (Exception reason){} 323 } 324 } 325 //是否一样 326 } 327 class Triangle extends Graph{ 328 public Triangle(Point[] points)throws Exception{ 329 super(points); 330 if(this.status == -1 || this.len != 3){ 331 throw new Exception("not a triangle"); 332 } 333 } 334 335 //判断是否为等腰三角形 336 public boolean isIsoscelesTriangle(){ 337 return this.lines[0].getXianLength() == this.lines[1].getXianLength() || 338 this.lines[1].getXianLength() == this.lines[2].getXianLength() || 339 this.lines[2].getXianLength() == this.lines[0].getXianLength(); 340 } 341 //求三个点围成的图形面积 342 public static double area(Point a,Point b,Point c){ 343 double len1 = a.disToPoint(b); 344 double len2 = b.disToPoint(c); 345 double len3 = c.disToPoint(a); 346 double p = (len1+len2+len3) / 2; 347 return Math.sqrt(p*(p-len1)*(p-len2)*(p-len3)); 348 } 349 350 351 //求三角形类型,(锐角0,直角1,钝角2) 352 public int type(){ 353 double[] num = new double[3]; 354 num[0] = this.lines[0].getXianLength();num[1] = this.lines[1].getXianLength();num[2] = this.lines[2].getXianLength(); 355 Arrays.sort(num); 356 double tmp = Math.pow(num[0],2) + Math.pow(num[1],2) - Math.pow(num[2],2); 357 if(Math.abs(tmp) < 0.0000001) return 1; 358 if(tmp < 0) return 2; 359 return 0; 360 } 361 362 } 363 class Quadrilateral extends Graph{ 364 365 public Quadrilateral(Point[] points)throws Exception{ 366 super(points); 367 if(this.status == -1 || this.len != 4){ 368 throw new Exception("not a quadrilateral"); 369 } 370 } 371 372 //判断是否为平行四边形(对边分别平行) 373 public boolean isParallelQuadrilateral(){ 374 return this.lines[0].isParallelOrNot(this.lines[2]) && this.lines[1].isParallelOrNot(this.lines[3]); 375 } 376 377 //判断是否为菱形(平行四边形 + 四边长度相等) 378 public boolean isDiamond(){ 379 boolean v = this.lines[0].getXianLength() == this.lines[1].getXianLength() && this.lines[1].getXianLength() == this.lines[2].getXianLength() && 380 this.lines[2].getXianLength() == this.lines[3].getXianLength(); 381 return this.isParallelQuadrilateral() && v; 382 } 383 384 //判断是否为矩形(对角线相等) 385 public boolean isRectangle(){ 386 return this.points[0].disToPoint(this.points[2]) == this.points[1].disToPoint(this.points[3]); 387 } 388 389 //判断是否为正方形(菱形 + 矩形) 390 public boolean isSquare(){ 391 return this.isDiamond() && this.isRectangle(); 392 } 393 394 } 395 class Pentagon extends Graph { 396 397 public Pentagon(Point[] points)throws Exception{ 398 super(points); 399 if(this.status == -1 || this.len != 5){ 400 throw new Exception("not a pentagon"); 401 } 402 } 403 404 } 405 public class Main { 406 public static void main(String[] args) { 407 Scanner input = new Scanner(System.in); 408 String s = input.nextLine(); 409 //判断输入格式是否正确 410 if(!s.matches("^[1-5][:](([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))[,]([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))\\s?)+$")){ 411 System.out.println("Wrong Format"); 412 return; 413 } 414 //取出cmd,将串转化为浮点型 415 int cmd = s.charAt(0)-'0'; 416 s = s.substring(2).trim(); 417 String[] tmstr = s.split(" |,"); 418 double[] number = new double[30]; 419 int count = 0; 420 for(String s1:tmstr){ 421 if(!check(s1)){ 422 System.out.println("wrong number of points"); 423 } 424 number[count++] = Double.parseDouble(s1); 425 } 426 //将浮点型转化为坐标点型 427 Point[] p = new Point[10]; 428 for(int i=0;i<count;i+=2){ 429 p[i/2] = new Point(number[i],number[i+1]); 430 } 431 pointsCheck(cmd,count); 432 if(cmd == 1){ 433 try{ 434 Pentagon pentagon = new Pentagon(new Point[]{p[0],p[1],p[2],p[3],p[4]}); 435 System.out.println("true"); 436 }catch (Exception reason){ 437 System.out.println("false"); 438 } 439 } 440 else if(cmd == 2){ 441 try{ 442 Pentagon pentagon = new Pentagon(new Point[]{p[0],p[1],p[2],p[3],p[4]}); 443 if(pentagon.isConvexGraphical){ 444 System.out.printf("%s %s %s\n",pentagon.isConvexGraphical,changeFormat(pentagon.sideLength),changeFormat(pentagon.area)); 445 } 446 else System.out.println("false"); 447 }catch (Exception reason){ 448 System.out.println(reason.getMessage()); 449 } 450 } 451 else if(cmd == 3){ 452 Line line = null; 453 try{ 454 line = new Line(p[0],p[1]); 455 } 456 catch (Exception reason){ 457 System.out.println(reason.getMessage()); 458 } 459 Graph graphical = new Graph(new Point[]{p[2],p[3],p[4],p[5],p[6]}); 460 if(graphical.status == -1){ 461 System.out.println("not a polygon"); 462 System.exit(0); 463 } 464 if(graphical.len == 3){ 465 try{ 466 Triangle triangle = new Triangle(graphical.points); 467 solve(line,triangle); 468 }catch (Exception reason){} 469 } 470 if(graphical.len == 4){ 471 try{ 472 Quadrilateral quadrilateral = new Quadrilateral(graphical.points); 473 solve(line,quadrilateral); 474 }catch (Exception reason){} 475 } 476 if(graphical.len == 5){ 477 try{ 478 Pentagon pentagon = new Pentagon(graphical.points); 479 solve(line,pentagon); 480 }catch (Exception reason){} 481 } 482 } 483 } 484 //判断点数是否正确 485 public static void pointsCheck(int cmd,int count){ 486 if(cmd == 1 || cmd == 2){ 487 if(count != 10){ 488 System.out.println("wrong number of points"); 489 System.exit(0); 490 } 491 } 492 if(cmd == 3){ 493 if(count != 14){ 494 System.out.println("wrong number of points"); 495 System.exit(0); 496 } 497 } 498 } 499 500 public static boolean check(String str){ 501 return str.matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$"); 502 } 503 //五边形直线的交点 504 public static void solve(Line line,Pentagon pentagon){ 505 for(Line item:pentagon.lines){ 506 if(line.isSameTo(item)){ 507 System.out.println("The line is coincide with one of the lines"); 508 return; 509 } 510 } 511 Point[] intersections = new Point[5]; 512 for(int i=0;i<5;i++){ 513 intersections[i] = line.getIntersection(pentagon.lines[i]); 514 } 515 boolean[] check = new boolean[]{false,false,false,false,false}; 516 for(int i=0;i<5;i++){ 517 if(intersections[i] != null){ 518 check[i] = intersections[i].inXian(pentagon.lines[i]); 519 } 520 } 521 /*特判交点在角上面的情况*/ 522 for(int i=0;i<5;i++){ 523 if(pentagon.points[i].inLine(line)){ 524 //两个不相邻角在line之上 525 if(pentagon.points[(i+2)%pentagon.len].inLine(line)){ 526 pr_area(pentagon,pentagon.points[i], pentagon.points[(i+1)%pentagon.len], pentagon.points[(i+2)%pentagon.len]); 527 } 528 else if(pentagon.points[(i+3)%pentagon.len].inLine(line)){ 529 pr_area(pentagon,pentagon.points[i], pentagon.points[(i+3)%pentagon.len], pentagon.points[(i+4)%pentagon.len]); 530 } 531 //对边和line有交点(分割为两个四边形) 532 else if(check[(i+2)%pentagon.len]){ 533 Graph tmp = new Graph(new Point[]{pentagon.points[i], pentagon.points[(i+1)%pentagon.len], pentagon.points[(i+2)%pentagon.len], intersections[(i+2)%pentagon.len]}); 534 double[] ans = new double[]{tmp.area, pentagon.area - tmp.area}; 535 Arrays.sort(ans); 536 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 537 } 538 //剩余两个不相邻边和line有交点 539 else if(check[(i+1)%pentagon.len]){ 540 pr_area(pentagon,pentagon.points[i], pentagon.points[(i+1)%pentagon.len], intersections[(i+1)%pentagon.len]); 541 } 542 else if(check[(i+3)%pentagon.len]){ 543 pr_area(pentagon,pentagon.points[i], pentagon.points[(i+4)%pentagon.len], intersections[(i+3)%pentagon.len]); 544 } 545 //就一个交点 546 else{ 547 System.out.println("1"); 548 } 549 return; 550 } 551 } 552 /*交点分别在边上面的情况*/ 553 for(int i=0;i<5;i++){ 554 if(check[i] && check[(i+2)%pentagon.len]){ 555 Graph tmp = new Graph(new Point[]{intersections[i], pentagon.points[(i+1)%pentagon.len], pentagon.points[(i+2)%pentagon.len], intersections[(i+2)%pentagon.len]}); 556 double[] ans = new double[]{tmp.area, pentagon.area - tmp.area}; 557 Arrays.sort(ans); 558 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 559 return; 560 } 561 if(check[i] && check[(i+3)%pentagon.len]){ 562 Graph tmp = new Graph(new Point[]{intersections[i], pentagon.points[i], pentagon.points[(i+4)%pentagon.len], intersections[(i+3)%pentagon.len]}); 563 double[] ans = new double[]{tmp.area, pentagon.area - tmp.area}; 564 Arrays.sort(ans); 565 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 566 return; 567 } 568 } 569 //无交点 570 System.out.println("0"); 571 } 572 public static void solve(Line line,Quadrilateral q){ 573 //与任意一条边重合 574 for(Line item: q.lines){ 575 if(line.isSameTo(item)){ 576 System.out.println("The line is coincide with one of the lines"); 577 return; 578 } 579 } 580 Point[] intersections = new Point[4]; 581 for(int i=0;i<4;i++){ 582 intersections[i] = line.getIntersection(q.lines[i]); 583 } 584 boolean[] check = new boolean[]{false,false,false,false}; 585 for(int i=0;i<4;i++){ 586 if(intersections[i] != null){ 587 check[i] = intersections[i].inXian(q.lines[i]); 588 } 589 } 590 591 /*特判交点在角上面的情况*/ 592 for(int i=0;i<4;i++){ 593 if(q.points[i].inLine(line)){ 594 //对角在line之上 595 if(q.points[(i+2)%q.len].inLine(line)){ 596 pr_area(q,q.points[i], q.points[(i+1)%q.len], q.points[(i+2)%q.len]); 597 } 598 //两个对边和line有交点 599 else if(check[(i+1)%q.len]){ 600 pr_area(q, q.points[i], q.points[(i+1)%q.len], intersections[(i+1)%q.len]); 601 } 602 else if(check[(i+2)%q.len]){ 603 pr_area(q, q.points[i], q.points[(i+3)%q.len], intersections[(i+2)%q.len]); 604 } 605 //就一个交点 606 else{ 607 System.out.println("1"); 608 } 609 return; 610 } 611 } 612 613 /*两组对边和line有交点的情况*/ 614 for(int i=0;i<2;i++){ 615 if(check[i] && check[(i+2)%q.len]){ 616 Graph tmp = new Graph(new Point[]{intersections[i], q.points[(i+1)%q.len], q.points[(i+2)%q.len], intersections[(i+2)%q.len]}); 617 double[] ans = new double[]{tmp.area, q.area - tmp.area}; 618 Arrays.sort(ans); 619 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 620 return; 621 } 622 } 623 624 /*无交点*/ 625 System.out.println("0"); 626 } 627 public static void solve(Line line,Triangle triangle){ 628 //与任意一条边重合 629 if(line.isSameTo(triangle.lines[0]) || line.isSameTo(triangle.lines[1]) || line.isSameTo(triangle.lines[2])){ 630 System.out.println("The line is coincide with one of the lines"); 631 return; 632 } 633 //与三条边的交点(值可能为null,即平行) 634 Point p_ab = line.getIntersection(triangle.lines[0]); 635 Point p_bc = line.getIntersection(triangle.lines[1]); 636 Point p_ca = line.getIntersection(triangle.lines[2]); 637 638 639 //三交点是否位于边之内 640 boolean p_ab_in=false, p_bc_in =false, p_ca_in=false; 641 if(p_ab != null) p_ab_in = p_ab.inXian(triangle.lines[0]); 642 if(p_bc != null) p_bc_in = p_bc.inXian(triangle.lines[1]); 643 if(p_ca != null) p_ca_in = p_ca.inXian(triangle.lines[2]); 644 645 646 //任一角在直线之上(特判三角形的角) 647 if(triangle.points[0].inLine(line)){ 648 //与另一条边无交点或者交点在边之外 649 if(p_ca == null || !p_ca.inXian1(triangle.lines[2])){ 650 System.out.println("1"); 651 } 652 else pr_area(triangle,triangle.points[0],triangle.points[1],p_ca); 653 return; 654 } 655 if(triangle.points[1].inLine(line)){ 656 if(p_ca == null || !p_ca.inXian1(triangle.lines[1])){ 657 System.out.println("1"); 658 } 659 else pr_area(triangle,triangle.points[0],triangle.points[1],p_ca); 660 return; 661 } 662 if(triangle.points[2].inLine(line)){ 663 if(p_ab == null || !p_ab.inXian1(triangle.lines[0])){ 664 System.out.println("1"); 665 } 666 else pr_area(triangle,triangle.points[0],triangle.points[2],p_ab); 667 return; 668 } 669 670 //两个交点 671 if(p_ab_in && p_bc_in){ pr_area(triangle,triangle.points[1],p_ab,p_bc);return;} 672 if(p_bc_in && p_ca_in){ pr_area(triangle,triangle.points[2],p_bc,p_ca);return;} 673 if(p_ca_in && p_ab_in){ pr_area(triangle,triangle.points[0],p_ca,p_ab);return;} 674 //无交点 675 System.out.println("0"); 676 } 677 public static void pr_area(Triangle t, Point a,Point b,Point c){ 678 double[] ans = new double[2]; 679 ans[0] = Triangle.area(a,b,c); 680 ans[1] = t.area - ans[0]; 681 Arrays.sort(ans); 682 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 683 } 684 public static void pr_area(Quadrilateral q,Point a,Point b,Point c){ 685 double[] ans = new double[2]; 686 ans[0] = Triangle.area(a,b,c); 687 ans[1] = q.area - ans[0]; 688 Arrays.sort(ans); 689 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 690 } 691 public static void pr_area(Pentagon pentagon,Point a,Point b,Point c){ 692 double[] ans = new double[2]; 693 ans[0] = Triangle.area(a,b,c); 694 ans[1] = pentagon.area - ans[0]; 695 Arrays.sort(ans); 696 System.out.printf("2 %s %s\n",changeFormat(ans[0]),changeFormat(ans[1])); 697 } 698 699 public static String changeFormat(double a){ 700 String res = String.format("%.3f",a); 701 res = res.replaceAll("0+?$", ""); 702 if(res.charAt(res.length()-1) == '.') res+='0'; 703 return res; 704 } 705 706 }View Code
运行结果:
分析:由上图可看出,注释深度比较大,其他的都比较小,圈复杂度比较低。
7-2 点线形系列5-凸五边形的计算-2
题目:
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
4:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),判断它们两个之间是否存在包含关系(一个多边形有一条或多条边与另一个多边形重合,其他部分都包含在另一个多边形内部,也算包含)。
两者存在六种关系:1、分离(完全无重合点) 2、连接(只有一个点或一条边重合) 3、完全重合 4、被包含(前一个多边形在后一个多边形的内部)5、交错 6、包含(后一个多边形在前一个多边形的内部)。
各种关系的输出格式如下:
1、no overlapping area between the previous triangle/quadrilateral/
pentagon and the following triangle/quadrilateral/ pentagon
2、the previous triangle/quadrilateral/ pentagon is connected to the following triangle/quadrilateral/ pentagon
3、the previous triangle/quadrilateral/ pentagon coincides with the following triangle/quadrilateral/ pentagon
4、the previous triangle/quadrilateral/ pentagon is inside the following triangle/quadrilateral/ pentagon
5、the previous triangle/quadrilateral/ pentagon is interlaced with the following triangle/quadrilateral/ pentagon
6、the previous triangle/quadrilateral/ pentagon contains the following triangle/quadrilateral/ pentagon
5:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出两个多边形公共区域的面积。注:只考虑每个多边形被另一个多边形分割成最多两个部分的情况,不考虑一个多边形将另一个分割成超过两个区域的情况。
6:输入六个点坐标,输出第一个是否在后五个点所构成的多边形(限定为凸多边形,不考虑凹多边形),的内部(若是五边形输出in
the pentagon/outof the pentagon,若是四边形输出in the quadrilateral/outof the
quadrilateral,若是三角形输出in the triangle/outof the
triangle)。输入入错存在冗余点要排除,冗余点的判定方法见选项5。如果点在多边形的某条边上,输出"on the triangle/on
the quadrilateral/on the pentagon"。
以上4、5、6选项输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
代码如下:
1 import java.util.*; 2 import java.util.Arrays; 3 import java.util.Comparator; 4 /**/ 5 public class Main { 6 public static void main(String[] args) { 7 Scanner scanner = new Scanner(System.in); 8 String str = scanner.nextLine(); 9 //判断输入格式是否正确 10 if(!str.matches("^[1-9][:](([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))[,]([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))\\s?)+$")){ 11 System.out.println("Wrong Format"); 12 System.exit(0); 13 } 14 //取出cmd,将串转化为浮点型 15 int cmd = str.charAt(0)-'0'; 16 str = str.substring(2).trim(); 17 String[] tmpstr = str.split(" |,"); 18 double[] num = new double[30]; 19 int cnt = 0; 20 for(String s:tmpstr){ 21 num[cnt++] = Double.parseDouble(s); 22 } 23 //将浮点型转化为坐标点型 24 Point[] p = new Point[10]; 25 for(int i=0;i<cnt;i+=2){ 26 p[i/2] = new Point(num[i],num[i+1]); 27 } 28 pointsCntCheck(cmd,cnt); 29 if(cmd == 4){ 30 Graphical graphical1 = new Graphical(new Point[]{p[0], p[1], p[2], p[3], p[4]}); 31 Graphical graphical2 = new Graphical(new Point[]{p[5], p[6], p[7], p[8], p[9]}); 32 System.out.print(graphical1.relationshipWith(graphical2)); 33 } 34 if(cmd == 5){ 35 Graphical graphical1 = new Graphical(new Point[]{p[0], p[1], p[2], p[3], p[4]}); 36 Graphical graphical2 = new Graphical(new Point[]{p[5], p[6], p[7], p[8], p[9]}); 37 System.out.println(changeFormat(graphical1.area1(graphical2))); 38 } 39 if(cmd == 6){ 40 Graphical graphical1 = new Graphical(new Point[]{p[1], p[2], p[3], p[4], p[5]}); 41 int res = graphical1.isContainPoint(p[0]); 42 String[] name = new String[]{"triangle", "quadrilateral", "pentagon"}; 43 if(res == -1){ 44 System.out.print("in the "+name[graphical1.len-3]); 45 } 46 if(res == 0){ 47 System.out.print("on the "+name[graphical1.len-3]); 48 } 49 if(res == 1){ 50 System.out.print("outof the "+name[graphical1.len-3]); 51 } 52 } 53 54 } 55 public static void pointsCntCheck(int cmd,int cnt){ 56 if((cmd == 4 || cmd == 5) && cnt != 20){ 57 System.out.println("wrong number of points"); 58 System.exit(0); 59 } 60 if(cmd == 6 && cnt != 12){ 61 System.out.println("wrong number of points"); 62 System.exit(0); 63 } 64 } 65 66 public static String changeFormat(double a){ 67 String res = String.format("%.3f",a); 68 res = res.replaceAll("0+?$", ""); 69 if(res.charAt(res.length()-1) == '.') res+='0'; 70 return res; 71 } 72 public static boolean check(String str){ 73 return str.matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$"); 74 } 75 } 76 class Graphical { 77 public int len=0,status=1; //多边形边数,状态 78 public Point[] points; 79 public Line[] lines; 80 public double sideLength = 0,area = 0; //边长,面积 81 public boolean isConvexGraphical = true; 82 public Graphical(Point[] points){ 83 this.points = new Point[points.length]; 84 points = this.pointNum(points); //去除重复点 85 if(points.length <=2 ){ 86 this.status = -1; 87 88 return; 89 } 90 //相邻边夹角0则去除中间点,夹角180则status:-1 91 for(int i=0;i<points.length;i++){ 92 int first = i , second = (i+1)%points.length, third = (i+2)%points.length; 93 try{ 94 Line l1 = new Line(points[first],points[second]); 95 Line l2 = new Line(points[second],points[third]); 96 if( Math.abs(l1.vectorAngle(l2) - Math.PI) < 0.000001 ){ //夹角180 97 this.status = -1; 98 return; 99 } 100 else if(Math.abs(l1.vectorAngle(l2)) > 0.000001){ //夹角不为0 101 this.points[this.len++] = points[second].deepCopy(); 102 } 103 }catch (Exception e){} 104 } 105 106 this.points = Arrays.copyOf(this.points,this.len); 107 this.lines = new Line[this.len]; 108 //初始化边 109 for(int i=0;i<this.len;i++){ 110 try { 111 int first = i, second = (i+1)%this.len; 112 this.lines[i] = new Line(this.points[first], this.points[second]); 113 }catch (Exception e){} 114 } 115 //判断任意不相邻边(线段交点)是否有交点 116 checkEdge(); 117 Graphical.area(this); 118 Graphical.sideLength(this); 119 Graphical.checkConvex(this); 120 } 121 /*public void print(){ 122 if(this.status == -1){ 123 System.out.println("false"); 124 return; 125 } 126 System.out.println("点数为:"+this.len); 127 for(int i=0;i<this.len;i++){ 128 this.points[i].print(); 129 } 130 for(int i=0;i<this.len;i++){ 131 this.lines[i].print(); 132 } 133 System.out.println("周长为:"+this.sideLength); 134 System.out.println("面积为:"+this.area); 135 System.out.println("凹凸性:"+this.isConvexGraphical); 136 }*/ 137 //判断图形是否包含某个点返回值-1,0,1 (内部,边缘,外部) 138 public int isContainPoint(Point p){ 139 for(int i=0;i<this.len;i++){ //位于边之上 140 if(p.inXian1(this.lines[i])) return 0; 141 } 142 143 double s = 0; 144 for(int i=0;i<this.len;i++){ 145 s += Triangle.area(p,this.points[i], this.points[(i+1)%this.len]); 146 } 147 return Math.abs(s-this.area) < 0.000001 ? -1:1; 148 } 149 //判断两个图形类之间的关系() 150 public String relationshipWith(Graphical g){ 151 String[] name = new String[]{"triangle", "quadrilateral", "pentagon"}; 152 //分离 153 if(this.isSeparatedFrom(g)){ 154 return "no overlapping area between the previous "+name[this.len-3]+ " and the following "+name[g.len-3]; 155 } 156 //完全重合 157 if(this.isSameTo(g)) 158 return "the previous "+name[this.len-3]+ " coincides with the following "+name[g.len-3]; 159 //包含 160 if(this.isContainGra(g)){ 161 return "the previous "+name[this.len-3]+ " contains the following "+name[g.len-3]; 162 } 163 //被包含 164 if(g.isContainGra(this)){ 165 return "the previous "+name[this.len-3]+ " is inside the following "+name[g.len-3]; 166 } 167 //连接 168 if(!this.isContainGra(g) && !g.isContainGra(this) && this.isPointOn(g)){ 169 return "the previous "+name[this.len-3]+ " is connected to the following "+name[g.len-3]; 170 } 171 //交错 172 return "the previous "+name[this.len-3]+ " is interlaced with the following "+name[g.len-3]; 173 } 174 //完全分离 175 public boolean isSeparatedFrom(Graphical g){ 176 boolean ok = true; 177 int[] check2 = new int[g.len]; 178 for(int i=0;i<g.len;i++){ 179 check2[i] = this.isContainPoint(g.points[i]); 180 } 181 for(int item:check2){ 182 if(item != 1) ok = false; 183 } 184 185 return ok; 186 } 187 //完全包含(任意点都在this之内) 188 public boolean isContainGra(Graphical g){ 189 boolean ok = true; 190 int[] check2 = new int[g.len]; 191 for(int i=0;i<g.len;i++){ 192 check2[i] = this.isContainPoint(g.points[i]); 193 } 194 for(int item:check2){ 195 if(item == 1) ok = false; 196 } 197 return ok; 198 } 199 //判断两个图形是否一样(点完全重合) 200 public boolean isSameTo(Graphical g){ 201 if(this.len != g.len) return false; 202 for(int i=0;i<this.len;i++){ 203 boolean ok = false; 204 for(int j=0;j<g.len;j++){ 205 if(this.points[i].pointsCoincide(g.points[j])) ok = true; 206 } 207 if(!ok) return false; 208 } 209 return true; 210 } 211 //连接 212 public boolean isPointOn(Graphical g){ 213 int flag = 0,flag1 = 0; 214 for(int i = 0;i<this.len;i++){ 215 for(int j = 0;j<g.len;j++){ 216 if(this.points[i].pointsCoincide(g.points[j])){ 217 flag++; 218 } 219 } 220 } 221 for(int i = 0;i<this.len;i++){ 222 for(int j = 0;j<g.len;j++){ 223 if(this.lines[i].isSameTo(g.lines[j])){ 224 flag1++; 225 } 226 } 227 } 228 if(flag == 1 || flag1 == 1) 229 return true; 230 return false; 231 } 232 //去除所有重复点 233 private Point[] pointNum(Point[] p) { 234 int len = 0; 235 Point[] p1 = new Point[p.length]; 236 for(int i = 0;i < p.length;i++){ 237 boolean flag = true; 238 for(int j = 0;j < len;j++) { 239 if (p[i].pointsCoincide(p1[j])) { 240 flag = false; 241 break; 242 } 243 } 244 if(flag){ 245 p1[len++] = p[i].deepCopy(); 246 } 247 } 248 return Arrays.copyOf(p1,len); 249 } 250 //判断不相邻边是否有交点 251 private void checkEdge(){ 252 for(int i=0;i<this.len;i++){ 253 for(int j=i+2;j<this.len;j++){ 254 if(i == 0 && j == this.len-1) continue; 255 Point p = this.lines[i].getIntersection(this.lines[j]); 256 if(p==null) continue; 257 if(p.inXian1(this.lines[i]) && p.inXian1(this.lines[j])){ 258 this.status = -1; 259 return; 260 } 261 } 262 } 263 } 264 //计算两个图形的重叠面积(交点加内部顶点构成重叠多边形) 265 public double area1(Graphical g){ 266 Point[] intersection = new Point[100]; 267 int intersection_len = 0; 268 269 for(Line item1:this.lines){ //求出两多边形的交点 270 for(Line item2: g.lines){ 271 Point tmp = item1.lsi(item2); 272 if(tmp != null){ 273 intersection[intersection_len++] = tmp.deepCopy(); 274 } 275 } 276 } 277 278 for(Point item:g.points){ //顶点包含在内部 279 if(this.isContainPoint(item) == -1) intersection[intersection_len++] = item.deepCopy(); 280 } 281 for(Point item:this.points){ //顶点包含在内部 282 if(g.isContainPoint(item) == -1) intersection[intersection_len++] = item.deepCopy(); 283 } 284 285 if(intersection_len == 0) return 0; //交点为0,分离 286 287 //排序交点数组 288 intersection = Arrays.copyOf(intersection,intersection_len); 289 intersection = this.pointNum(intersection); 290 Point focus = Point.focusPoint(intersection); 291 Point sta = intersection[0].deepCopy(); 292 293 Arrays.sort(intersection,1,intersection.length, new Comparator<Point>() { 294 @Override 295 public int compare(Point o1, Point o2) { 296 try{ 297 Line origin =new Line(focus,sta); 298 Line l1 = new Line(focus,o1); 299 Line l2 = new Line(focus,o2); 300 double a1 = origin.vectorAngle(l1); 301 double a2 = origin.vectorAngle(l2); 302 if(origin.vectorCrossMul(l1) < 0) a1 = 2*Math.PI - a1; 303 if(origin.vectorCrossMul(l2) < 0) a2 = 2*Math.PI - a2; 304 if(a1-a2 > 0.000001) return 1; 305 if(Math.abs(a1-a2) < 0.000001) return 0; 306 return -1; 307 }catch (Exception reason){} 308 return 0; 309 } 310 }); 311 312 Graphical graphical = new Graphical(intersection); 313 return graphical.area; 314 315 } 316 //多边形面积 317 private static void area(Graphical e){ 318 double res = 0; 319 Point origin = new Point(0,0); 320 for(int i=0;i<e.len;i++){ 321 try{ 322 Line l1 = new Line(origin,e.points[i]); 323 Line l2 = new Line(origin,e.points[(i+1)%e.len]); 324 res += 0.5 * l1.vectorCrossMul(l2); 325 }catch (Exception reason){} 326 } 327 e.area = Math.abs(res); 328 } 329 //多边形周长 330 private static void sideLength(Graphical e){ 331 double res = 0; 332 for(int i=0;i<e.len;i++){ 333 res += e.points[i].disToPoint(e.points[(i+1)%e.len]); 334 } 335 e.sideLength = res; 336 } 337 //多边形凹凸性 338 private static void checkConvex(Graphical e){ 339 if(e.len == 3) return; 340 int v = 0; 341 for(int i=0;i<e.len;i++){ 342 int first = i, second = (i+1)%e.len, third = (i+2)%e.len; 343 try{ 344 Line l1 = new Line(e.points[first], e.points[second]); 345 Line l2 = new Line(e.points[first], e.points[third]); 346 if(v==0){ 347 if(l1.vectorCrossMul(l2) > 0) v = 1; 348 else v = -1; 349 } 350 if(v == 1 && l1.vectorCrossMul(l2) < 0) e.isConvexGraphical = false; 351 if(v == -1 && l1.vectorCrossMul(l2) > 0) e.isConvexGraphical = false; 352 }catch (Exception reason){} 353 } 354 } 355 //是否一样 356 } 357 358 //点类 359 class Point{ 360 double x, y; 361 362 public Point(){ 363 this.x = 0; 364 this.y = 0; 365 } 366 public Point(double a,double b){ 367 this.x = a; 368 this.y = b; 369 } 370 public void print(){ 371 String x = String.format("%.6f",this.x); 372 String y = String.format("%.6f",this.y); 373 x = x.replaceAll("0+?$", ""); 374 y = y.replaceAll("0+?$", ""); 375 System.out.printf("(%s , %s)\n",this.x,this.y); 376 } 377 //两点坐标相同 378 public boolean pointsCoincide(Point b){ 379 return (this.x==b.x)&&(this.y==b.y); 380 } 381 //两点距离 382 public double disToPoint(Point b){ 383 return Math.sqrt(Math.pow(this.x-b.x,2) + Math.pow(this.y-b.y,2)); 384 } 385 //点到直线的垂直距离 386 public double disToLine(Line l){ 387 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)); 388 } 389 //判断是否在直线之上 390 public boolean inLine(Line l){ 391 return Math.abs(l.a*this.x + l.b*this.y + l.c) < 0.000001; 392 } 393 //判断是否在线段之内(包括端点) 394 public boolean inXian1(Line l){ 395 if(!this.inLine(l)) return false; 396 double res = this.disToPoint(l.sta) + this.disToPoint(l.ed) - l.getXianLength(); 397 return Math.abs(res) < 0.000001; 398 } 399 //判断是否在线段之内(不包括端点) 400 public boolean inXian(Line l){ 401 return this.inXian1(l) && (!this.pointsCoincide(l.sta)) && (!this.pointsCoincide(l.ed)); 402 } 403 public Point deepCopy(){ 404 Point res = new Point(); 405 res.x = this.x; 406 res.y = this.y; 407 return res; 408 } 409 public Point add(Point another){ 410 Point res = this.deepCopy(); 411 res.x += another.x; 412 res.y += another.y; 413 return res; 414 } 415 public Point sub(Point another){ 416 Point res = this.deepCopy(); 417 res.x -= another.x; 418 res.y -= another.y; 419 return res; 420 } 421 //求点集重心 422 public static Point focusPoint(Point[] points ){ 423 Point res = new Point(0,0); 424 for(Point item:points){ 425 res = res.add(item); 426 } 427 res.x /= points.length; 428 res.y /= points.length; 429 return res; 430 } 431 432 } 433 class Line{ 434 Point sta, ed; 435 double a,b,c; 436 private final Point vector; 437 438 public Line(Point a,Point b)throws Exception{ 439 if(a.pointsCoincide(b)){ 440 throw new Exception("points coincide"); 441 } 442 this.sta = a; 443 this.ed = b; 444 this.a = (-(a.y-b.y)); 445 this.b = (a.x-b.x); 446 this.c = (-this.a*this.sta.x-this.b*this.sta.y); 447 this.vector = ed.sub(sta); 448 } 449 450 public void print(){ 451 System.out.printf("%fX + %fY + %f = 0\n",this.a,this.b,this.c); 452 } 453 454 //求线段长度 455 public double getXianLength(){ 456 return this.sta.disToPoint(this.ed); 457 } 458 //点到直线的距离 459 public double distanceToLine(Point x0) { 460 return Math.abs((this.ed.y-this.sta.y)*x0.x+(this.sta.x-this.ed.x)*x0.y+this.ed.x*this.sta.y-this.ed.y*this.sta.x)/Math.sqrt((this.ed.y-this.sta.y)*(this.ed.y-this.sta.y)+(this.ed.x-this.sta.x)*(this.ed.x-this.sta.x)); 461 462 } 463 //求线段斜率 464 public double Slope(){ 465 if(this.b == 0){ 466 return 2^48; 467 } 468 return -this.a / this.b; 469 } 470 471 //判断是否平行 472 public boolean isParallelOrNot(Line l0){ 473 if(this.b==0 || l0.b==0){ 474 return (this.b == 0 && l0.b == 0); 475 } 476 return ((this.a / this.b) == (l0.a / l0.b)); 477 } 478 479 //判断是否重合 480 public boolean isSameTo(Line l0){ 481 return this.isParallelOrNot(l0) && (this.sta.inLine(l0)); 482 } 483 484 //判断是否垂直 485 public boolean isVerticalOrNot(Line l0){ 486 return this.a * l0.a + this.b * l0.b == 0; 487 } 488 //求两条直线交点 489 public Point getIntersection(Line l0){ 490 if(this.isParallelOrNot(l0)) return null; 491 Point res = new Point(); 492 res.y = (l0.a*this.c-this.a*l0.c) / (this.a*l0.b-l0.a*this.b); 493 res.x = (this.b*l0.c-l0.b*this.c) / (this.a*l0.b-l0.a*this.b); 494 return res; 495 } 496 497 //LineSegmentIntersection 获取线段交点,返回值可能为null 498 public Point lsi(Line l0){ 499 Point res = this.getIntersection(l0); 500 if(res == null) return res; 501 boolean ok = (res.inXian1(this) && res.inXian1(l0)); 502 return ok ? res:null; 503 } 504 505 //求向量模 506 public double vectorLength(){ 507 return Math.sqrt( Math.pow(this.vector.x,2) + Math.pow(this.vector.y,2) ); 508 } 509 //求向量点积 510 public double vectorMul(Line another){ 511 return (this.vector.x * another.vector.x) + (this.vector.y * another.vector.y); 512 } 513 514 //求向量叉积 515 public double vectorCrossMul(Line another){ 516 return (this.vector.x * another.vector.y) - (another.vector.x * this.vector.y); 517 } 518 //求两向量夹角(非0向量) 519 public double vectorAngle(Line another){ 520 double cos_angle = this.vectorMul(another) / (this.vectorLength() * another.vectorLength()); 521 return Math.acos(cos_angle); 522 } 523 524 } 525 526 class Triangle extends Graphical{ 527 public Triangle(Point[] points)throws Exception{ 528 super(points); 529 if(this.status == -1 || this.len != 3){ 530 throw new Exception("not a triangle"); 531 } 532 } 533 //求三个点围成的图形面积 534 public static double area(Point a,Point b,Point c){ 535 double len1 = a.disToPoint(b); 536 double len2 = b.disToPoint(c); 537 double len3 = c.disToPoint(a); 538 double p = (len1+len2+len3) / 2; 539 return Math.sqrt(p*(p-len1)*(p-len2)*(p-len3)); 540 } 541 } 542 class Quadrilateral extends Graphical{ 543 public Quadrilateral(Point[] points)throws Exception{ 544 super(points); 545 if(this.status == -1 || this.len != 4){ 546 throw new Exception("not a quadrilateral"); 547 } 548 } 549 //判断是否为平行四边形(对边分别平行) 550 public boolean isParallelQuadrilateral(){ 551 return this.lines[0].isParallelOrNot(this.lines[2]) && this.lines[1].isParallelOrNot(this.lines[3]); 552 } 553 } 554 class Pentagon extends Graphical { 555 public Pentagon(Point[] points)throws Exception{ 556 super(points); 557 if(this.status == -1 || this.len != 5){ 558 throw new Exception("not a pentagon"); 559 } 560 } 561 }View Code
运行结果如下:还有一些点没有完成。
分析:本次作业中运用了抽象类,且在主函数中我提炼出了很多方法,由上图可看出圈复杂比较低,成本比较低,注释相对较多,代码整体来说可以,只是需要完善功能,因为还有些测试点未过。
(3)期中测试7-1点与线(类设计)
题目略。
本题题目要求比较简单,基本上就是根据类图设计好相应的类,再到主类中写出测试代码,没有什么复杂的算法。下面只给出点、线子类的代码。
点、线类代码如下:
class Point{ 2 double x,y; 3 public Point(){ 4 this.x=0; 5 this.y=0; 6 } 7 public Point(double x,double y){ 8 this.x=x; 9 this.y=y; 10 } 11 public double getX(){ 12 return this.x; 13 } 14 public double getY(){ 15 return this.y; 16 } 17 public void setX(double x){ 18 this.x = x; 19 } 20 public void setY(double y){ 21 this.y =y; 22 } 23 public void display(){ 24 System.out.println("("+this.x+","+this.y+")"); 25 } 26 } 27 // 28 class Line{ 29 Point point1,point2; 30 String color; 31 /*public Line(){ 32 33 }*/ 34 public Line(Point p1,Point p2,String color){ 35 this.point1 = p1; 36 this.point2 = p2; 37 this.color = color; 38 } 39 public Point getPoint1(){ 40 return this.point1; 41 } 42 public Point getYPoint1(){ 43 return this.point2; 44 } 45 public void setPoint1(Point point1){ 46 this.point1 = point1; 47 } 48 public void setPoint2(Point point2){ 49 this.point2 = point2; 50 } 51 public String getColor(){ 52 return this.color; 53 } 54 public void setColor(String color){ 55 this.color = color; 56 } 57 public double getDistance(){ 58 return Math.sqrt((this.point1.x-this.point2.x)*(this.point1.x-this.point2.x)+(this.point1.y-this.point2.y)*(this.point1.y-this.point2.y)); 59 } 60 public void display(){ 61 System.out.println("The line's color is:"+this.color); 62 System.out.println("The line's begin point's Coordinate is:"); 63 System.out.printf("(%.2f,%.2f)\n",this.point1.x,this.point1.y); 64 System.out.println("The line's end point's Coordinate is:"); 65 System.out.printf("(%.2f,%.2f)\n",this.point2.x,this.point2.y); 66 67 System.out.printf("The line's length is:%.2f\n",this.getDistance()); 68 } 69 }
7-2 点线面问题重构(继承与多态)
题目略。
本题题目要求与第一题的难度差不多,只是相比之下多了Plane类,加上了父类Element。同样地根据类图设计好相应的类,且点和线类的内容不变,只需要再加上抽象类,Plane类,写上extend Element。再到主类中写出测试代码,没有什么复杂的算法。
新增父类Element,和Plane类的设计代码如下:
1 /* 2 * 抽象类:Element(接口) 3 * 方法:显示信息 4 */ 5 abstract class Element{ 6 abstract public void display(); 7 }
1 /* 2 * 类:Plane 3 * 方法:显示颜色信息 4 */ 5 class Plane extends Element{ 6 String color; 7 public Plane(){ 8 9 } 10 public Plane(String color){ 11 this.color = color; 12 } 13 public String getColor(){ 14 return this.color; 15 } 16 public void setColor(String color){ 17 this.color = color; 18 } 19 public void display(){ 20 System.out.println("The Plane's color is:"+this.color); 21 } 22 }
7-3 点线面问题再重构(容器类)
题目略。
这题稍微要复杂一些,还加上了一个子类GeometryObject,需要掌握ArrayList类的使用方法,本题Main类还需要用到switch类,
代码如下:(已全部折叠)
1 package 点线类重构; 2 3 import java.util.*; 4 public class Main1{ 5 static Scanner in=new Scanner(System.in); 6 public static void main(String[] args) { 7 GeometryObject a=new GeometryObject(); 8 double x1,x2,y1,y2; 9 String color; 10 int choice; 11 Point point1; 12 Point point2; 13 Line line; 14 Plane plane; 15 Element element; 16 choice = in.nextInt(); 17 while(choice!= 0) { 18 switch(choice) { 19 case 1: 20 point1=new Point(in.nextDouble(),in.nextDouble()); 21 element=point1; 22 a.add(element); 23 break; 24 case 2: 25 x1=in.nextDouble(); 26 y1=in.nextDouble(); 27 x2=in.nextDouble(); 28 y2=in.nextDouble(); 29 color=in.next(); 30 if(x1<=200&&x1>0&&x2<=200&&x2>0&&y1<=200&&y1>0&&y2<=200&&y2>0){ 31 point1=new Point(x1,y1); 32 point2=new Point(x2,y2); 33 line=new Line(point1,point2,color); 34 element=line; 35 a.add(element); 36 } 37 else 38 { 39 a.add(null); 40 } 41 break; 42 case 3: 43 color=in.next(); 44 plane=new Plane(color); 45 element=plane; 46 a.add(element); 47 break; 48 case 4: 49 int index = in.nextInt(); 50 a.remove(index); 51 } 52 choice = in.nextInt(); 53 } 54 a.getList(); 55 } 56 } 57 /* 58 * 类:容器GeometryObject 59 * 方法:显示信息 60 */ 61 class GeometryObject{ 62 ArrayList<Element> list = new ArrayList<>(); 63 public GeometryObject(){ 64 65 } 66 public void add(Element element){ 67 list.add(element); 68 } 69 public void remove(int index){ 70 if(list.size()>index-1) 71 list.remove(index-1); 72 } 73 public void getList() 74 { 75 for (Element temp:list) 76 { 77 if(temp==null) 78 { 79 System.out.println("Wrong Format"); 80 }else 81 { 82 temp.display(); 83 } 84 85 } 86 } 87 } 88 /* 89 * 抽象类:Element(接口) 90 * 方法:显示信息 91 */ 92 abstract class Element{ 93 abstract public void display(); 94 } 95 /* 96 * 类:Plane 97 * 方法:显示颜色信息 98 */ 99 class Plane extends Element{ 100 String color; 101 public Plane(){ 102 103 } 104 public Plane(String color){ 105 this.color = color; 106 } 107 public String getColor(){ 108 return this.color; 109 } 110 public void setColor(String color){ 111 this.color = color; 112 } 113 public void display(){ 114 System.out.println("The Plane's color is:"+this.color); 115 } 116 } 117 /* 118 * 类:Point 119 */ 120 class Point extends Element{ 121 double x,y; 122 public Point(){ 123 this.x=0; 124 this.y=0; 125 } 126 public Point(double x,double y){ 127 this.x=x; 128 this.y=y; 129 } 130 public double getX(){ 131 return this.x; 132 } 133 public double getY(){ 134 return this.y; 135 } 136 public void setX(double x){ 137 this.x = x; 138 } 139 public void setY(double y){ 140 this.y =y; 141 } 142 public void display(){ 143 System.out.printf("(%.2f,%.2f)\n",this.x,this.y); 144 } 145 } 146 /* 147 * 类:Line 148 */ 149 class Line extends Element{ 150 Point point1,point2; 151 String color; 152 public Line(){ 153 154 } 155 public Line(Point p1,Point p2,String color){ 156 this.point1 = p1; 157 this.point2 = p2; 158 this.color = color; 159 } 160 public Point getPoint1(){ 161 return this.point1; 162 } 163 public Point getYPoint1(){ 164 return this.point2; 165 } 166 public void setPoint1(Point point1){ 167 this.point1 = point1; 168 } 169 public void setPoint2(Point point2){ 170 this.point2 = point2; 171 } 172 public String getColor(){ 173 return this.color; 174 } 175 public void setColor(String color){ 176 this.color = color; 177 } 178 public double getDistance(){ 179 return Math.sqrt((this.point1.x-this.point2.x)*(this.point1.x-this.point2.x)+(this.point1.y-this.point2.y)*(this.point1.y-this.point2.y)); 180 } 181 public void display(){ 182 System.out.println("The line's color is:"+this.color); 183 System.out.println("The line's begin point's Coordinate is:"); 184 System.out.printf("(%.2f,%.2f)\n",this.point1.x,this.point1.y); 185 System.out.println("The line's end point's Coordinate is:"); 186 System.out.printf("(%.2f,%.2f)\n",this.point2.x,this.point2.y); 187 188 System.out.printf("The line's length is:%.2f\n",this.getDistance()); 189 } 190 }View Code
在复杂度分析上,有三个题目的kiviat Graph图可知,第三个的平均深度和最大复杂度比较高,但是平均复杂度还是较低的,算法上还算可以。最后一题我并没有在规定时间内完成测试,是后面在ideal里面测试完成的。
三、踩坑心得
1.四边形
(1)判断是否在三角形内部的判断条件用面积法不是两个部分面积的和等于总的面积,而是相差0.00001左右。
(2)异常处理try-catch来处理各种异常,可以较少代码长度,一定程度较小复杂度。但不太会,处理了很久。
2.五边形
(1)输出面积的格式化输出出错了,用的是四边形里面的方法,之前没有出错,这次却出错,然后改用了一种方法,用字符串替换replaceAll方法替换程序要的结果。
(2)五边形的相关计算非常复杂,需要各种判断方法,且有些算法根本想不出,想得满分太难了!数学方面要求比较高。
(3)题目难度非常大!运用抽象类或接口,可以大大减少代码的长度,是java中非常方便使用的一类。
3.期中测试
(1)输出结果的格式转换,使用String.format("%.2f", data)
。题目比较简单除此外没有什么其他比较坑的地方了。
总之,这次的三类题目中的坑就是要灵活运用各种基础知识,包括java,数学。对于java封装,多态的思想还需多加学习,灵活应用才行。
四、改进建议
这些作业中相比PTA前三次作业代码的注释更详细了。但期中测试中的代码我几乎没有写注释,因为测试时间有限,而我的敲码速度比较慢,第三题都没有在规定时间内做完,根本没有时间写注释。以后还要多敲代码,练练打字速度。还有就是算法方面有待改进。前面这些题目对于我来说难度比较大,可以解决但算法常常不够好,从前面的分析可知有些算法的平均深度。平均成本、方法比较高,算法比较复杂繁琐,所以算法上还需要优化。后期还需要多去看视频教学,多看看书。
五、总结
通过前面这些作业,我更加理解了java中面向对象的思想,对封装的使用更加熟练了。且通过四边形,五边形等的作业,我更加熟悉了格式转换的方法,以及后面新学的异常处理,多态的使用。真真切切地感受到了java封装、继承、多态的带来的便利。利用java的面向对象编程的思想可以大大减少重复代码,缩短代码长度,加上注释,可以非常方便的留着重复使用。四边形,五边形系列的题目中就利用到了父类继承,抽象类,接口,不然代码将会非常的长!不过对于后面新学的异常处理和多态的知识,我还不是很掌握,还需要加强学习。
标签:return,Point,期中考试,double,五边形,res,四边形,Line,public From: https://www.cnblogs.com/java-036/p/16826058.html