前言:这几次题目集中,随着题目内容的不断改变,对于多边形的类设计变得更加复杂。虽然题目量不大,但是总体的难度有提升,四边形开始需要考虑凹凸多边形,对多边形的判断也逐渐复杂,需要考虑多种情况。在学习了继承、抽象类等后,可将多边形类进行改进,比如期中考试的题目集。使用改进后的类后,代码变得更加清晰明了。
设计与分析:
题目4.7-2:
用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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"。
本题属于多边形类中的四边形类,需要对四边形进行分析,并将四边形问题适时转化为对三角形、线、点的分析。
源代码:
点类:
class Dian{
double x,y;
public double juli(Dian a){
return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2));
}
}
线类:
class Xian{
Dian a = new Dian();
Dian b = new Dian();
double k;
public double xielv(){
this.k = (this.a.y-this.b.y)/(this.a.x-this.b.x);
return this.k;
}
public double chuizhijuli(Dian m){
double d;
if(this.a.x==this.b.x){
d=Math.abs(m.x-this.a.x);
}
else{
d=(Math.abs(m.y-this.k*m.x-(this.a.y-this.k*this.a.x))/(Math.sqrt(this.k*this.k+1)));
}
return d;
}
public boolean pingxing(Xian l){
if((l.a.y-l.b.y)*(this.a.x-this.b.x)==(l.a.x-l.b.x)*(this.a.y-this.b.y))
return true;
else
return false;
}
public Dian jiaodian(Xian l){
Dian n = new Dian();
double b1;
double b2;
if(this.a.x==this.b.x){
b2 = l.a.y - l.k * l.a.x;
n.x = this.a.x;
n.y = l.k * n.x + b2;
}
else if(l.a.x==l.b.x){
b1 = this.a.y - this.k * this.a.x;
n.x = l.a.x;
n.y = this.k * n.x + b1;
}
else{
b1 = this.a.y - this.k * this.a.x;
b2 = l.a.y - l.k * l.a.x;
n.x = (b2-b1)/(this.k-l.k);
n.y = l.k * n.x + b2;
}
return n;
}
public boolean xianshang(Dian x){
if((x.y-this.b.y)*(this.a.x-this.b.x)==(x.x-this.b.x)*(this.a.y-this.b.y))
return true;
else
return false;
}
public boolean xianduanshang(Dian x){
if((this.a.x==x.x&&this.a.y==x.y)||(this.b.x==x.x&&this.b.y==x.y))
return true;
else{
double ax = x.juli(this.a);
double bx = x.juli(this.b);
double ab = this.b.juli(this.a);
if(Math.abs(ax+bx-ab)<0.000001)
return true;
else
return false;
}
}
}
三角形类:
class Sanjiaoxing{
Dian A = new Dian();
Dian B = new Dian();
Dian C = new Dian();
public double mianji(Dian a,Dian b,Dian c){
double ab = a.juli(b);
double bc = c.juli(b);
double ca = a.juli(c);
double p = (ab+bc+ca)/2;
return Math.sqrt(p*(p-ab)*(p-bc)*(p-ca));
}
}
四边形类:
class Sibianxing{
Dian A = new Dian();
Dian B = new Dian();
Dian C = new Dian();
Dian D = new Dian();
public double mianji(Dian a,Dian b,Dian c,Dian d){
Xian ac = new Xian();
Xian bd = new Xian();
Dian n = new Dian();
n = ac.jiaodian(bd);
Sanjiaoxing T = new Sanjiaoxing();
if(ac.xianduanshang(n)&&bd.xianduanshang(n))
return T.mianji(a,c,d)+T.mianji(a,c,b);
else if(ac.xianduanshang(n)&&!bd.xianduanshang(n))
return T.mianji(a,b,d)+T.mianji(d,c,b);
else
return T.mianji(a,c,d)+T.mianji(a,c,b);
}
}
用正则表达式判断输入是否合法函数:
public static int hefa(String a){
String pattern = "^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?),[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(a);
if(m.matches()){
return 1;
}
else{
return 0;
}
}
第一问:
判断是否是四边形、平行四边形:将四个点按顺序存储后,由对角线交点个数来判断是否组成四边形;若对角线交点同时不存在于两条对角线上,则不构成四边形;若两条对边平行且相等则为平行四边形。(四个点不重复的前提下)
case "1":
if(point.length!=9){
System.out.print("wrong number of points");
return;
}
else{
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian N = new Dian();
if((A.x==B.x&&A.y==B.y)||(A.x==C.x&&A.y==C.y)||(A.x==D.x&&A.y==D.y)||(C.x==B.x&&C.y==B.y)||(D.x==B.x&&D.y==B.y)||(C.x==D.x&&C.y==D.y)){
System.out.print("points coincide");
return;
}
else{
Xian AB = new Xian();
AB.a = A;
AB.b = B;
if(AB.a.x!=AB.b.x)
AB.k = AB.xielv();
//System.out.println(AB.k);
Xian BC = new Xian();
BC.a = B;
BC.b = C;
if(BC.a.x!=BC.b.x)
BC.k = BC.xielv();
Xian CD = new Xian();
CD.a = C;
CD.b = D;
if(CD.a.x!=CD.b.x)
CD.k = CD.xielv();
Xian DA = new Xian();
DA.a = D;
DA.b = A;
if(DA.a.x!=DA.b.x)
DA.k = DA.xielv();
Xian AC = new Xian();
AC.a = A;
AC.b = C;
if(AC.a.x!=AC.b.x)
AC.k = AC.xielv();
Xian BD = new Xian();
BD.a = B;
BD.b = D;
if(BD.a.x!=BD.b.x)
BD.k = BD.xielv();
N = AC.jiaodian(BD);
if(AB.pingxing(CD)&&BC.pingxing(DA))
System.out.print("true true");
else if(AB.xianshang(C)||AB.xianshang(D)||CD.xianshang(A)||CD.xianshang(B))
System.out.print("false false");
else if(!AC.xianduanshang(N)&&!BD.xianduanshang(N))
System.out.print("false false");
else
System.out.print("true false");
}
}
break;
第二问:
判断菱形、矩形、正方形:在构成平行四边形的前提下,四边相等则为菱形;有一个角为直角则为矩形;当矩形的两条临边相等时为正方形。(正方形即是矩形也是菱形)
case "2":
if(point.length!=9){
System.out.print("wrong number of points");
return;
}
else{
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
//System.out.print(C.y);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian N = new Dian();
/*if((A.x==B.x&&A.y==B.y)||(A.x==C.x&&A.y==C.y)||(A.x==D.x&&A.y==D.y)||(C.x==B.x&&C.y==B.y)||(D.x==B.x&&D.y==B.y)||(C.x==D.x&&C.y==D.y)){
System.out.print("points coincide");
return;
}
else{*/
Xian AB = new Xian();
AB.a = A;
AB.b = B;
if(AB.a.x!=AB.b.x)
AB.k = AB.xielv();
double ab = A.juli(B);
Xian BC = new Xian();
BC.a = B;
BC.b = C;
if(BC.a.x!=BC.b.x)
BC.k = BC.xielv();
double bc = C.juli(B);
Xian CD = new Xian();
CD.a = C;
CD.b = D;
if(CD.a.x!=CD.b.x)
CD.k = CD.xielv();
double cd = C.juli(D);
Xian DA = new Xian();
DA.a = D;
DA.b = A;
if(DA.a.x!=DA.b.x)
DA.k = DA.xielv();
double da = A.juli(D);
Xian AC = new Xian();
AC.a = A;
AC.b = C;
if(AC.a.x!=AC.b.x)
AC.k = AC.xielv();
double ac = A.juli(C);
Xian BD = new Xian();
BD.a = B;
BD.b = D;
if(BD.a.x!=BD.b.x)
BD.k = BD.xielv();
N = AC.jiaodian(BD);
if(AB.xianshang(C)||AB.xianshang(D)||CD.xianshang(A)||CD.xianshang(B))
System.out.print("not a quadrilateral");
else if((!AC.xianduanshang(N)&&!BD.xianduanshang(N))||(AC.pingxing(BD)))
System.out.print("not a quadrilateral");
else if(AB.pingxing(CD)&&BC.pingxing(DA)){
if(ab!=bc&&(Math.abs(ab*ab+bc*bc-ac*ac)<0.000001))
System.out.print("false true false");
else if(ab==bc&&(Math.abs(ab*ab+bc*bc-ac*ac)<0.000001))
System.out.print("true true true");
else if(ab==bc)
System.out.print("true false false");
else
System.out.print("false false false");
}
else
System.out.print("false false false");
//}
}
break;
第三问:
判断四边形是凸四边形还是凹四边形:当四边形对角线的交点同时在两条对角线上时,该四边形为凸四边形;当四边形对角线的交点只在其中一条上时,该四边形为凹四边形;当四边形对角线的交点同时不在两条对角线上时,该图形不为四边形。
case "3":
if(point.length!=9){
System.out.print("wrong number of points");
return;
}
else{
Sanjiaoxing T = new Sanjiaoxing();
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian N = new Dian();
if((A.x==B.x&&A.y==B.y)||(A.x==C.x&&A.y==C.y)||(A.x==D.x&&A.y==D.y)||(C.x==B.x&&C.y==B.y)||(D.x==B.x&&D.y==B.y)||(C.x==D.x&&C.y==D.y)){
System.out.print("points coincide");
return;
}
Xian AB = new Xian();
AB.a = A;
AB.b = B;
if(AB.a.x!=AB.b.x)
AB.k = AB.xielv();
double ab = A.juli(B);
Xian BC = new Xian();
BC.a = B;
BC.b = C;
if(BC.a.x!=BC.b.x)
BC.k = BC.xielv();
double bc = C.juli(B);
Xian CD = new Xian();
CD.a = C;
CD.b = D;
if(CD.a.x!=CD.b.x)
CD.k = CD.xielv();
double cd = C.juli(D);
Xian DA = new Xian();
DA.a = D;
DA.b = A;
if(DA.a.x!=DA.b.x)
DA.k = DA.xielv();
double da = A.juli(D);
Xian AC = new Xian();
AC.a = A;
AC.b = C;
if(AC.a.x!=AC.b.x)
AC.k = AC.xielv();
double ac = A.juli(C);
Xian BD = new Xian();
BD.a = B;
BD.b = D;
if(BD.a.x!=BD.b.x)
BD.k = BD.xielv();
N = AC.jiaodian(BD);
if(AB.xianshang(C)||AB.xianshang(D)||CD.xianshang(A)||CD.xianshang(B))
System.out.print("not a quadrilateral");
else if((!AC.xianduanshang(N)&&!BD.xianduanshang(N))||(AC.pingxing(BD)))
System.out.print("not a quadrilateral");
else{
if(AC.xianduanshang(N)&&BD.xianduanshang(N)){
double zhouchang;
zhouchang = ab+bc+cd+da;
double s = T.mianji(A,B,C)+T.mianji(A,D,C);
zhouchang = Math.round(zhouchang*1000)/1000.0;
s = Math.round(s*1000)/1000.0;
System.out.println("true "+zhouchang+" "+s);
}
else{
if(AC.xianduanshang(N)&&!BD.xianduanshang(N)){//BD切割
double zhouchang;
zhouchang = ab+bc+cd+da;
double s = T.mianji(A,B,D)+T.mianji(B,D,C);
zhouchang = Math.round(zhouchang*1000)/1000.0;
s = Math.round(s*1000)/1000.0;
System.out.println("false "+zhouchang+" "+s);
}
else{
double zhouchang;
zhouchang = ab+bc+cd+da;
double s = T.mianji(A,C,D)+T.mianji(B,A,C);
zhouchang = Math.round(zhouchang*1000)/1000.0;
s = Math.round(s*1000)/1000.0;
System.out.println("false "+zhouchang+" "+s);
}
}
}
}
break;
第四问:
直线分割四边形(三角形):当判断输入的四个点能否构成三角形时,需考虑点重复以及顶点与两个底点不同时相邻的情况,故需分四种情况分别讨论(若使用继承,则可只讨论一次);当切割的图形为四边形时,需通过记录交点位置来判断切割后的图形面积如何计算。
case "4":
if(point.length!=13){
System.out.print("wrong number of points");
return;
}
else{
Sanjiaoxing T = new Sanjiaoxing();
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian E = new Dian();
E.x = Double.valueOf(point[9]);
E.y = Double.valueOf(point[10]);
Dian F = new Dian();
F.x = Double.valueOf(point[11]);
F.y = Double.valueOf(point[12]);
Dian N = new Dian();
Dian D1 = new Dian();
Dian D2 = new Dian();
Dian D3 = new Dian();
Dian D4 = new Dian();
Sibianxing W = new Sibianxing();
double S,s1,s2;
if(A.x==B.x&&A.y==B.y){
System.out.print("points coincide");
return;
}
Xian AB = new Xian();
AB.a = A;
AB.b = B;
if(AB.a.x!=AB.b.x)
AB.k = AB.xielv();
double ab = A.juli(B);
Xian CD = new Xian();
CD.a = C;
CD.b = D;
if(CD.a.x!=CD.b.x)
CD.k = CD.xielv();
double cd = C.juli(D);
Xian DE = new Xian();
DE.a = D;
DE.b = E;
if(DE.a.x!=DE.b.x)
DE.k = DE.xielv();
double de = E.juli(D);
Xian EF = new Xian();
EF.a = E;
EF.b = F;
if(EF.a.x!=EF.b.x)
EF.k = EF.xielv();
double ef = E.juli(F);
Xian FC = new Xian();
FC.a = F;
FC.b = C;
if(FC.a.x!=FC.b.x)
FC.k = FC.xielv();
double fc = C.juli(F);
Xian CE = new Xian();
CE.a = C;
CE.b = E;
if(CE.a.x!=CE.b.x)
CE.k = CE.xielv();
double ce = C.juli(E);
Xian FD = new Xian();
FD.a = F;
FD.b = D;
if(FD.a.x!=FD.b.x)
FD.k = FD.xielv();
double fd = F.juli(D);
N = CE.jiaodian(FD);
double f1=0,f2=0,f3=0,f4=0,sum=0;
if((CD.xianshang(E)&&CD.xianshang(F))||(!CE.xianduanshang(N)&&!FD.xianduanshang(N))||(CE.pingxing(FD))||(CE.xianduanshang(N)&&!FD.xianduanshang(N))||(!CE.xianduanshang(N)&&FD.xianduanshang(N))){
System.out.print("not a quadrilateral or triangle");
return;
}
if((AB.pingxing(CD)&&CD.chuizhijuli(A)==0)||(AB.pingxing(DE)&&DE.chuizhijuli(A)==0)||(AB.pingxing(EF)&&EF.chuizhijuli(A)==0)||(AB.pingxing(FC)&&FC.chuizhijuli(A)==0)){
System.out.print("The line is coincide with one of the lines");
return;
}
if((FD.xianduanshang(E)&&!FD.xianshang(C))||(E.x==C.x&&E.y==C.y)||(E.x==D.x&&E.y==D.y)||(E.x==F.x&&E.y==F.y)){
if(!AB.pingxing(CD)){
D1 = AB.jiaodian(CD);
if(CD.xianduanshang(D1)){
f1=1;
sum++;
}
}
if(!AB.pingxing(FD)){
D2 = AB.jiaodian(FD);
if(FD.xianduanshang(D2)&&!(D2.x==D1.x&&D2.y==D1.y)){
f2=1;
sum++;
}
}
if(!AB.pingxing(FC)){
D3 = AB.jiaodian(FC);
if(FC.xianduanshang(D3)&&!(D3.x==D1.x&&D3.y==D1.y)&&!(D3.x==D2.x&&D3.y==D2.y)){
f3=1;
sum++;
}
}
if(sum==0){
System.out.print("0");
}
else if(sum==1){
System.out.print("1");
}
else{
S = T.mianji(C,D,F);
if(f1==1&&f2==1)
s1 = T.mianji(D1,D,D2);
else if(f1==1&&f3==1)
s1 = T.mianji(D1,C,D3);
else
s1 = T.mianji(D2,F,D3);
s2 = S - s1;
if(s1>s2)
System.out.println("2 "+Math.round(s2*1000)/1000.0+" "+Math.round(s1*1000)/1000.0);
else
System.out.println("2 "+Math.round(s1*1000)/1000.0+" "+Math.round(s2*1000)/1000.0);
}
}
else if((CE.xianduanshang(F)&&!CE.xianshang(D))||(F.x==C.x&&F.y==C.y)||(F.x==D.x&&F.y==D.y)||(E.x==F.x&&E.y==F.y)){
if(!AB.pingxing(DE)){
D1 = AB.jiaodian(DE);
if(DE.xianduanshang(D1)){
f1=1;
sum++;
}
}
if(!AB.pingxing(CE)){
D2 = AB.jiaodian(CE);
if(CE.xianduanshang(D2)&&!(D2.x==D1.x&&D2.y==D1.y)){
f2=1;
sum++;
}
}
if(!AB.pingxing(CD)){
D3 = AB.jiaodian(CD);
if(CD.xianduanshang(D3)&&!(D3.x==D1.x&&D3.y==D1.y)&&!(D3.x==D2.x&&D3.y==D2.y)){
f3=1;
sum++;
}
}
if(sum==0){
System.out.print("0");
}
else if(sum==1){
System.out.print("1");
}
else{
S = T.mianji(C,D,E);
if(f1==1&&f2==1)
s1 = T.mianji(D1,E,D2);
else if(f1==1&&f3==1)
s1 = T.mianji(D1,D,D3);
else
s1 = T.mianji(D2,C,D3);
s2 = S - s1;
if(s1>s2)
System.out.println("2 "+Math.round(s2*1000)/1000.0+" "+Math.round(s1*1000)/1000.0);
else
System.out.println("2 "+Math.round(s1*1000)/1000.0+" "+Math.round(s2*1000)/1000.0);
}
}
else if((FD.xianduanshang(C)&&!FD.xianshang(E))||(E.x==C.x&&E.y==C.y)||(C.x==D.x&&C.y==D.y)||(C.x==F.x&&C.y==F.y)){
if(!AB.pingxing(EF)){
D1 = AB.jiaodian(EF);
if(EF.xianduanshang(D1)){
f1=1;
sum++;
}
}
if(!AB.pingxing(FD)){
D2 = AB.jiaodian(FD);
if(FD.xianduanshang(D2)&&!(D2.x==D1.x&&D2.y==D1.y)){
f2=1;
sum++;
}
}
if(!AB.pingxing(DE)){
D3 = AB.jiaodian(DE);
if(DE.xianduanshang(D3)&&!(D3.x==D1.x&&D3.y==D1.y)&&!(D3.x==D2.x&&D3.y==D2.y)){
f3=1;
sum++;
}
}
if(sum==0){
System.out.print("0");
}
else if(sum==1){
System.out.print("1");
}
else{
S = T.mianji(F,D,E);
if(f1==1&&f2==1)
s1 = T.mianji(D1,F,D2);
else if(f1==1&&f3==1)
s1 = T.mianji(D1,E,D3);
else
s1 = T.mianji(D2,D,D3);
s2 = S - s1;
if(s1>s2)
System.out.println("2 "+Math.round(s2*1000)/1000.0+" "+Math.round(s1*1000)/1000.0);
else
System.out.println("2 "+Math.round(s1*1000)/1000.0+" "+Math.round(s2*1000)/1000.0);
}
}
else if((CE.xianduanshang(D)&&!CE.xianshang(F))||(E.x==D.x&&E.y==D.y)||(C.x==D.x&&C.y==D.y)||(D.x==F.x&&D.y==F.y)){
if(!AB.pingxing(FC)){
D1 = AB.jiaodian(FC);
if(FC.xianduanshang(D1)){
f1=1;
sum++;
}
}
if(!AB.pingxing(CE)){
D2 = AB.jiaodian(CE);
//System.out.println(D2.x +" " +D2.y);
if(CE.xianduanshang(D2)&&!(D2.x==D1.x&&D2.y==D1.y)){
f2=1;
sum++;
}
}
if(!AB.pingxing(EF)){
D3 = AB.jiaodian(EF);
if(EF.xianduanshang(D3)&&!(D3.x==D1.x&&D3.y==D1.y)&&!(D3.x==D2.x&&D3.y==D2.y)){
f3=1;
sum++;
}
}
//System.out.println(f1+" "+f2+" "+f3);
if(sum==0){
System.out.print("0");
}
else if(sum==1){
System.out.print("1");
}
else{
S = T.mianji(C,F,E);
if(f1==1&&f2==1)
s1 = T.mianji(D1,C,D2);
else if(f1==1&&f3==1)
s1 = T.mianji(D1,F,D3);
else
s1 = T.mianji(D2,E,D3);
s2 = S - s1;
if(s1>s2)
System.out.println("2 "+Math.round(s2*1000)/1000.0+" "+Math.round(s1*1000)/1000.0);
else
System.out.println("2 "+Math.round(s1*1000)/1000.0+" "+Math.round(s2*1000)/1000.0);
}
}
else if(CE.xianduanshang(N)&&FD.xianduanshang(N)){
if(!AB.pingxing(CD)){
D1 = AB.jiaodian(CD);
if(CD.xianduanshang(D1)){
f1=1;
sum++;
}
}
if(!AB.pingxing(DE)){
D2 = AB.jiaodian(DE);
if(DE.xianduanshang(D2)&&!(D2.x==D1.x&&D2.y==D1.y)){
f2=1;
sum++;
}
}
if(!AB.pingxing(EF)){
D3 = AB.jiaodian(EF);
if(EF.xianduanshang(D3)&&!(D3.x==D2.x&&D3.y==D2.y)){
f3=1;
sum++;
}
}
if(!AB.pingxing(FC)){
D4 = AB.jiaodian(FC);
if(FC.xianduanshang(D3)&&!(D3.x==D4.x&&D3.y==D4.y)&&!(D1.x==D4.x&&D1.y==D4.y)){
f4=1;
sum++;
}
}
if(sum==0){
System.out.print("0");
}
else if(sum==1){
System.out.print("1");
}
else{
S = W.mianji(C,D,E,F);
if(f1==1&&f2==1)
s1 = T.mianji(D1,D,D2);
else if(f1==1&&f3==1)
s1 = W.mianji(D1,D,E,D3);
else if(f1==1&&f4==1)
s1 = T.mianji(D1,C,D4);
else if(f2==1&&f3==1)
s1 = T.mianji(D2,E,D3);
else if(f2==1&&f4==1)
s1 = W.mianji(D4,C,D,D2);
else
s1 = T.mianji(D3,F,D4);
s2 = S - s1;
if(s1>s2)
System.out.println("2 "+Math.round(s2*1000)/1000.0+" "+Math.round(s1*1000)/1000.0);
else
System.out.println("2 "+Math.round(s1*1000)/1000.0+" "+Math.round(s2*1000)/1000.0);
}
}
else{
System.out.println("not a quadrilateral or triangle");
}
}
break;
第五问:
判断点是否在四边形(三角形)内:利用点分别与其他两个相邻的点构成三角形,通过计算三角形面积之和是否与四边形(三角形)的面积相等来判断点是否在四边形(三角形)内。
case "5":
if(point.length!=11){
System.out.print("wrong number of points");
return;
}
else{
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian E = new Dian();
E.x = Double.valueOf(point[9]);
E.y = Double.valueOf(point[10]);
Dian N = new Dian();
Dian D1 = new Dian();
Dian D2 = new Dian();
Dian D3 = new Dian();
Dian D4 = new Dian();
Sibianxing W = new Sibianxing();
Sanjiaoxing T = new Sanjiaoxing();
double s,s1,s2,s3,s4;
Xian BC = new Xian();
BC.a = B;
BC.b = C;
if(BC.a.x!=BC.b.x)
BC.k = BC.xielv();
double bc = C.juli(B);
Xian CD = new Xian();
CD.a = C;
CD.b = D;
if(CD.a.x!=CD.b.x)
CD.k = CD.xielv();
double cd = C.juli(D);
Xian DE = new Xian();
DE.a = D;
DE.b = E;
if(DE.a.x!=DE.b.x)
DE.k = DE.xielv();
double de = E.juli(D);
Xian EB = new Xian();
EB.a = E;
EB.b = B;
if(EB.a.x!=EB.b.x)
EB.k = EB.xielv();
double eb = E.juli(B);
Xian BD = new Xian();
BD.a = B;
BD.b = D;
if(BD.a.x!=BD.b.x)
BD.k = BD.xielv();
double bd = B.juli(D);
Xian CE = new Xian();
CE.a = C;
CE.b = E;
if(CE.a.x!=CE.b.x)
CE.k = CE.xielv();
double ce = C.juli(E);
N = BD.jiaodian(CE);
if((BC.xianshang(E)&&DE.xianshang(B))||(!CE.xianduanshang(N)&&!BD.xianduanshang(N))||(CE.pingxing(BD))||(CE.xianduanshang(N)&&!BD.xianduanshang(N))||(!CE.xianduanshang(N)&&BD.xianduanshang(N))){
System.out.print("not a quadrilateral or triangle");
return;
}
if((CE.xianduanshang(D)&&!CE.xianshang(B))||(E.x==D.x&&E.y==D.y)||(C.x==D.x&&C.y==D.y)||(D.x==B.x&&D.y==B.y)){
if(BC.xianduanshang(A)||CE.xianduanshang(A)||EB.xianduanshang(A))
System.out.println("on the triangle");
else{
s = T.mianji(B,C,E);
s1 = T.mianji(A,B,C);
s2 = T.mianji(A,B,E);
s3 = T.mianji(A,E,C);
if(Math.abs(s1+s2+s3-s)<0.000001)
System.out.println("in the triangle");
else
System.out.println("outof the triangle");
}
}
else if((BD.xianduanshang(E)&&!BD.xianshang(C))||(E.x==D.x&&E.y==D.y)||(C.x==E.x&&C.y==E.y)||(E.x==B.x&&E.y==B.y)){
if(BC.xianduanshang(A)||CD.xianduanshang(A)||BD.xianduanshang(A))
System.out.println("on the triangle");
else{
s = T.mianji(B,C,D);
s1 = T.mianji(A,B,C);
s2 = T.mianji(A,B,D);
s3 = T.mianji(A,D,C);
if(Math.abs(s1+s2+s3-s)<0.000001)
System.out.println("in the triangle");
else
System.out.println("outof the triangle");
}
}
else if((CE.xianduanshang(B)&&!CE.xianshang(D))||(B.x==D.x&&B.y==D.y)||(C.x==B.x&&C.y==B.y)||(E.x==B.x&&E.y==B.y)){
if(CD.xianduanshang(A)||DE.xianduanshang(A)||CE.xianduanshang(A))
System.out.println("on the triangle");
else{
s = T.mianji(E,C,D);
s1 = T.mianji(A,E,C);
s2 = T.mianji(A,E,D);
s3 = T.mianji(A,D,C);
if(Math.abs(s1+s2+s3-s)<0.000001)
System.out.println("in the triangle");
else
System.out.println("outof the triangle");
}
}
else if((BD.xianduanshang(C)&&!BD.xianshang(E))||(C.x==D.x&&C.y==D.y)||(C.x==B.x&&C.y==B.y)||(E.x==C.x&&E.y==C.y)){
if(BD.xianduanshang(A)||DE.xianduanshang(A)||EB.xianduanshang(A))
System.out.println("on the triangle");
else{
s = T.mianji(E,B,D);
s1 = T.mianji(A,E,B);
s2 = T.mianji(A,E,D);
s3 = T.mianji(A,D,B);
if(Math.abs(s1+s2+s3-s)<0.000001)
System.out.println("in the triangle");
else
System.out.println("outof the triangle");
}
}
else if(BD.xianduanshang(N)&&CE.xianduanshang(N)){
if(BC.xianduanshang(A)||CD.xianduanshang(A)||DE.xianduanshang(A)||EB.xianduanshang(A))
System.out.println("on the quadrilateral");
else{
s = W.mianji(B,C,D,E);
s1 = T.mianji(A,C,B);
s2 = T.mianji(A,C,D);
s3 = T.mianji(A,D,E);
s4 = T.mianji(A,B,E);
if(Math.abs(s1+s2+s3+s4-s)<0.000001)
System.out.println("in the quadrilateral");
else
System.out.println("outof the quadrilateral");
}
}
else
System.out.println("not a quadrilateral or triangle");
}
break;
代码分析:
本题未使用继承,导致代码多处重复杂乱,使用的条件判断语句也更多。但是由于本次的类重新编写过,许多方法也改写过,所以使用起来更加方便。后续可使用继承方法将其中一些判断、计算放置在一起,使代码更加简洁明了。在提交代码的过程中,由于计算的误差原因,需要对数据进行处理,最终得到我们所需要的准确度。
题目5.7-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
本题开始进入五边形的题目,五边形需要考虑的情况和种类比四边形更复杂,但是计算的过程没有很大的困难,与之前的三角形、四边形都有很大关联。
源代码:
点类:
class Dian{
double x,y;
public double juli(Dian a){
return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2));
}
}
线类:
class Xian{
Dian a = new Dian();
Dian b = new Dian();
double k;
public double xielv(){
this.k = (this.a.y-this.b.y)/(this.a.x-this.b.x);
return this.k;
}
public boolean pingxing(Xian l){
if((l.a.y-l.b.y)*(this.a.x-this.b.x)==(l.a.x-l.b.x)*(this.a.y-this.b.y))
return true;
else
return false;
}
public Dian jiaodian(Xian l){
Dian n = new Dian();
double b1;
double b2;
if(this.a.x==this.b.x){
b2 = l.a.y - l.k * l.a.x;
n.x = this.a.x;
n.y = l.k * n.x + b2;
}
else if(l.a.x==l.b.x){
b1 = this.a.y - this.k * this.a.x;
n.x = l.a.x;
n.y = this.k * n.x + b1;
}
else{
b1 = this.a.y - this.k * this.a.x;
b2 = l.a.y - l.k * l.a.x;
n.x = (b2-b1)/(this.k-l.k);
n.y = l.k * n.x + b2;
}
return n;
}
public boolean xianshang(Dian x){
if((x.y-this.b.y)*(this.a.x-this.b.x)==(x.x-this.b.x)*(this.a.y-this.b.y))
return true;
else
return false;
}
public boolean xianduanshang(Dian x){
if((this.a.x==x.x&&this.a.y==x.y)||(this.b.x==x.x&&this.b.y==x.y))
return true;
else{
double ax = x.juli(this.a);
double bx = x.juli(this.b);
double ab = this.b.juli(this.a);
if(Math.abs(ax+bx-ab)<0.000001)
return true;
else
return false;
}
}
}
三角形类:
class Sanjiaoxing{
Dian a = new Dian();
Dian b = new Dian();
Dian c = new Dian();
public double mianji(Dian a,Dian b,Dian c){
double ab = a.juli(b);
double bc = c.juli(b);
double ca = a.juli(c);
double p = (ab+bc+ca)/2;
return Math.sqrt(p*(p-ab)*(p-bc)*(p-ca));
}
public boolean is_sanjiaoxing(Dian a,Dian b,Dian c){
double ab = a.juli(b);
double bc = c.juli(b);
double ca = a.juli(c);
Xian AB = new Xian();
AB.a = a;
AB.b = b;
if(AB.xianshang(c))
return false;
if(ab+bc-ac<0.000001||ac+bc-ab<0.000001||ab+ac-bc<0.000001)
return false;
else
return true;
}
}
四边形类:
class Sibianxing{
Dian a = new Dian();
Dian b = new Dian();
Dian c = new Dian();
Dian d = new Dian();
public double mianji(Dian a,Dian b,Dian c,Dian d){
Xian ac = new Xian();
Xian bd = new Xian();
Dian n = new Dian();
n = ac.jiaodian(bd);
Sanjiaoxing T = new Sanjiaoxing();
if(ac.xianduanshang(n)&&bd.xianduanshang(n))
return T.mianji(a,c,d)+T.mianji(a,c,b);
else if(ac.xianduanshang(n)&&!bd.xianduanshang(n))
return T.mianji(a,b,d)+T.mianji(d,c,b);
else
return T.mianji(a,c,d)+T.mianji(a,c,b);
}
public boolean is_tusibianxing(Dian a,Dian b,Dian c,Dian d){
Dian N = new Dian();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
N = ac.jiaodian(bd);
if(ac.xianduanshang(N)&&bd.xianduanshang(N))
return true;
else
return false;
}
public boolean is_sibianxing(Dian a,Dian b,Dian c,Dian d){
if((a.x==b.x&&a.y==b.y)||(a.x==c.x&&a.y==c.y)||(a.x==d.x&&a.y==d.y)||(c.x==b.x&&c.y==b.y)||(d.x==b.x&&d.y==b.y)||(c.x==d.x&&c.y==d.y))
return false;
Dian N = new Dian();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
N = ac.jiaodian(bd);
if(ab.xianshang(c)||bc.xianshang(d)||cd.xianshang(a)||ab.xianshang(d))
return false;
if(!ac.xianduanshang(N)&&!bd.xianduanshang(N))
return false;
else
return true;
}
}
五边形类:
class Wubianxing{
Dian a = new Dian();
Dian b = new Dian();
Dian c = new Dian();
Dian d = new Dian();
Dian e = new Dian();
public boolean is_wubianxing(Dian a,Dian b,Dian c,Dian d,Dian e){
if((a.x==b.x&&a.y==b.y)||(a.x==c.x&&a.y==c.y)||(a.x==d.x&&a.y==d.y)||(a.x==e.x&&a.y==e.y)||(c.x==b.x&&c.y==b.y)||(d.x==b.x&&d.y==b.y)||(e.x==b.x&&e.y==b.y)||(c.x==d.x&&c.y==d.y)||(c.x==e.x&&c.y==e.y)||(e.x==d.x&&e.y==d.y))
return false;
Sibianxing W = new Sibianxing();
Dian n1 = new Dian();
Dian n2 = new Dian();
Dian n3 = new Dian();
Dian n4 = new Dian();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian ae = new Xian();
ae.a = a;
ae.b = e;
if(ae.a.x!=ae.b.x)
ae.k = ae.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian be = new Xian();
be.a = b;
be.b = e;
if(be.a.x!=be.b.x)
be.k = be.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
Xian ce = new Xian();
ce.a = c;
ce.b = e;
if(ce.a.x!=ce.b.x)
ce.k = ce.xielv();
Xian de = new Xian();
de.a = d;
de.b = e;
if(de.a.x!=de.b.x)
de.k = de.xielv();
if((bc.xianshang(d)&&cd.xianshang(e))||(ac.xianshang(d)&&cd.xianshang(e))||(ab.xianshang(d)&&de.xianshang(b))||(ab.xianshang(c)&&ab.xianshang(e))||(ab.xianshang(d)&&cd.xianshang(b)))
return false;
else{
if(W.is_sibianxing(b,c,d,e)){
if(bc.xianshang(a)||cd.xianshang(a)||de.xianshang(a)||be.xianshang(a))
return false;
if(!ae.pingxing(cd))
n1 = ae.jiaodian(cd);
if(!ae.pingxing(bc))
n2 = ae.jiaodian(bc);
if(!ab.pingxing(cd))
n3 = ab.jiaodian(cd);
if(!ab.pingxing(de))
n4 = ab.jiaodian(de);
if((ae.xianduanshang(n1)&&cd.xianduanshang(n1))||(ae.xianduanshang(n2)&&bc.xianduanshang(n2))||(ab.xianduanshang(n3)&&cd.xianduanshang(n3))||(ab.xianduanshang(n4)&&de.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,c,d,e)){
if(ac.xianshang(b)||cd.xianshang(b)||de.xianshang(b)||ae.xianshang(b))
return false;
if(!ab.pingxing(de))
n1 = ab.jiaodian(de);
if(!ab.pingxing(cd))
n2 = ab.jiaodian(cd);
if(!bc.pingxing(de))
n3 = bc.jiaodian(de);
if(!bc.pingxing(ae))
n4 = bc.jiaodian(ae);
if((ab.xianduanshang(n1)&&de.xianduanshang(n1))||(ab.xianduanshang(n2)&&cd.xianduanshang(n2))||(bc.xianduanshang(n3)&&de.xianduanshang(n3))||(bc.xianduanshang(n4)&&ae.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,d,e)){
if(ab.xianshang(c)||bd.xianshang(c)||de.xianshang(c)||ae.xianshang(c))
return false;
if(!bc.pingxing(ae))
n1 = bc.jiaodian(ae);
if(!bc.pingxing(de))
n2 = bc.jiaodian(de);
if(!cd.pingxing(ab))
n3 = cd.jiaodian(ab);
if(!cd.pingxing(ae))
n4 = cd.jiaodian(ae);
if((bc.xianduanshang(n1)&&ae.xianduanshang(n1))||(bc.xianduanshang(n2)&&de.xianduanshang(n2))||(cd.xianduanshang(n3)&&ab.xianduanshang(n3))||(cd.xianduanshang(n4)&&ae.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,c,e)){
if(ab.xianshang(d)||bc.xianshang(d)||ce.xianshang(d)||ae.xianshang(d))
return false;
if(!de.pingxing(ab))
n1 = de.jiaodian(ab);
if(!de.pingxing(bc))
n2 = de.jiaodian(bc);
if(!cd.pingxing(ab))
n3 = cd.jiaodian(ab);
if(!cd.pingxing(ae))
n4 = cd.jiaodian(ae);
if((de.xianduanshang(n1)&&ab.xianduanshang(n1))||(de.xianduanshang(n2)&&bc.xianduanshang(n2))||(ab.xianduanshang(n3)&&cd.xianduanshang(n3))||(cd.xianduanshang(n4)&&ae.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,c,d)){
if(ab.xianshang(e)||bc.xianshang(e)||cd.xianshang(e)||ad.xianshang(e))
return false;
if(!ae.pingxing(cd))
n1 = ae.jiaodian(cd);
if(!ae.pingxing(bc))
n2 = ae.jiaodian(bc);
if(!de.pingxing(ab))
n3 = de.jiaodian(ab);
if(!de.pingxing(bc))
n4 = de.jiaodian(bc);
if((ae.xianduanshang(n1)&&cd.xianduanshang(n1))||(ae.xianduanshang(n2)&&bc.xianduanshang(n2))||(ab.xianduanshang(n3)&&de.xianduanshang(n3))||(bc.xianduanshang(n4)&&de.xianduanshang(n4)))
return false;
else
return true;
}
else
return false;
}
}
public boolean is_tuwubianxing(Dian a,Dian b,Dian c,Dian d,Dian e){
Sibianxing W = new Sibianxing();
Sanjiaoxing T = new Sanjiaoxing();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian ae = new Xian();
ae.a = a;
ae.b = e;
if(ae.a.x!=ae.b.x)
ae.k = ae.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian be = new Xian();
be.a = b;
be.b = e;
if(be.a.x!=be.b.x)
be.k = be.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
Xian ce = new Xian();
ce.a = c;
ce.b = e;
if(ce.a.x!=ce.b.x)
ce.k = ce.xielv();
Xian de = new Xian();
de.a = d;
de.b = e;
if(de.a.x!=de.b.x)
de.k = de.xielv();
if(W.is_sibianxing(b,c,d,e)){
if(T.mianji(a,b,c)+T.mianji(a,c,d)+T.mianji(a,d,e)+T.mianji(a,b,e)-W.mianji(b,c,d,e)<0.000001)
return false;
else
return true;
}
else if(W.is_sibianxing(a,c,d,e)){
if(T.mianji(a,b,c)+T.mianji(b,c,d)+T.mianji(b,d,e)+T.mianji(a,b,e)-W.mianji(a,c,d,e)<0.000001)
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,d,e)){
if(T.mianji(a,b,c)+T.mianji(b,c,d)+T.mianji(c,d,e)+T.mianji(c,a,e)-W.mianji(a,b,d,e)<0.000001)
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,c,e)){
if(T.mianji(a,b,d)+T.mianji(b,c,d)+T.mianji(c,d,e)+T.mianji(a,d,e)-W.mianji(a,b,c,e)<0.000001)
return false;
else
return true;
}
else{
if(T.mianji(a,b,e)+T.mianji(e,c,b)+T.mianji(c,d,e)+T.mianji(a,d,e)-W.mianji(a,b,c,d)<0.000001)
return false;
else
return true;
}
}
public double mianji(Dian a,Dian b,Dian c,Dian d,Dian e){
Sanjiaoxing T = new Sanjiaoxing();
return T.mianji(a,b,c) + T.mianji(a,c,d) + T.mianji(a,d,e);
}
}
第一问:
判断是否构成五边形:先判断其中四个点是否构成四边形,再判断剩下一个点是否在该线段的里面或外面(在里面则一定构成五边形,为凹五边形;在外面则为凸五边形)。
case "1":
if(point.length!=11){
System.out.print("wrong number of points");
return;
}
else{
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian E = new Dian();
E.x = Double.valueOf(point[9]);
E.y = Double.valueOf(point[10]);
Wubianxing P = new Wubianxing();
if(!P.is_wubianxing(A,B,C,D,E))
System.out.println("false");
else
System.out.println("true");
}
break;
第二问:
判断是凸五边形还是凹五边形:先判断其中四个点是否构成四边形,再判断剩下一个点是否在该线段的里面或外面(在里面则一定构成五边形,为凹五边形;在外面则为凸五边形)。
case "2":
if(point.length!=11){
System.out.print("wrong number of points");
return;
}
else{
Dian A = new Dian();
A.x = Double.valueOf(point[1]);
A.y = Double.valueOf(point[2]);
Dian B = new Dian();
B.x = Double.valueOf(point[3]);
B.y = Double.valueOf(point[4]);
Dian C = new Dian();
C.x = Double.valueOf(point[5]);
C.y = Double.valueOf(point[6]);
Dian D = new Dian();
D.x = Double.valueOf(point[7]);
D.y = Double.valueOf(point[8]);
Dian E = new Dian();
E.x = Double.valueOf(point[9]);
E.y = Double.valueOf(point[10]);
Wubianxing P = new Wubianxing();
Sanjiaoxing T = new Sanjiaoxing();
if(!P.is_wubianxing(A,B,C,D,E)){
System.out.println("not a pentagon");
return;
}
else{
if(!P.is_tuwubianxing(A,B,C,D,E)){
System.out.println("false");
return;
}
else{
double c = A.juli(B) + B.juli(C) + C.juli(D) + D.juli(E) + E.juli(A);
double s = T.mianji(A,B,C) + T.mianji(A,C,D) + T.mianji(A,D,E);
System.out.println("true "+Math.round(c*1000)/1000.0+" "+Math.round(s*1000)/1000.0);
}
}
}
break;
第三问:
直线切割五边形、四边形或三角形:先判断构成的是五边形、四边形还是三角形,再用直线切割。(切割方法前面的三角形、四边形都写过)
case 3: dex = 7; sign = ver.feifa(str, dex);
in.output(sign);
if(sign==1){//输入格式合法
Line l = new Line();
l.dot1.x = Double.valueOf(tokens[1]); l.dot1.y = Double.valueOf(tokens[2]);
l.dot2.x = Double.valueOf(tokens[3]); l.dot2.y = Double.valueOf(tokens[4]);
Pentagon p = new Pentagon();
Square s = new Square();
Triangle t = new Triangle();
if(l.dot1.coincide(l.dot2)){//l两端点重合
System.out.print("points coincide");
break;
}
p.setWuBianXing(5, tokens, p);//五边形信息录入
if(p.wuBianXingJudge(p)){//构成五边形
if(p.xianChongHe5(p, l)){
System.out.print("The line is coincide with one of the lines");
break;
}
p.qieGeWuBianXing(p, l);
}
else if(s.siBianXingJudge(p, s)){//构成四边形
if(s.xianChongHe4(s, l)){
System.out.print("The line is coincide with one of the lines");
break;
}
s.qieGeSiBianXing(s, l);
}
else if(t.sanJiaoXingJudge(p, t)){//构成三角形
if(t.xianChongHe3(t, l)){
System.out.print("The line is coincide with one of the lines");
break;
}
t.qieGeSanJiaoXing(t, l);
}
else{//不构成多边形
System.out.print("not a polygon");
}
}
break;
代码分析:
本题的五边形类中,将判断是否为五边形以及判断五边形的类型作为方法写进了类中,使代码简洁了些许,但是其中还是会有大段重复的判断方法,后续需要继续缩减代码。在提交的过程中,五边形有许多种特殊的情况需要考虑,例如其中三点共线也是可以构成五边形的,因此在考虑问题时需要换取另一种方法进行判断,并且在计算时也要分好多种情况进行讨论,使得代码多次进行条件语句的判断。
题目5.7-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
本题属于五边形的后续计算,将五边形各种方面的问题都包括进题目中,难度大在对于各种情况的考虑不周全。
源代码:
点类:
class Dian{
double x,y;
public double juli(Dian a){
return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2));
}
}
线类:
class Xian{
Dian a = new Dian();
Dian b = new Dian();
double k;
public double xielv(){
this.k = (this.a.y-this.b.y)/(this.a.x-this.b.x);
return this.k;
}
public boolean pingxing(Xian l){
if((l.a.y-l.b.y)*(this.a.x-this.b.x)==(l.a.x-l.b.x)*(this.a.y-this.b.y))
return true;
else
return false;
}
public Dian jiaodian(Xian l){
Dian n = new Dian();
double b1;
double b2;
if(this.a.x==this.b.x){
b2 = l.a.y - l.k * l.a.x;
n.x = this.a.x;
n.y = l.k * n.x + b2;
}
else if(l.a.x==l.b.x){
b1 = this.a.y - this.k * this.a.x;
n.x = l.a.x;
n.y = this.k * n.x + b1;
}
else{
b1 = this.a.y - this.k * this.a.x;
b2 = l.a.y - l.k * l.a.x;
n.x = (b2-b1)/(this.k-l.k);
n.y = l.k * n.x + b2;
}
return n;
}
public boolean xianshang(Dian x){
if((x.y-this.b.y)*(this.a.x-this.b.x)==(x.x-this.b.x)*(this.a.y-this.b.y))
return true;
else
return false;
}
public boolean xianduanshang(Dian x){
if((this.a.x==x.x&&this.a.y==x.y)||(this.b.x==x.x&&this.b.y==x.y))
return true;
else{
double ax = x.juli(this.a);
double bx = x.juli(this.b);
double ab = this.b.juli(this.a);
if(Math.abs(ax+bx-ab)<0.000001)
return true;
else
return false;
}
}
}
三角形类:
class Sanjiaoxing{
Dian a = new Dian();
Dian b = new Dian();
Dian c = new Dian();
public double mianji(Dian a,Dian b,Dian c){
double ab = a.juli(b);
double bc = c.juli(b);
double ca = a.juli(c);
double p = (ab+bc+ca)/2;
return Math.sqrt(p*(p-ab)*(p-bc)*(p-ca));
}
public boolean is_sanjiaoxing(Dian a,Dian b,Dian c){
double ab = a.juli(b);
double bc = c.juli(b);
double ca = a.juli(c);
Xian AB = new Xian();
AB.a = a;
AB.b = b;
if(AB.xianshang(c))
return false;
if(ab+bc-ac<0.000001||ac+bc-ab<0.000001||ab+ac-bc<0.000001)
return false;
else
return true;
}
}
四边形类:
class Sibianxing{
Dian a = new Dian();
Dian b = new Dian();
Dian c = new Dian();
Dian d = new Dian();
public double mianji(Dian a,Dian b,Dian c,Dian d){
Xian ac = new Xian();
Xian bd = new Xian();
Dian n = new Dian();
n = ac.jiaodian(bd);
Sanjiaoxing T = new Sanjiaoxing();
if(ac.xianduanshang(n)&&bd.xianduanshang(n))
return T.mianji(a,c,d)+T.mianji(a,c,b);
else if(ac.xianduanshang(n)&&!bd.xianduanshang(n))
return T.mianji(a,b,d)+T.mianji(d,c,b);
else
return T.mianji(a,c,d)+T.mianji(a,c,b);
}
public boolean is_tusibianxing(Dian a,Dian b,Dian c,Dian d){
Dian N = new Dian();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
N = ac.jiaodian(bd);
if(ac.xianduanshang(N)&&bd.xianduanshang(N))
return true;
else
return false;
}
public boolean is_sibianxing(Dian a,Dian b,Dian c,Dian d){
if((a.x==b.x&&a.y==b.y)||(a.x==c.x&&a.y==c.y)||(a.x==d.x&&a.y==d.y)||(c.x==b.x&&c.y==b.y)||(d.x==b.x&&d.y==b.y)||(c.x==d.x&&c.y==d.y))
return false;
Dian N = new Dian();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
N = ac.jiaodian(bd);
if(ab.xianshang(c)||bc.xianshang(d)||cd.xianshang(a)||ab.xianshang(d))
return false;
if(!ac.xianduanshang(N)&&!bd.xianduanshang(N))
return false;
else
return true;
}
}
五边形类:
class Wubianxing{
Dian a = new Dian();
Dian b = new Dian();
Dian c = new Dian();
Dian d = new Dian();
Dian e = new Dian();
public boolean is_wubianxing(Dian a,Dian b,Dian c,Dian d,Dian e){
if((a.x==b.x&&a.y==b.y)||(a.x==c.x&&a.y==c.y)||(a.x==d.x&&a.y==d.y)||(a.x==e.x&&a.y==e.y)||(c.x==b.x&&c.y==b.y)||(d.x==b.x&&d.y==b.y)||(e.x==b.x&&e.y==b.y)||(c.x==d.x&&c.y==d.y)||(c.x==e.x&&c.y==e.y)||(e.x==d.x&&e.y==d.y))
return false;
Sibianxing W = new Sibianxing();
Dian n1 = new Dian();
Dian n2 = new Dian();
Dian n3 = new Dian();
Dian n4 = new Dian();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian ae = new Xian();
ae.a = a;
ae.b = e;
if(ae.a.x!=ae.b.x)
ae.k = ae.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian be = new Xian();
be.a = b;
be.b = e;
if(be.a.x!=be.b.x)
be.k = be.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
Xian ce = new Xian();
ce.a = c;
ce.b = e;
if(ce.a.x!=ce.b.x)
ce.k = ce.xielv();
Xian de = new Xian();
de.a = d;
de.b = e;
if(de.a.x!=de.b.x)
de.k = de.xielv();
if((bc.xianshang(d)&&cd.xianshang(e))||(ac.xianshang(d)&&cd.xianshang(e))||(ab.xianshang(d)&&de.xianshang(b))||(ab.xianshang(c)&&ab.xianshang(e))||(ab.xianshang(d)&&cd.xianshang(b)))
return false;
else{
if(W.is_sibianxing(b,c,d,e)){
if(bc.xianshang(a)||cd.xianshang(a)||de.xianshang(a)||be.xianshang(a))
return false;
if(!ae.pingxing(cd))
n1 = ae.jiaodian(cd);
if(!ae.pingxing(bc))
n2 = ae.jiaodian(bc);
if(!ab.pingxing(cd))
n3 = ab.jiaodian(cd);
if(!ab.pingxing(de))
n4 = ab.jiaodian(de);
if((ae.xianduanshang(n1)&&cd.xianduanshang(n1))||(ae.xianduanshang(n2)&&bc.xianduanshang(n2))||(ab.xianduanshang(n3)&&cd.xianduanshang(n3))||(ab.xianduanshang(n4)&&de.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,c,d,e)){
if(ac.xianshang(b)||cd.xianshang(b)||de.xianshang(b)||ae.xianshang(b))
return false;
if(!ab.pingxing(de))
n1 = ab.jiaodian(de);
if(!ab.pingxing(cd))
n2 = ab.jiaodian(cd);
if(!bc.pingxing(de))
n3 = bc.jiaodian(de);
if(!bc.pingxing(ae))
n4 = bc.jiaodian(ae);
if((ab.xianduanshang(n1)&&de.xianduanshang(n1))||(ab.xianduanshang(n2)&&cd.xianduanshang(n2))||(bc.xianduanshang(n3)&&de.xianduanshang(n3))||(bc.xianduanshang(n4)&&ae.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,d,e)){
if(ab.xianshang(c)||bd.xianshang(c)||de.xianshang(c)||ae.xianshang(c))
return false;
if(!bc.pingxing(ae))
n1 = bc.jiaodian(ae);
if(!bc.pingxing(de))
n2 = bc.jiaodian(de);
if(!cd.pingxing(ab))
n3 = cd.jiaodian(ab);
if(!cd.pingxing(ae))
n4 = cd.jiaodian(ae);
if((bc.xianduanshang(n1)&&ae.xianduanshang(n1))||(bc.xianduanshang(n2)&&de.xianduanshang(n2))||(cd.xianduanshang(n3)&&ab.xianduanshang(n3))||(cd.xianduanshang(n4)&&ae.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,c,e)){
if(ab.xianshang(d)||bc.xianshang(d)||ce.xianshang(d)||ae.xianshang(d))
return false;
if(!de.pingxing(ab))
n1 = de.jiaodian(ab);
if(!de.pingxing(bc))
n2 = de.jiaodian(bc);
if(!cd.pingxing(ab))
n3 = cd.jiaodian(ab);
if(!cd.pingxing(ae))
n4 = cd.jiaodian(ae);
if((de.xianduanshang(n1)&&ab.xianduanshang(n1))||(de.xianduanshang(n2)&&bc.xianduanshang(n2))||(ab.xianduanshang(n3)&&cd.xianduanshang(n3))||(cd.xianduanshang(n4)&&ae.xianduanshang(n4)))
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,c,d)){
if(ab.xianshang(e)||bc.xianshang(e)||cd.xianshang(e)||ad.xianshang(e))
return false;
if(!ae.pingxing(cd))
n1 = ae.jiaodian(cd);
if(!ae.pingxing(bc))
n2 = ae.jiaodian(bc);
if(!de.pingxing(ab))
n3 = de.jiaodian(ab);
if(!de.pingxing(bc))
n4 = de.jiaodian(bc);
if((ae.xianduanshang(n1)&&cd.xianduanshang(n1))||(ae.xianduanshang(n2)&&bc.xianduanshang(n2))||(ab.xianduanshang(n3)&&de.xianduanshang(n3))||(bc.xianduanshang(n4)&&de.xianduanshang(n4)))
return false;
else
return true;
}
else
return false;
}
}
public boolean is_tuwubianxing(Dian a,Dian b,Dian c,Dian d,Dian e){
Sibianxing W = new Sibianxing();
Sanjiaoxing T = new Sanjiaoxing();
Xian ab = new Xian();
ab.a = a;
ab.b = b;
if(ab.a.x!=ab.b.x)
ab.k = ab.xielv();
Xian ac = new Xian();
ac.a = a;
ac.b = c;
if(ac.a.x!=ac.b.x)
ac.k = ac.xielv();
Xian ad = new Xian();
ad.a = a;
ad.b = d;
if(ad.a.x!=ad.b.x)
ad.k = ad.xielv();
Xian ae = new Xian();
ae.a = a;
ae.b = e;
if(ae.a.x!=ae.b.x)
ae.k = ae.xielv();
Xian bc = new Xian();
bc.a = b;
bc.b = c;
if(bc.a.x!=bc.b.x)
bc.k = bc.xielv();
Xian bd = new Xian();
bd.a = b;
bd.b = d;
if(bd.a.x!=bd.b.x)
bd.k = bd.xielv();
Xian be = new Xian();
be.a = b;
be.b = e;
if(be.a.x!=be.b.x)
be.k = be.xielv();
Xian cd = new Xian();
cd.a = c;
cd.b = d;
if(cd.a.x!=cd.b.x)
cd.k = cd.xielv();
Xian ce = new Xian();
ce.a = c;
ce.b = e;
if(ce.a.x!=ce.b.x)
ce.k = ce.xielv();
Xian de = new Xian();
de.a = d;
de.b = e;
if(de.a.x!=de.b.x)
de.k = de.xielv();
if(W.is_sibianxing(b,c,d,e)){
if(T.mianji(a,b,c)+T.mianji(a,c,d)+T.mianji(a,d,e)+T.mianji(a,b,e)-W.mianji(b,c,d,e)<0.000001)
return false;
else
return true;
}
else if(W.is_sibianxing(a,c,d,e)){
if(T.mianji(a,b,c)+T.mianji(b,c,d)+T.mianji(b,d,e)+T.mianji(a,b,e)-W.mianji(a,c,d,e)<0.000001)
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,d,e)){
if(T.mianji(a,b,c)+T.mianji(b,c,d)+T.mianji(c,d,e)+T.mianji(c,a,e)-W.mianji(a,b,d,e)<0.000001)
return false;
else
return true;
}
else if(W.is_sibianxing(a,b,c,e)){
if(T.mianji(a,b,d)+T.mianji(b,c,d)+T.mianji(c,d,e)+T.mianji(a,d,e)-W.mianji(a,b,c,e)<0.000001)
return false;
else
return true;
}
else{
if(T.mianji(a,b,e)+T.mianji(e,c,b)+T.mianji(c,d,e)+T.mianji(a,d,e)-W.mianji(a,b,c,d)<0.000001)
return false;
else
return true;
}
}
public double mianji(Dian a,Dian b,Dian c,Dian d,Dian e){
Sanjiaoxing T = new Sanjiaoxing();
return T.mianji(a,b,c) + T.mianji(a,c,d) + T.mianji(a,d,e);
}
}
第四问:
判断两个多边形之间的关系:需要将每种关系分开讨论,分离为毫无交点;连接为只有一个点重合或一条边重合(排除包含);完全重合为构成多边形的每一条边都重合;被包含和包含都是一个图形的所有点都存在于另一个图形的内部;交错为两图形的交点不唯一且都在线段上。
case 4: dex = 10; sign = ver.feifa(str, dex);
in.output(sign);
if(sign==1){//输入合法
Pentagon p1 = new Pentagon(); Square s1 = new Square(); Triangle t1 = new Triangle();
Pentagon p2 = new Pentagon(); Square s2 = new Square(); Triangle t2 = new Triangle();
p1.setWuBianXing(1, tokens, p1);//五边形p1信息录入
p2.setWuBianXing(11, tokens, p2);//五边形p1信息录入
weiZhiGuangXi gx = new weiZhiGuangXi();
gx.weiZhiGuangXi(p1, p2, s1, s2, t1, t2);
}
break;
第五问:
多边形分割:分割时需分情况讨论分割点的位置,再通过图形来确认分割面积的计算方法。
case 5: dex = 10; sign = ver.feifa(str, dex);
in.output(sign);
if(sign==1){//输入合法
Pentagon p1 = new Pentagon(); Square s1 = new Square(); Triangle t1 = new Triangle();
Pentagon p2 = new Pentagon(); Square s2 = new Square(); Triangle t2 = new Triangle();
p1.setWuBianXing(1, tokens, p1);//五边形p1信息录入
p2.setWuBianXing(11, tokens, p2);//五边形p1信息录入
}
break;
第六问:
判断点是否在多边形内部:使用面积法判断(同三角形和四边形)。
case 6: dex = 6; sign = ver.feifa(str, dex);
in.output(sign);
if(sign==1){//输入合法
Spot dot = new Spot();
dot.x = Double.valueOf(tokens[1]); dot.y = Double.valueOf(tokens[2]);
Pentagon p = new Pentagon();
Square s = new Square();
Triangle t = new Triangle();
p.setWuBianXing(3, tokens, p);//五边形信息录入
if(p.wuBianXingJudge(p)){//构成五边形
if(p.dianOnWuBianXing(p, dot)){//点在五边形上
System.out.print("on the pentagon");
}
else if(p.dianInWuBianXing(p, dot)){//点在五边形内
System.out.print("in the pentagon");
}
else{//点在五边形外
System.out.print("outof the pentagon");
}
}
else if(s.siBianXingJudge(p, s)){//构成四边形
if(s.dianOnSiBianXing(s, dot)){//点在四边形上
System.out.print("on the quadrilateral");
}
else if(s.dianInSiBianXing(s, dot)){//点在四边形内
System.out.print("in the quadrilateral");
}
else{//点在四边形外
System.out.print("outof the quadrilateral");
}
}
else if(t.sanJiaoXingJudge(p, t)){//构成三角形
if(t.dianOnSanJiaoXing(t, dot)){//点在三角形上
System.out.print("on the triangle");
}
else if(t.dianInSanJiaoXing(t, dot)){//点在三角形内
System.out.print("in the triangle");
}
else{//点在三角形外
System.out.print("outof the triangle");
}
}
else{//不构成多边形
System.out.print("not a polygon");
}
}
break;
代码分析:
因为将多种计算都放入了类中的方法,故代码简洁了许多,但是有些方法还是不够完善,导致一些问题还是无法解决,计算较为复杂。同时,由于每种多边形的计算方法和判断方法都不同,需要对每种情况都进行分类讨论、计算,导致代码十分长,最终超出限制。在提交的过程中发现,由于各种情况较多,对于非法的判断就不需要单独考虑,只需将合法的计算,剩下的都视为不合法即可。
期中7-1:
- 设计一个类表示平面直角坐标系上的点Point,私有属性分别为横坐标x与纵坐标y,数据类型均为实型数,除构造方法以及属性的getter与setter方法外,定义一个用于显示信息的方法display(),用来输出该坐标点的坐标信息,格式如下:
(x,y)
,数值保留两位小数。为简化题目,其中,坐标点的取值范围设定为(0,200]
。若输入有误,系统则直接输出Wrong Format
- 设计一个类表示平面直角坐标系上的线Line,私有属性除了标识线段两端的点point1、point2外,还有一个字符串类型的color,用于表示该线段的颜色,同样,除构造方法以及属性的getter与setter方法外,定义一个用于计算该线段长度的方法getDistance(),还有一个用于显示信息的方法display(),用来输出线段的相关信息,输出格式如下:
```
The line's color is:颜色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:长度值
```
其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)
方法。
设计类图如下图所示。
** 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的display()方法进行输出。**
本题与之前的较为一致,只需更改主类即可。
源代码:
点类:
class Point{
private double x;
private double y;
Point(){
}
Point(double x,double y){
this.x = x;
this.y = y;
}
public double getx(){
return this.x;
}
public double gety(){
return this.y;
}
public void setx(double x){
this.x = x;
}
public void sety(double y){
this.y = y;
}
public void display(){
System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")");
}
}
线类:
class Line{
private Point point1;
private Point point2;
private String color;
Line(){
point1 = new Point();
point2 = new Point();
}
Line(Point p1,Point p2,String color){
this.point1 = p1;
this.point2 = p2;
this.color = color;
}
public Point getPoint1(){
return this.point1;
}
public Point getPoint2(){
return this.point2;
}
public void setPoint1(Point point1){
this.point1 = point1;
}
public void setPoint2(Point point2){
this.point2 = point2;
}
public String getColor(){
return this.color;
}
public void setColor(String color){
this.color = color;
}
public double getDistance(){
return Math.sqrt(Math.pow(this.point1.getx()-this.point2.getx(),2)+Math.pow(this.point1.gety()-this.point2.gety(),2));
}
public void display(){
Line L = new Line();
L.point1 = this.point1;
L.point2 = this.point2;
System.out.println("The line's color is:"+this.color);
System.out.println("The line's begin point's Coordinate is:");
point1.display();
System.out.println("The line's end point's Coordinate is:");
point2.display();
double l;
l = L.getDistance();
System.out.println("The line's length is:"+String.format("%.2f", l));
}
}
主类:
class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
if(x1>0&&x1<=200&&y1>0&&y1<=200&&x2>0&&x2<=200&&y2>0&&y2<=200){
Point point1 = new Point();
point1.setx(x1);
point1.sety(y1);
Point point2 = new Point();
point2.setx(x2);
point2.sety(y2);
Line L = new Line();
L.setPoint1(point1);
L.setPoint2(point2);
L.setColor(color);
L.display();
}
else{
System.out.println("Wrong Format");
}
}
}
代码分析:
本题较为简单,只是在之前的基础上增加了几个方法,根据题目给出的类图进行编写即可。
期中7-2:
在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。
- 对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。
- 再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,输出格式如下:
The Plane's color is:颜色
- 在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。示例代码如下:
element = p1;//起点Point
element.display();
element = p2;//终点Point
element.display();
element = line;//线段
element.display();
element = plane;//面
element.display();
其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)
方法。
源代码:
Element抽象类:
abstract class Element{
public abstract void display();
}
点类:
class Point extends Element{
private double x;
private double y;
Point(){
}
Point(double x,double y){
this.x = x;
this.y = y;
}
public double getx(){
return this.x;
}
public double gety(){
return this.y;
}
public void setx(double x){
this.x = x;
}
public void sety(double y){
this.y = y;
}
public void display(){
System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")");
}
}
线类:
class Line extends Element{
private Point point1;
private Point point2;
private String color;
Line(){
point1 = new Point();
point2 = new Point();
}
Line(Point p1,Point p2,String color){
this.point1 = p1;
this.point2 = p2;
this.color = color;
}
public Point getPoint1(){
return this.point1;
}
public Point getPoint2(){
return this.point2;
}
public void setPoint1(Point point1){
this.point1 = point1;
}
public void setPoint2(Point point2){
this.point2 = point2;
}
public String getColor(){
return this.color;
}
public void setColor(String color){
this.color = color;
}
public double getDistance(){
return Math.sqrt(Math.pow(this.point1.getx()-this.point2.getx(),2)+Math.pow(this.point1.gety()-this.point2.gety(),2));
}
public void display(){
Line L = new Line();
L.point1 = this.point1;
L.point2 = this.point2;
System.out.println("The line's color is:"+this.color);
System.out.println("The line's begin point's Coordinate is:");
point1.display();
System.out.println("The line's end point's Coordinate is:");
point2.display();
double l;
l = L.getDistance();
System.out.println("The line's length is:"+String.format("%.2f", l));
}
}
Plane类:
class Plane extends Element{
private String color;
Plane(){
}
Plane(String color){
this.color = color;
}
public String getColor(){
return this.color;
}
public void setColor(String color){
this.color = color;
}
public void display(){
System.out.println("The Plane's color is:"+this.color);
}
}
主类:
class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
if(x1>0&&x1<=200&&y1>0&&y1<=200&&x2>0&&x2<=200&&y2>0&&y2<=200){
Point p1 = new Point();
p1.setx(x1);
p1.sety(y1);
Point p2 = new Point();
p2.setx(x2);
p2.sety(y2);
Line line = new Line();
line.setPoint1(p1);
line.setPoint2(p2);
line.setColor(color);
Plane plane = new Plane();
plane.setColor(color);
Element element;
element = p1;//起点Point
element.display();
element = p2;//终点Point
element.display();
element = line;//线段
element.display();
element = plane;//面
element.display();
}
else{
System.out.println("Wrong Format");
}
}
}
代码分析:
本题使用了继承,通过Element抽象类将多边形的display方法放置在父类中,使各类之间紧密型加强了。同时,本题也提醒我们不能new一个抽象类,但是可以通过声明使用抽象方法。
期中7-3:
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。
- 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为
ArrayList<Element>
类型的对象(若不了解泛型,可以不使用<Element>
) - 增加该类的
add()
方法及remove(int index)
方法,其功能分别为向容器中增加对象及删除第index - 1
(ArrayList中index>=0)个对象 - 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:
- 1:向容器中增加Point对象
- 2:向容器中增加Line对象
- 3:向容器中增加Plane对象
- 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作
- 0:输入结束
- 示例代码如下:
choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://insert Point object into list
...
break;
case 2://insert Line object into list
...
break;
case 3://insert Plane object into list
...
break;
case 4://delete index - 1 object from list
int index = input.nextInt();
...
}
choice = input.nextInt();
}
-
输入结束后,按容器中的对象顺序分别调用每个对象的
display()
方法进行输出。
类图如下所示:
本题运用了容器类对继承进行改写,总体更改不大,较易。
源代码:
Element抽象类:
abstract class Element{
public abstract void display();
}
GeometryObject类:
class GeometryObject{
ArrayList<Element> list = new ArrayList<>();
public GeometryObject(){
}
public void add(Element element){
list.add(element);
}
public void remove(int index){
for(int i=0;i<list.size();i++){
if(i==index-1){
list.remove(i);
break;
}
}
}
public ArrayList<Element> getList(){
return list;
}
}
点类:
class Point extends Element{
private double x;
private double y;
Point(){
}
Point(double x,double y){
this.x = x;
this.y = y;
}
public double getx(){
return this.x;
}
public double gety(){
return this.y;
}
public void setx(double x){
this.x = x;
}
public void sety(double y){
this.y = y;
}
public void display(){
System.out.println("("+String.format("%.2f", this.x)+","+String.format("%.2f", this.y)+")");
}
}
线类:
class Line extends Element{
private Point point1;
private Point point2;
private String color;
Line(){
point1 = new Point();
point2 = new Point();
}
Line(Point p1,Point p2,String color){
this.point1 = p1;
this.point2 = p2;
this.color = color;
}
public Point getPoint1(){
return this.point1;
}
public Point getPoint2(){
return this.point2;
}
public void setPoint1(Point point1){
this.point1 = point1;
}
public void setPoint2(Point point2){
this.point2 = point2;
}
public String getColor(){
return this.color;
}
public void setColor(String color){
this.color = color;
}
public double getDistance(){
return Math.sqrt(Math.pow(this.point1.getx()-this.point2.getx(),2)+Math.pow(this.point1.gety()-this.point2.gety(),2));
}
public void display(){
Line L = new Line();
L.point1 = this.point1;
L.point2 = this.point2;
System.out.println("The line's color is:"+this.color);
System.out.println("The line's begin point's Coordinate is:");
point1.display();
System.out.println("The line's end point's Coordinate is:");
point2.display();
double l;
l = L.getDistance();
System.out.println("The line's length is:"+String.format("%.2f", l));
}
}
Plane类:
class Plane extends Element{
private String color;
Plane(){
}
Plane(String color){
this.color = color;
}
public String getColor(){
return this.color;
}
public void setColor(String color){
this.color = color;
}
public void display(){
System.out.println("The Plane's color is:"+this.color);
}
}
主类:
class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
GeometryObject geometryObject = new GeometryObject();
int choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://insert Point object into list
double x = input.nextDouble();
double y = input.nextDouble();
Point p = new Point();
p.setx(x);
p.sety(y);
geometryObject.add(p);
break;
case 2://insert Line object into list
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
Point p1 = new Point();
p1.setx(x1);
p1.sety(y1);
Point p2 = new Point();
p2.setx(x2);
p2.sety(y2);
Line line = new Line();
line.setPoint1(p1);
line.setPoint2(p2);
line.setColor(color);
geometryObject.add(line);
break;
case 3://insert Plane object into list
Plane plane = new Plane();
color = input.next();
plane.setColor(color);
geometryObject.add(plane);
break;
case 4://delete index - 1 object from list
int index = input.nextInt();
geometryObject.remove(index);
break;
}
choice = input.nextInt();
}
ArrayList<Element> list = geometryObject.getList();
for(Element element:list){
element.display();
}
}
}
代码分析:
本题将继承改写后为容器类,使代码更加清晰,利于多个图形的使用。但是对于ArrayList<Element>类型了解还是不够多不够深入,无法独自顺利地运用ArrayList<Element>类型,后续还需要进一步学习。
踩坑心得:对于多边形类型的题目来说,最好的方法是运用继承,将多边形整合在一起,使用起来会更加方便。同时,在考虑多边形的各种情况时要有序,否则可能会遗漏某些情况。
改进建议:将需要重复使用的计算放入类的方法中,这样代码中不会出现多次大段重复的代码,只需出现明显易懂的调用代码即可。对于输入的存储也需要使用类来整合,这样可以使思路更加清晰。
总结:通过这几次对四边形、五边形的题目,我更加了解了类与方法,也了解到了继承及容器类的使用和便利。在考虑问题的方式上也学会了多方面思考,而不是仅靠自己的猜想只考虑到一般情况。在后续对java的学习中,我需要更加巩固对继承的学习,打好基础,不再像以前那样使用单纯的类和方法。