目录
一、前言
1.难度分析
四边形和五边形题目较难,期中考试照着类图写代码即可,难度不大,建议使用idea,方法get/set属性直接生成,之前我是拒绝使用idea的,但我后面试用了一下,哇,功能是真的强,无需自己手敲,强烈推荐。
2.题量分析
四边形和五边形比起之前的题目题量更多,难度自然不用说,期中考试考察的点是1.类设计 2.继承和多态 3.容器类(List) 只要上课认真点,明白怎么设计,基本上没多大问题,题量也就三个小题。
3.知识点
注意:部分知识可能难以理解,结合代码看效果更佳!
4-7-1 sdut-String-2 识蛟龙号载人深潜,立科技报国志(II)(正则表达式)
正则表达式\D:匹配一个非数字字符,即不是数字。
\D+表示匹配非数字字符串。
至于为什么要加两个\,是因为字符串中的\\会被编译器解释为\。
重要的代码解析如下:
//匹配字符串s中的非数字字符串
//根据匹配的内容将字符串s分成若干个字符串放进数组sp,匹配的内容会被去除
String sp[]=s.split("\\D+");
//需要注意的是若字符串s第一个字符不是数字,sp[0]会为空
//在字符串转化为数字时,需要先判断是否为空值
if(!i.equals(""))
4-7-2 点线形系列4-凸四边形的计算
1.判断是否是四边形、平行四边形
四边形:四个点不重合,四条边不重合,不能构成“漏斗”,即线段不能相交
平行四边形:在四边形的基础上,两组对边相等/一组对边平行且相等
2.判断是否是菱形、矩形、正方形
菱形:是平行四边形且一组邻边相等
矩形:是平行四边形且一组邻边互相垂直
正方形:是菱形且一组邻边互相垂直
3.判断是凹四边形还是凸四边形,获取面积
凹四边形:是四边形且两条对角线与另外4个点在两侧/面积法
凸四边形:不是凹四边形/面积法
面积:用面积法求,即四点相连,任意三点构成的三角形面积,可以观察凹凸四边形之间的关系自行摸索
4.输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积
四边形能构成三角形:
只有一个点重合或在三角形边上,其余三个点构成三角形。
交点个数0:
四边形四个点任意两个点构成的线段与直线均没有交点,即四边形的四个点均在直线同一侧
交点个数1:四边形一点在直线上,其余三点在直线同一侧
交点个数2:除了交点个数0,1情况外
分割面积:
暴力破解,列出所有情况,先求出分割的三角形面积,再用总面积相减。
5-7-1 点线形系列5-凸五边形的计算-1
1.判断是否是五边形:
点不重合,边不重合,点不在边上,不是“漏斗”
2.判断是凹五边形还是凸五边形:
每个点都连线,形成三个三角形,三个三角形面积相加得到总的面积,五个点就有五个总面积,两两比较,若相等为(注意精度)凸五边形,否则为凹五边形。也可以用这种方法求凸五边形面积。
3.输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积:
五边形下降为四边形:只有一点重合/在边上,且剩余四点能构成四边形
五边形下降为三角形:只有两点重合/在边上,且剩余三点能构成三角形
交点个数 0:五个点均在直线同一侧
交点个数 1:一个点在直线上,其余四个点均在直线同一侧
交点个数 2:以上情况除外
分割两部分的面积:
五边形也是暴力破解,方法和四边形一样,都是把所有情况全列出来,四边形和三角形调用之前分割方法即可
5-7-2 点线形系列5-凸五边形的计算-2
4.前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出六种关系的其中一种:
1、分离(完全无重合点):遍历五个点,获得点与多边形的两个点组成的三角形面积之和,再计算两多边形交点个数,如果面积相等,点在多边形内,或者有交点,返回不是分离,遍历完五个点之后,返回是分离。
2、连接(只有一个点或一条边重合):获得两个多边形相交的点列表(List,去掉重复点),如果点数为1或者2,返回是连接
3、完全重合:先判断两个多边形是否为同类,如三角形对三角形,再判断两个多边形的面积是否相等,相等即为重合
4、被包含:与包含一样的方法,将两个多边形对调即可。
5、交错:其余情况除外
6、包含:前提不是多边形重合,遍历五个点获得点与多边形的两个点组成的三角形面积之和,如果面积不相等,点在多边形外,返回不是包含,遍历完五个点之后,返回是包含。
二、设计与分析
在作代码分析前,由于第一次博客已经放出:点,直线,三角形类,虽然进行了驼峰命名和部分bug优化,但总体不变,因此以下只将线段类,四边形类,五边形类放置如下,以避免过长的代码冗余,个人建议先将类方法和Main分别放进编辑器,按住Ctrl键后将鼠标移至Main的方法引用,可查询相应的方法。以下并非提交的PTA源码,因提交后优化了部分代码,但大体上是不变的。
如果不需要查看类代码,建议点击跳过
线段类:
public class Segment {//线段
Point a,b;
Segment(Point inp1,Point inp2){
this.a=new Point(inp1);
this.b=new Point(inp2);
}
Segment(String s, int i, int j){
this.a=new Point(s,i);
this.b=new Point(s,j);
}
Segment(Segment ab){
this.a=new Point(ab.a);
this.b=new Point(ab.b);
}
Segment(){
}
//功能:获取线段长度
public double length() {
return a.distance(b);
}
//功能:判断点是否在线段上
public boolean isPointOnSegment(Point p) {
if(Math.abs(p.distance(a)+p.distance(b)-this.length())<1e-6)
return true;
return false;
}
//功能:转化为直线
public Line changeToLine() {
Line l = new Line(this.a,this.b);
return l;
}
//功能:判断两条线段是否相交
public boolean isInterset(Segment s) {
Line l1 = new Line(this.a,this.b);
Line l2 = new Line(s.a,s.b);
if(l1.isInterset(s.a, s.b)&&l2.isInterset(this.a, this.b))
return true;
return false;
}
}
四边形类:
import java.util.Arrays;
public class Quadrilateral {
Point a;
Point b;
Point c;
Point d;
Segment ab;
Segment bc;
Segment cd;
Segment ad;
Triangle abc;
Triangle acd;
Triangle abd;
Triangle bcd;
Quadrilateral(Point ia,Point ib,Point ic,Point id){
this.a = ia;
this.b = ib;
this.c = ic;
this.d = id;
this.ab = new Segment (ia,ib);
this.bc = new Segment (ib,ic);
this.cd = new Segment (ic,id);
this.ad = new Segment (ia,id);
abc=new Triangle(ia,ib,ic);
acd=new Triangle(ia,ic,id);
abd=new Triangle(ia,ib,id);
bcd=new Triangle(ib,ic,id);
}
/*
* 输入:原始点的字符串,字符串的四个点索引值,如第一个点索引值为1 String,int
* 输出:
* 功能:根据字符串获取四边形的四点和四边
*/
Quadrilateral(String s, int i, int j, int k, int l){
this.a=new Point(s,i);
this.b=new Point(s,j);
this.c=new Point(s,k);
this.d=new Point(s,l);
this.ab=new Segment(this.a,this.b);
this.bc=new Segment(this.b,this.c);
this.cd=new Segment(this.c,this.d);
this.ad=new Segment(this.a,this.d);
abc=new Triangle(this.a,this.b,this.c);
acd=new Triangle(this.a,this.c,this.d);
abd=new Triangle(this.a,this.b,this.d);
bcd=new Triangle(this.b,this.c,this.d);
}
Quadrilateral(Quadrilateral abcd){
this.a=abcd.a;
this.b=abcd.b;
this.c=abcd.c;
this.d=abcd.d;
this.ab=abcd.ab;
this.bc=abcd.bc;
this.cd=abcd.cd;
this.ad=abcd.ad;
abc=abcd.abc;
acd=abcd.acd;
abd=abcd.abd;
bcd=abcd.bcd;
}
Quadrilateral(){
}
/*
* 输入:
* 输出:boolean
* 功能:判断四个点是否存在重合
*/
public boolean pointCoi() {
if(this.a.isCoincident(this.b)||this.a.isCoincident(this.c)||this.a.isCoincident(this.d)||
this.b.isCoincident(this.c)||this.b.isCoincident(this.d)||this.c.isCoincident(this.d))
return true;
return false;
}
/*
* 输入:
* 输出:boolean
* 功能:判断是否能构成四边形
*/
public boolean isQuadrilateral() {
Line ab=new Line(this.a,this.b);
Line cd=new Line(this.c,this.d);
Line bc=new Line(this.b,this.c);
Line ad=new Line(this.a,this.d);
if(this.pointCoi()||ab.isInterset(this.c, this.d)&&cd.isInterset(this.a, this.b)
||bc.isInterset(this.a, this.d)&&ad.isInterset(this.b, this.c)
||ab.isSameLine(bc)||bc.isSameLine(cd)||cd.isSameLine(ad)||ad.isSameLine(ab))
return false;//case 9:第一个“漏斗”,ab和cd相交;case 15:第二个“漏斗”,ad和bc相交
return true;
}
/*
* 输入:point
* 输出:boolean
* 功能:判断点是否在四边形边上
*/
public boolean isPointOnSide (Point a) {
if(this.ab.isPointOnSegment(a)||this.bc.isPointOnSegment(a)||this.cd.isPointOnSegment(a)||this.ad.isPointOnSegment(a))//判断点a是否在三角形线上
return true;
return false;
}
/*
* 输入:无
* 输出:无
* 功能:判断是否为平行四边形
*/
public boolean isParallelogram() {//是四边形且两组对边相等
Line ab=new Line(this.a,this.b);
Line cd=new Line(this.c,this.d);
if(this.isQuadrilateral()&&this.a.distance(this.b)==this.c.distance(this.d)
&&ab.isParallel(cd))
return true;
return false;
}
/*
* 输入:无
* 输出:无
* 功能:判断是否为菱形
*/
public boolean isLozenge() {//是平行四边形且一组邻边相等
if(this.isParallelogram()&&this.ab.length()==this.bc.length())
return true;
return false;
}
/*
* 输入:无
* 输出:无
* 功能:判断是否为矩形
*/
public boolean isRectangle() {//是平行四边形且一组邻边互相垂直
Line ab=new Line(this.a,this.b);
Line ad=new Line(this.a,this.d);
if(this.isParallelogram()&&ab.isVertical(ad))
return true;
return false;
}
/*
* 输入:无
* 输出:无
* 功能:判断是否为正方形
*/
public boolean isSquare() {//是菱形且一组邻边互相垂直
Line ab=new Line(this.a,this.b);
Line ad=new Line(this.a,this.d);
if(this.isLozenge()&&ab.isVertical(ad))
return true;
return false;
}
/*
* 输入:无
* 输出:无
* 功能:判断是否为凸四边形
*/
public boolean isConvexQuadrilateral() {//是四边形且两条对角线与另外4个点在两侧
Line ac=new Line(this.a, this.c);
Line bd=new Line(this.b, this.d);;
if(this.isQuadrilateral()&&ac.isInterset(this.b, this.d)&&bd.isInterset(this.a, this.c))
return true;
return false;
}
/*
* 输入:无
* 输出:周长 double
* 功能:获得四边形周长
*/
public double getPerimeter() {//是四边形且两条对角线与另外4个点在两侧
return Common.round(this.a.distance(this.b)+this.b.distance(this.c)+this.c.distance(this.d)+this.d.distance(this.a),3);
}
/*
* 输入:无
* 输出:面积 double
* 功能:获得四边形面积
*/
public double getArea() {
if(this.isConvexQuadrilateral()) {//凸四边形
return Common.round(this.abc.getArea()+this.acd.getArea(), 3);
}else {
if(this.abc.getArea()+this.acd.getArea()<this.abd.getArea()+this.bcd.getArea())
return Common.round(this.abc.getArea()+this.acd.getArea(), 3);
else
return Common.round(this.abd.getArea()+this.bcd.getArea(), 3);
}
}
/*
* 输入:无
* 输出:boolean
* 功能:判断能否构成三角形
*/
public boolean canFormTriangle() {
Line ab=new Line(this.a,this.b);
Line ad=new Line(this.a,this.d);
Line bc=new Line(this.b,this.c);
Line cd=new Line(this.c,this.d);
if((this.a.isCoincident(this.b)||this.a.isCoincident(this.c)||this.a.isCoincident(this.d))&&this.bcd.isLegalForm())//只有一个点重合
return true;
if((this.b.isCoincident(this.a)||this.b.isCoincident(this.c)||this.b.isCoincident(this.d))&&this.acd.isLegalForm())//只有一个点重合
return true;
if((this.c.isCoincident(this.a)||this.c.isCoincident(this.b)||this.c.isCoincident(this.d))&&this.abd.isLegalForm())//只有一个点重合
return true;
if((this.d.isCoincident(this.a)||this.d.isCoincident(this.b)||this.d.isCoincident(this.c))&&this.abc.isLegalForm())//只有一个点重合
return true;
if(ab.isSameLine(ad)&&Math.abs(this.ab.length()+this.ad.length()-this.b.distance(this.d))<1e-6&&this.bcd.isLegalForm())
return true;//a点在直线bd上
if(ab.isSameLine(bc)&&Math.abs(this.ab.length()+this.bc.length()-this.a.distance(this.c))<1e-6&&this.acd.isLegalForm())
return true;//b点在直线ac上
if(cd.isSameLine(bc)&&Math.abs(this.bc.length()+this.cd.length()-this.b.distance(this.d))<1e-6&&this.abd.isLegalForm())
return true;//c点在直线bd上
if(cd.isSameLine(ad)&&Math.abs(this.cd.length()+this.ad.length()-this.a.distance(this.c))<1e-6&&this.abc.isLegalForm())
return true;//d点在直线ac上
return false;
}
/*
* 输入:无
* 输出:triangle
* 功能:返回四边形构成的三角形
*/
public Triangle formTriangle() {
Line ab=new Line(this.a,this.b);
Line ad=new Line(this.a,this.d);
Line bc=new Line(this.b,this.c);
Line cd=new Line(this.c,this.d);
if((this.a.isCoincident(this.b)||this.a.isCoincident(this.c)||this.a.isCoincident(this.d))&&this.bcd.isLegalForm())//只有一个点重合
return bcd;
if((this.b.isCoincident(this.a)||this.b.isCoincident(this.c)||this.b.isCoincident(this.d))&&this.acd.isLegalForm())//只有一个点重合
return acd;
if((this.c.isCoincident(this.a)||this.c.isCoincident(this.b)||this.c.isCoincident(this.d))&&this.abd.isLegalForm())//只有一个点重合
return abd;
if((this.d.isCoincident(this.a)||this.d.isCoincident(this.b)||this.d.isCoincident(this.c))&&this.abc.isLegalForm())//只有一个点重合
return abc;
if(ab.isSameLine(ad)&&Math.abs(this.ab.length()+this.ad.length()-this.b.distance(this.d))<1e-6&&this.bcd.isLegalForm())
return bcd;//a点在直线bd上
if(ab.isSameLine(bc)&&Math.abs(this.ab.length()+this.bc.length()-this.a.distance(this.c))<1e-6&&this.acd.isLegalForm())
return acd;//b点在直线ac上
if(cd.isSameLine(bc)&&Math.abs(this.bc.length()+this.cd.length()-this.b.distance(this.d))<1e-6&&this.abd.isLegalForm())
return abd;//c点在直线bd上
if(cd.isSameLine(ad)&&Math.abs(this.cd.length()+this.ad.length()-this.a.distance(this.c))<1e-6&&this.abc.isLegalForm())
return abc;//d点在直线ac上
return bcd;//避免警告,无用
}
/*
* 输入:直线 line
* 输出:交点个数0/1/2 int
* 功能:求直线ab与四边形cdef的交点个数
*/
public int getIntersetionNum(Line ab) {
Point c = this.a;//四边形其中一点
Point d = this.b;
Point e = this.c;
Point f = this.d;
if(ab.isSameSide(c,d)&&ab.isSameSide(c,e)&&ab.isSameSide(c,f)&&ab.isSameSide(d,e)
&&ab.isSameSide(d,f)&&ab.isSameSide(e,f))//四边形四个点任意两个点构成的线段与线段ab均没有交点,即四边形的四个点均在线段ab同一侧
return 0;
if(ab.isPointOnLine(c)||ab.isPointOnLine(d)||ab.isPointOnLine(e)||ab.isPointOnLine(f)){//直线过四边形任一顶点
if(ab.isPointOnLine(c)) {//c点在ab上
if(ab.isSameSide(d,e)&&ab.isSameSide(d,f)&&ab.isSameSide(e,f)) //d,e,f三点在同一侧
return 1;//交点只有一个
else
return 2;//交点有两个,其中一个交点为c点
}
if(ab.isPointOnLine(d)) {
if(ab.isSameSide(c,e)&&ab.isSameSide(c,f)&&ab.isSameSide(e,f)) //c,e,f三点在同一侧
return 1;
else
return 2;
}
if(ab.isPointOnLine(e)) {
if(ab.isSameSide(c,d)&&ab.isSameSide(c,f)&&ab.isSameSide(d,f)) //c,d,f三点在同一侧
return 1;
else
return 2;
}
if(ab.isPointOnLine(f)) {
if(ab.isSameSide(c,d)&&ab.isSameSide(c,e)&&ab.isSameSide(d,e)) //c,d,e三点在同一侧
return 1;
else
return 2;
}
}
return 2;//直线不过四边形的顶点
}
/*
* 输入:直线 line
* 输出:面积数组,从小到大返回 double[]
* 功能:获得直线ab分割四边形cdef后的两个面积
*/
public double[] getDividedArea (Line mn) {
Line ab=new Line(this.a,this.b);
Line bc=new Line(this.b,this.c);
Line cd=new Line(this.c,this.d);
Line ad=new Line(this.a,this.d);
Point inter;
Point inter1;
Point inter2;
double []S=new double[2];
if(mn.isPointOnLine(this.a)||mn.isPointOnLine(this.b)||mn.isPointOnLine(this.c)||mn.isPointOnLine(this.d)){//直线过四边形任一顶点
if(mn.isPointOnLine(this.a)){//a点在mn上
if(mn.isPointOnLine(this.c)){//c点在mn上
if(Math.abs(this.abc.getArea()+this.acd.getArea()-this.getArea())<1e-6){//合适的对角线
S[0]=this.abc.getArea();
}
}else if(mn.isInterset(this.b,this.c)&&mn.isSameSide(this.c,this.d)){//交点在线段bc上且不过cd
inter=mn.getIntersection(bc);
Triangle aib=new Triangle(this.a,inter,this.b);
S[0]=aib.getArea();
}else if(mn.isInterset(this.c,this.d)&&mn.isSameSide(this.b,this.c)) {//交点在线段cd上且不过bc
inter=mn.getIntersection(cd);
Triangle aid=new Triangle(this.a,inter,this.d);
S[0]=aid.getArea();
}
}else if(mn.isPointOnLine(this.b)){//b点在mn上
if(mn.isPointOnLine(this.d)){//d点在mn上
if(Math.abs(this.abd.getArea()+this.bcd.getArea()-this.getArea())<1e-6)//合适的对角线
S[0]=this.abd.getArea();
}else if(mn.isInterset(this.a,this.d)&&mn.isSameSide(this.c,this.d)){//交点在线段ad上且不过cd
inter=mn.getIntersection(ad);
Triangle aib=new Triangle(this.a,inter,this.b);
S[0]=aib.getArea();
}else if(mn.isInterset(this.c,this.d)&&mn.isSameSide(this.a,this.d)) {//交点在线段cd上且不过ad
inter=mn.getIntersection(cd);
Triangle bic=new Triangle(this.b,inter,this.c);
S[0]=bic.getArea();
}
}else if(mn.isPointOnLine(this.c)){//c点在mn上
if(mn.isInterset(this.a,this.d)&&mn.isSameSide(this.a,this.b)){//交点在线段ad上且不过ab
inter=mn.getIntersection(ad);
Triangle cid=new Triangle(this.c,inter,this.d);
S[0]=cid.getArea();
}else if(mn.isInterset(this.a,this.b)&&mn.isSameSide(this.a,this.d)) {//交点在线段ab上且不过ad
inter=mn.getIntersection(ab);
Triangle bic=new Triangle(this.b,inter,this.c);
S[0]=bic.getArea();
}
}else if(mn.isPointOnLine(this.d)){//d点在mn上
if(mn.isInterset(this.b,this.c)&&mn.isSameSide(this.a,this.b)){//交点在线段bc上且不过ab
inter=mn.getIntersection(bc);
Triangle cid=new Triangle(this.c,inter,this.d);
S[0]=cid.getArea();
}else if(mn.isInterset(this.a,this.b)&&mn.isSameSide(this.b,this.c)) {//交点在线段ab上且不过bc
inter=mn.getIntersection(ab);
Triangle aid=new Triangle(this.a,inter,this.d);
S[0]=aid.getArea();
}
}
}else {//直线不过四边形的顶点
if(mn.isSameSide(this.b,this.c)&&mn.isSameSide(this.b,this.d)&&mn.isSameSide(this.c,this.d)){//点b,c,d在同一侧
inter1=mn.getIntersection(ab);
inter2=mn.getIntersection(ad);
Triangle aii=new Triangle(this.a,inter1,inter2);
S[0]=aii.getArea();
}else if(mn.isSameSide(this.a,this.c)&&mn.isSameSide(this.a,this.d)&&mn.isSameSide(this.c,this.d)){//点a,c,d在同一侧
inter1=mn.getIntersection(ab);
inter2=mn.getIntersection(bc);
Triangle bii=new Triangle(this.b,inter1,inter2);
S[0]=bii.getArea();
}else if(mn.isSameSide(this.a,this.b)&&mn.isSameSide(this.a,this.d)&&mn.isSameSide(this.b,this.d)){//点a,b,d在同一侧
inter1=mn.getIntersection(bc);
inter2=mn.getIntersection(cd);
Triangle cii=new Triangle(this.c,inter1,inter2);
S[0]=cii.getArea();
}else if(mn.isSameSide(this.a,this.b)&&mn.isSameSide(this.a,this.c)&&mn.isSameSide(this.b,this.c)){//点a,b,c在同一侧
inter1=mn.getIntersection(ad);
inter2=mn.getIntersection(cd);
Triangle dii=new Triangle(this.d,inter1,inter2);
S[0]=dii.getArea();
}else if(mn.isSameSide(this.a,this.b)&&mn.isSameSide(this.c,this.d)){//点a,b和c,d在直线mn不同侧
inter1=mn.getIntersection(ad);
inter2=mn.getIntersection(bc);
Quadrilateral abii=new Quadrilateral(this.a,this.b,inter1,inter2);
S[0]=abii.getArea();
}else if(mn.isSameSide(this.a,this.d)&&mn.isSameSide(this.b,this.c)){//点a,d和b,c在直线mn不同侧
inter1=mn.getIntersection(ab);
inter2=mn.getIntersection(cd);
Quadrilateral bcii=new Quadrilateral(this.b,this.c,inter1,inter2);
S[0]=bcii.getArea();
}
}
S[1]=this.getArea()-S[0];
//System.out.println(S[0]);
Arrays.sort(S);//升序排列
return S;
}
}
五边形:
import java.util.ArrayList;
import java.util.Arrays;
public class Pentagon {
Point[] pArray;//点数组
Segment[] sArray;//线段数组
Pentagon(Point[] ip){
this.sArray=new Segment[5];
this.pArray=new Point[5];
this.pArray=ip;
for(int i=0;i<this.sArray.length-1;i++) {
this.sArray[i]=new Segment(pArray[i],pArray[i]);
}
}
Pentagon(Point p1,Point p2,Point p3,Point p4,Point p5){
this.sArray=new Segment[5];
this.pArray=new Point[]{p1,p2,p3,p4,p5};
for(int i=0;i<this.sArray.length;i++) {
this.sArray[i]=new Segment(pArray[i],pArray[(i+1)%5]);
}
}
Pentagon(String s, int i, int j, int k, int l, int m){
this.sArray=new Segment[5];
Point p1=new Point(s,i);
Point p2=new Point(s,j);
Point p3=new Point(s,k);
Point p4=new Point(s,l);
Point p5=new Point(s,m);
this.pArray=new Point[]{p1,p2,p3,p4,p5};
for(int a=0;a<this.sArray.length;a++) {
this.sArray[a]=new Segment(pArray[a],pArray[(a+1)%5]);
//System.out.println(this.sArray[a].a.x+","+this.sArray[a].a.y+" "+this.sArray[a].b.x+","+this.sArray[a].b.y);
}
}
Pentagon(Pentagon pen){
this.sArray=new Segment[5];
this.pArray=new Point[5];
this.sArray=pen.sArray;
this.pArray=pen.pArray;
}
Pentagon(){
}
/*
* 输入:
* 输出:boolean
* 功能:判断五个点是否存在重合
*/
public boolean exitPointCoi() {
for(int i=0;i<this.pArray.length-1;i++) {
for(int j=i+1;j<this.pArray.length;j++)
if(this.pArray[i].isCoincident(this.pArray[j]))
return true;
}
return false;
}
/*
* 输入:
* 输出:boolean
* 功能:判断五条边的所在直线是否存在重合
*/
public boolean exitLineCoi() {
Line[] lArray=new Line[5];
lArray=this.getLine();//获得五边形的五条直线
for(int i=0;i<this.pArray.length;i++) {
if(lArray[i].isSameLine(lArray[(i+1)%5]))
return true;
}
return false;
}
/*
* 输入:
* 输出:boolean
* 功能:判断五边形的五个点是否存在点在边上
*/
public boolean exitPointOnSegment() {
for(int i=0;i<this.pArray.length;i++) {//五个点在边上
for(int j=i+1;j<i+4;j++) //除了关联点的另外三条边
if(sArray[j%5].isPointOnSegment(pArray[i]))
return true;
}
return false;
}
/*
* 输入:
* 输出:boolean
* 功能:判断是否存在线段交点,即是否存在边相交(“漏斗”状)
* 优化:布尔数组判断是否已经执行过相关判断。
* 布尔数组的下标对应线段数组sArray的下标(0 0 0 0 0对应ab,bc,cd,de,ae线段):
*/
public boolean exitSegmentIntersection() {
int i,j,length=this.pArray.length;
boolean []judge1=new boolean[length];
boolean []judge2=new boolean[length];
for(i=0;i<length;i++){
judge1[i]=false;
judge2[i]=false;
}
for(i=0;i<length;i++) {//五个点在边上
for(j=i+2;j<i+4;j++) //除了关联点的另外三条边
if(!judge1[j%length]||!judge2[i]) {
judge1[i]=true;
judge2[j%length]=true;
if(sArray[i].isInterset(sArray[j%length]))
return true;
}
}
return false;
}
/*
* 输入:
* 输出:Line[]
* 功能:获得五边形线段的所在直线
*/
public Line[] getLine() {
Line[] lArray=new Line[5];
for(int i=0;i<this.pArray.length;i++) {
// System.out.println(this.sArray[i].a.x+","+this.sArray[i].a.y+""+this.sArray[i].b.x+","+this.sArray[i].b.y);
lArray[i]=this.sArray[i].changeToLine();
}
return lArray;
}
/*
* 输入:
* 输出: boolean
* 功能:判断是否能构成五边形
*/
public boolean isPentagon() {
if(this.exitPointCoi()||this.exitLineCoi()||
this.exitPointOnSegment()||this.exitSegmentIntersection())//点重合,边重合,漏斗
return false;//点重合,边重合,点在边上,漏斗
return true;
}
/*
* 输入:
* 输出:
* 功能:输出五边形的点信息
*/
public void outputPoint() {
System.out.println("五边形的点:");
for(int i=0;i<this.pArray.length;i++)
System.out.println("第"+(i+1)+"个点坐标:("+this.pArray[i].x+","+this.pArray[i].y+")");
}
/*
* 输入:
* 输出:
* 功能:输出五边形的线段信息
*/
public void outputSegment() {
System.out.println("五边形边的顶点:");
for(int i=0;i<this.pArray.length;i++)
System.out.println("第"+(i+1)+"条边的两点坐标:("+this.sArray[i].a.x+","+this.sArray[i].a.y+")"
+" ("+this.sArray[i].b.x+","+this.sArray[i].b.y+") 长度:"+this.sArray[i].length());
}
/*
* 输入:
* 输出:boolean
* 功能:判断是否能构成凸五边形
*/
public boolean isConvexPentagon() {
if(!this.isPentagon())//先判断是不是五边形
return false;
int i,j,length=this.pArray.length;
Triangle []t=new Triangle[length-2];
double []S=new double[length];
for(i=0;i<length;i++) {
for(j=i+1,S[i]=0;j<i+length-1;j++) {
t[j-i-1]=new Triangle(pArray[i],pArray[j%length],pArray[(j+1)%length]);
S[i]+=t[j-i-1].getArea();
}
}
for(i=0;i<length-1;i++) {
for(j=i+1;j<length;j++) {
if(Math.abs(S[i]-S[j])>1e-6)
return false;
}
}
return true;
}
/*
* 输入:
* 输出:double
* 功能:获得五边形周长
*/
public double getPerimeter() {
int i,length=this.pArray.length;
double C;
//this.outputSegment();
for(i=0,C=0;i<length;i++) {
C+=sArray[i].length();
}
return C;
}
/*
* 输入:
* 输出:double
* 功能:获得凸五边形面积
*/
public double getConvexArea() {
int j,length=this.pArray.length;
Triangle []t=new Triangle[length-2];
double S=0;
for(j=1;j<length-1;j++) {
t[j-1]=new Triangle(pArray[0],pArray[j%length],pArray[(j+1)%length]);
S+=t[j-1].getArea();
}
return S;
}
/*
* 输入:无
* 输出:boolean
* 功能:判断能否构成四边形
*/
public boolean canFormQuadrilateral() {
int length=this.pArray.length,i,j,coiNum;
Line[] lArray=new Line[length];//
Quadrilateral qua;
for(i=0;i<length;i++)
lArray[i]=new Line(sArray[i]);
for(i=0;i<length;i++) {//第i点重合
for(j=i+1,coiNum=0;j<i+5;j++) {
if(this.pArray[i].isCoincident(this.pArray[j%length]))
coiNum++;
}
qua=new Quadrilateral(this.pArray[(i+1)%length],this.pArray[(i+2)%length],this.pArray[(i+3)%length],this.pArray[(i+4)%length]);
if(coiNum==1&&qua.isQuadrilateral())//只有一个点重合且构成四边形
return true;
if(lArray[i].isSameLine(lArray[(i+length-1)%length])&&Math.abs(sArray[i].length()+sArray[(i+length-1)%length].length()
-this.pArray[(i+1)%length].distance(this.pArray[(i+4)%length]))<1e-6&&qua.isQuadrilateral()) {
return true;//点在边上
}
}
return false;
}
/*
* 输入:无
* 输出:Quadrilateral
* 功能:返回四边形,前提是能构成四边形
*/
public Quadrilateral returnQuadrilateral() {
int length=this.pArray.length,i,j,coiNum;
Line[] lArray=new Line[length];
Quadrilateral qua=new Quadrilateral();
for(i=0;i<length;i++)
lArray[i]=new Line(sArray[i]);
for(i=0;i<length;i++) {//第i点重合
for(j=i+1,coiNum=0;j<i+5;j++) {
if(this.pArray[i].isCoincident(this.pArray[j%length]))
coiNum++;
}
qua=new Quadrilateral(this.pArray[(i+1)%length],this.pArray[(i+2)%length],this.pArray[(i+3)%length],this.pArray[(i+4)%length]);
if(coiNum==1&&qua.isQuadrilateral())//只有一个点重合且构成四边形
return qua;
if(lArray[i].isSameLine(lArray[(i+length-1)%length])&&Math.abs(sArray[i].length()+sArray[(i+length-1)%length].length()
-this.pArray[(i+1)%length].distance(this.pArray[(i+4)%length]))<1e-6&&qua.isQuadrilateral()) {
return qua;//点在边上
}
}
return qua;//避免警告,无意义
}
/*
* 输入:无
* 输出:boolean
* 功能:判断能否构成三角形
*/
public boolean canFormTriangle() {
int length=this.pArray.length,i,j,k,coiNum,n;
Line[] lArray=new Line[length];
Quadrilateral qua;
Triangle tri=new Triangle();
Segment s1;
Segment s2;
Segment s3;
Segment s4;
Segment s;
Segment s0;
Line line1;
Line line2;
Point []p=new Point[3];
for(i=0;i<length;i++)
lArray[i]=new Line(sArray[i]);
for(i=0;i<length;i++) {//第i点重合
for(j=i+1,coiNum=0;j<i+5;j++) {
if(this.pArray[i].isCoincident(this.pArray[j%length]))
coiNum++;
}
qua=new Quadrilateral(this.pArray[(i+1)%length],this.pArray[(i+2)%length],this.pArray[(i+3)%length],this.pArray[(i+4)%length]);
if(coiNum==2&&qua.canFormTriangle())//两点重合且能构成三角形
return true;
}
for(i=0;i<length-1;i++) {//两点在边上
line1=new Line(this.pArray[(i+1)%length],this.pArray[(i+4)%length]);
s1=new Segment(this.pArray[i],this.pArray[(i+1)%length]);
s2=new Segment(this.pArray[i],this.pArray[(i+4)%length]);
s=new Segment(this.pArray[(i+1)%length],this.pArray[(i+4)%length]);
for(j=i+1;j<length;j++) {
line2=new Line(this.pArray[(j+1)%length],this.pArray[(j+4)%length]);
s3=new Segment(this.pArray[j],this.pArray[(j+1)%length]);
s4=new Segment(this.pArray[j],this.pArray[(j+4)%length]);
s0=new Segment(this.pArray[(j+1)%length],this.pArray[(j+4)%length]);
if(line1.isPointOnLine(this.pArray[i])&&Math.abs(s1.length()+s2.length()-s.length())<1e-6
&&line2.isPointOnLine(this.pArray[j])&&Math.abs(s3.length()+s4.length()-s0.length())<1e-6) {//点在边上
for(k=0,n=0;k<length;k++) {//获得除了两个在线上的点外的三个点
if(pArray[k]!=pArray[i]&&pArray[k]!=pArray[j]) {
p[n]=pArray[k];
n++;
}
}
tri=new Triangle(p[0],p[1],p[2]);
if(tri.isLegalForm())
return true;
}
}
}
return false;
}
/*
* 输入:无
* 输出:Triangle
* 功能:返回三角形,前提是能构成三角形
*/
public Triangle returnTriangle() {
int length=this.pArray.length,i,j,k,coiNum,n;
Line[] lArray=new Line[length];
Quadrilateral qua;
Triangle tri=new Triangle();
Segment s1;
Segment s2;
Segment s3;
Segment s4;
Segment s;
Segment s0;
Line line1;
Line line2;
Point []p=new Point[3];
for(i=0;i<length;i++)
lArray[i]=new Line(sArray[i]);
for(i=0;i<length;i++) {//第i点重合
for(j=i+1,coiNum=0;j<i+5;j++) {
if(this.pArray[i].isCoincident(this.pArray[j%length]))
coiNum++;
}
qua=new Quadrilateral(this.pArray[(i+1)%length],this.pArray[(i+2)%length],this.pArray[(i+3)%length],this.pArray[(i+4)%length]);
if(coiNum==2&&qua.canFormTriangle())//两点重合且能构成三角形
return qua.formTriangle();
}
for(i=0;i<length-1;i++) {//两点在边上
line1=new Line(this.pArray[(i+1)%length],this.pArray[(i+4)%length]);
s1=new Segment(this.pArray[i],this.pArray[(i+1)%length]);
s2=new Segment(this.pArray[i],this.pArray[(i+4)%length]);
s=new Segment(this.pArray[(i+1)%length],this.pArray[(i+4)%length]);
for(j=i+1;j<length;j++) {
line2=new Line(this.pArray[(j+1)%length],this.pArray[(j+4)%length]);
s3=new Segment(this.pArray[j],this.pArray[(j+1)%length]);
s4=new Segment(this.pArray[j],this.pArray[(j+4)%length]);
s0=new Segment(this.pArray[(j+1)%length],this.pArray[(j+4)%length]);
if(line1.isPointOnLine(this.pArray[i])&&Math.abs(s1.length()+s2.length()-s.length())<1e-6
&&line2.isPointOnLine(this.pArray[j])&&Math.abs(s3.length()+s4.length()-s0.length())<1e-6) {//点在边上
for(k=0,n=0;k<length;k++) {//获得除了两个在线上的点外的三个点
if(pArray[k]!=pArray[i]&&pArray[k]!=pArray[j]) {
p[n]=pArray[k];
n++;
}
}
tri=new Triangle(p[0],p[1],p[2]);
return tri;
}
}
}
return tri;//避免警告,无意义
}
/*
* 输入:
* 输出:boolean
* 功能:判断点是否在五边形的一条边线上
*/
public boolean isPointOnSide(Point p) {
for(int i=0;i<this.pArray.length;i++) {
if(this.sArray[i].isPointOnSegment(p))
return true;
}
return false;
}
/*
* 输入:
* 输出:boolean
* 功能:判断点是否在五边形的内部(包括边上)
*/
public boolean isPointInside(Point p) {
int j,length=pArray.length;
double S;
Triangle tri;
for(j=0,S=0;j<length;j++) {//获得点与多边形的两个点组成的三角形面积
tri=new Triangle(p,sArray[j].a,sArray[j].b);
S+=tri.getArea();
}
if(Math.abs(S-this.getConvexArea())<1e-6) {//面积相等,点在多边形内
return true;
}
return false;
}
/*
* 输入:
* 输出:boolean
* 功能:判断直线是否与五边形的一条边线重合
*/
public boolean isLineOnSide(Line line) {
for(int i=0;i<this.pArray.length;i++) {
Line side=this.sArray[i].changeToLine();
if(line.isSameLine(side)&&!this.sArray[i].a.isCoincident(this.sArray[i].b))
return true;
}
return false;
}
/*
* 输入:直线 line
* 输出:交点个数0/1/2 int
* 功能:求直线与五边形的交点个数
*/
public int getIntersetionNum(Line line) {
int i,j,length=this.pArray.length,sum=0;
for(i=1;i<length;i++) {
if(line.isSameSide(this.pArray[0],this.pArray[i]))
sum++;
}
if(sum==length-1)//第一个点和其余四个点均在直线同一侧
return 0;
for(i=0;i<length;i++) {//遍历五个点
if(line.isPointOnLine(this.pArray[i])) {//其中一点在边上
for(j=i+2,sum=0;j<i+length;j++) {
if(line.isSameSide(this.pArray[(i+1)%5],this.pArray[j%5]))
sum++;
}
if(sum==length-2)
return 1;
else
return 2;
}
}
return 2;//直线不过五边形的顶点
}
//----------------------------------------------------------
/* 输入:直线 line
* 输出:面积数组,从小到大返回 double[]
* 功能:获得直线分割五边形后的两个面积
*/
public double[] getDividedArea (Line line) {
Triangle tri;
Quadrilateral qua;
int i,length=this.pArray.length;
double []S=new double[2];
Point inter;
Point inter1;
Point inter2;
Line side,side1,side2;
for(i=0;i<length;i++) {
if(line.isPointOnLine(this.pArray[i])) {//第一个点在边上
if(line.isPointOnLine(this.pArray[(i+2)%length])) {//第三个点在边上
tri=new Triangle(this.pArray[i],this.pArray[(i+1)%length],this.pArray[(i+2)%length]);
S[0]=tri.getArea();
}else if(line.isPointOnLine(this.pArray[(i+3)%length])) {//第四个点在边上
tri=new Triangle(this.pArray[i],this.pArray[(i+3)%length],this.pArray[(i+4)%length]);
S[0]=tri.getArea();
}else if(line.isInterset(this.pArray[(i+1)%length], this.pArray[(i+2)%length])) {//交点在第二个点和第三个点之间
side=this.sArray[(i+1)%length].changeToLine();
inter=line.getIntersection(side);
tri=new Triangle(this.pArray[i], inter,this.pArray[(i+1)%length]);
S[0]=tri.getArea();
}else if(line.isInterset(this.pArray[(i+2)%length], this.pArray[(i+3)%length])) {//交点在第三个点和第四个点之间
side=this.sArray[(i+2)%length].changeToLine();
inter=line.getIntersection(side);
qua=new Quadrilateral(this.pArray[i],this.pArray[(i+1)%length],this.pArray[(i+2)%length], inter);
S[0]=qua.getArea();
}else if(line.isInterset(this.pArray[(i+3)%length], this.pArray[(i+4)%length])) {//交点在第四个点和第五个点之间
side=this.sArray[(i+3)%length].changeToLine();
inter=line.getIntersection(side);
tri=new Triangle(this.pArray[i], inter,this.pArray[(i+4)%length]);
S[0]=tri.getArea();
}
}else {//点不在边上
if(line.isInterset(pArray[i], pArray[(i+1)%length])&&line.isInterset(pArray[i], pArray[(i+2)%length])//第一个点与其余四个点不在同一侧
&&line.isInterset(pArray[i], pArray[(i+3)%length])&&line.isInterset(pArray[i], pArray[(i+4)%length])) {
side1=this.sArray[i].changeToLine();
side2=this.sArray[(i+4)%length].changeToLine();
inter1=line.getIntersection(side1);
inter2=line.getIntersection(side2);
tri=new Triangle(pArray[i],inter1,inter2);
S[0]=tri.getArea();
}else if(line.isSameSide(sArray[i].a, sArray[i].b)){//第一个点和第二个点在同一侧,与两个交点形成四边形
side1=this.sArray[(i+1)%length].changeToLine();
side2=this.sArray[(i+4)%length].changeToLine();
inter1=line.getIntersection(side1);
inter2=line.getIntersection(side2);
qua=new Quadrilateral(this.pArray[i],this.pArray[(i+1)%length],inter1, inter2);
S[0]=qua.getArea();
}
}
}
S[1]=this.getConvexArea()-S[0];
//System.out.println(S[0]);
Arrays.sort(S);//升序排列
return S;
}
/*
* 输入:Pentagon
* 输出:boolean
* 功能:判断多边形与另一个多边形是否重合(这里的多边形指五边形/四边形/三角形)
*/
public boolean isPolygonsCoincide(Pentagon pen) {
if((this.isPentagon()&&!pen.isPentagon())||(this.canFormQuadrilateral()&&!pen.canFormQuadrilateral())
||(this.canFormTriangle()&&!pen.canFormTriangle()))
return false;
double S1=0,S2=0,S=0;
Quadrilateral qua1,qua2;
Triangle tri1,tri2;
S=this.getCoincidentArea(pen);
if(this.isPentagon()&&pen.isPentagon()) {
S1=this.getConvexArea();
S2=pen.getConvexArea();
}
if(this.canFormQuadrilateral()&&pen.canFormQuadrilateral()) {
qua1=this.returnQuadrilateral();
qua2=pen.returnQuadrilateral();
S1=qua1.getArea();
S2=qua2.getArea();
}
if(this.canFormTriangle()&&pen.canFormTriangle()) {
tri1=this.returnTriangle();
tri2=pen.returnTriangle();
S1=tri1.getArea();
S2=tri2.getArea();
}
if(Math.abs(S-S1)<1e-6&&Math.abs(S-S2)<1e-6)
return true;
return false;
//if(S==S1&&S==S2)
}
/*
* 输入:Pentagon
* 输出:boolean
* 功能:判断多边形是否包含另一个多边形(这里的多边形指五边形/四边形/三角形)
*/
public boolean isPolygonsContain(Pentagon pen) {
double S;
int i,j,length=pArray.length;
Triangle tri;
if(!this.isPolygonsCoincide(pen)) {//不是多边形重合
for(i=0;i<length;i++) {//遍历五个点
for(j=0,S=0;j<length;j++) {//获得点与多边形的两个点组成的三角形面积
tri=new Triangle(pen.pArray[i],sArray[j].a,sArray[j].b);
S+=tri.getArea();
}
if(Math.abs(S-this.getConvexArea())>1e-6) {//面积不相等,点在多边形外
return false;
}
}
}
return true;
}
/*
* 输入:Pentagon
* 输出:boolean
* 功能:判断多边形是否被另一个多边形包含(这里的多边形指五边形/四边形/三角形)
*/
public boolean isPolygonsIncluded(Pentagon pen) {
double S;
int i,j,length=pArray.length;
Triangle tri;
if(!this.isPolygonsCoincide(pen)) {//不是多边形重合
for(i=0;i<length;i++) {//遍历五个点
for(j=0,S=0;j<length;j++) {//获得点与多边形的两个点组成的三角形面积
tri=new Triangle(this.pArray[i],pen.sArray[j].a,pen.sArray[j].b);
S+=tri.getArea();
}
if(Math.abs(S-pen.getConvexArea())>1e-6) {//面积不相等,点在多边形外
return false;
}
}
}
return true;
}
/*
* 输入:Pentagon
* 输出:boolean
* 功能:判断多边形是否与另一个多边形分离(这里的多边形指五边形/四边形/三角形)
*/
public boolean isPolygonsSeparate(Pentagon pen) {
double S;
int i,j,length=pArray.length,sum=0;
Triangle tri;
for(i=0;i<length;i++) {//遍历五个点
for(j=0,S=0;j<length;j++) {//获得点与多边形的两个点组成的三角形面积
tri=new Triangle(this.pArray[i],pen.sArray[j].a,pen.sArray[j].b);
S+=tri.getArea();
if(pen.sArray[i].isInterset(this.sArray[j]))
sum++;//交点个数
}
if(Math.abs(S-pen.getConvexArea())<1e-6||sum!=0) {
return false;//面积相等,点在多边形内,且有交点
}
}
return true;//所有点都在多边形外
}
/*
* 输入:Pentagon
* 输出:ArrayList<Point>
* 功能:获得两个多边形相交的点列表
*/
public ArrayList<Point> getIntersectPointList(Pentagon pen) {
ArrayList<Point> list1=new ArrayList<Point>();
ArrayList<Point> list2=new ArrayList<Point>();
ArrayList<Point> list3=new ArrayList<Point>();
ArrayList<Point> list0=new ArrayList<Point>();
double S;
int i,j,length=pArray.length,flag;
Triangle tri;
for(i=0;i<length;i++) {
for(j=0,S=0;j<length;j++) {//获得点与多边形的两个点组成的三角形面积
tri=new Triangle(this.pArray[i],pen.sArray[j].a,pen.sArray[j].b);
S+=tri.getArea();
}
if(Math.abs(S-pen.getConvexArea())<1e-6) {//面积相等,点在多边形内
list1.add(this.pArray[i]);//存放this在pen内部(包括线上)的点
}
//System.out.println(S);
}
for(i=0;i<length;i++) {
for(j=0,S=0;j<length;j++) {//获得点与多边形的两个点组成的三角形面积
tri=new Triangle(pen.pArray[i],this.sArray[j].a,this.sArray[j].b);
S+=tri.getArea();
}
if(Math.abs(S-this.getConvexArea())<1e-6) {//面积相等,点在多边形内
list2.add(pen.pArray[i]);//存放pen在this内部(包括线上)的点
}
}
for(i=0;i<length;i++) {
for(j=0;j<length;j++) {
if(this.sArray[i].isInterset(pen.sArray[j])) {//线段相交
Line line1=this.sArray[i].changeToLine();
Line line2=pen.sArray[j].changeToLine();
Point inter=line1.getIntersection(line2);
list3.add(inter);//存放pen与this的交点
}
}
}
// System.out.println(list1.size());
// System.out.println(list2.size());
// System.out.println(list3.size());
//4:0,1 0,2 -1,2 -2,2 -2,1 0,0 0,3 1,3 2,3 2,0
//System.out.println(list1.get(0).x+","+list1.get(0).y+" "+list1.get(1).x+","+list1.get(1).y+" ");
for(i=0;i<list1.size();i++) {
for(j=0,flag=0;j<list0.size();j++) {
if(list1.get(i).isCoincident(list0.get(j)))
flag=1;
}
if(flag==0)
list0.add(list1.get(i));
}
for(i=0;i<list2.size();i++) {
for(j=0,flag=0;j<list0.size();j++) {
if(list2.get(i).isCoincident(list0.get(j)))
flag=1;
}
if(flag==0)
list0.add(list2.get(i));
}
for(i=0;i<list3.size();i++) {
for(j=0,flag=0;j<list0.size();j++) {
if(list3.get(i).isCoincident(list0.get(j)))
flag=1;
}
if(flag==0)
list0.add(list3.get(i));
}
// System.out.println(list0.size());
// for(i=0;i<list0.size();i++)
// System.out.println(list0.get(i).x+","+list0.get(i).y+" ");
return list0;
}
/*
* 输入:Pentagon
* 输出:boolean
* 功能:判断多边形是否与另一个多边形连接(点点重合/或边边重合/点在边上)(这里的多边形指五边形/四边形/三角形)
*/
public boolean isPolygonsConnect(Pentagon pen) {
ArrayList<Point> list0=this.getIntersectPointList(pen);
if(list0.size()==1||list0.size()==2)
return true;
return false;
}
/*
* 输入:Pentagon
* 输出:boolean
* 功能:判断多边形是否与另一个多边形交错(这里的多边形指五边形/四边形/三角形)
*/
public boolean isPolygonsInterlace(Pentagon pen) {
if(this.isPolygonsCoincide(pen)||this.isPolygonsContain(pen)||this.isPolygonsIncluded(pen)
||this.isPolygonsSeparate(pen)||this.isPolygonsConnect(pen))//除了以上关系
return false;
return true;
}
/*
* 输入:
* 输出:String
* 功能:判断五边形的类别(五边形/四边形/三角形),输出triangle/quadrilateral/ pentagon/not a polygon字符串
*/
public String outputPolygonCategory() {
if(this.isPentagon()) {
return "pentagon";
}else if(this.canFormQuadrilateral()) {
return "quadrilateral";
}else if(this.canFormTriangle()) {
return "triangle";
}
return "not a polygon";
}
/*
* 输入:
* 输出:Point
* 功能:输出多边形内点
*/
public Point getCenter() {
double X = 0, Y = 0;
for (int i = 0; i < pArray.length; i++) {
X += pArray[i].x;
Y += pArray[i].y;
}
// 返回内点
Point center = new Point(X / pArray.length,Y / pArray.length);
return center;
}
/*
* 输入:
* 输出:double
* 功能:得到两个多边形(五边形)的重合面积
*/
public double getCoincidentArea(Pentagon pen) {
ArrayList<Point> list0=this.getIntersectPointList(pen);
//System.out.println(list0.size());
Point center = this.getCenter();
Point tmp ;
for (int i = 1; i < list0.size(); i++) {// 冒泡排序
for (int j = 0; j < list0.size() - i; j++) {
// 判断点A与点B之间的方向
if ((list0.get(j).x - center.x) * (list0.get(j+1).y - center.y) - (list0.get(j+1).x - center.x) * (list0.get(j).y - center.y)<=0) {
tmp = new Point(list0.get(j));
list0.set(j, list0.get(j+1));
list0.set(j+1, tmp);
}
}
}
Triangle tri;
double S=0;
if(list0.size()<3) {
return 0;
}
for(int i=1;i<list0.size();i++) {//case 21:选项5:两多边形交错,且有超过两个交叉点,用这种方法判断,原因是可能会切出来六边形
tri=new Triangle(list0.get(0),list0.get(i),list0.get((i+1)%list0.size()));
S+=tri.getArea();
}
return S;
}
}
4-7-1 sdut-String-2 识蛟龙号载人深潜,立科技报国志(II)(正则表达式)
源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s=input.nextLine();
while(!s.matches("end")) {
String sp[]=s.split("\\D+");
int sum=0;
for(String i:sp) {
if(!i.equals(""))
sum+=Integer.parseInt(i);
}
System.out.println(sum);
s=input.nextLine();
}
input.close();
}
}
SourceMonitor的生成报表内容:
总体来说,代码比较简单,复杂度不高。
4-7-2 点线形系列4-凸四边形的计算
源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s=input.nextLine();
char ch0=s.charAt(0);
char ch1=s.charAt(1);
s=s.substring(2);
if(ch0<'1'||ch0>'5'||ch1!=':'||!Point.isLegalInput(s,2)){
System.out.print("Wrong Format");
return ;
}
Point a;
Point b;
Line ab;
Triangle xyz;
Quadrilateral abcd;
Quadrilateral cdef;
switch(ch0){
case '1':
if(Point.getPointNum(s)!=4){
System.out.print("wrong number of points");
return ;
}
abcd = new Quadrilateral(s,1,2,3,4);//需要先判断点的个数是否有四个
if(abcd.pointCoi()){//判断四个点是否存在重合
System.out.print("points coincide");
return ;
}
if(abcd.isQuadrilateral()) //是否为四边形
System.out.print("true ");
else
System.out.print("false ");
if(abcd.isParallelogram()) //是否为平行四边形
System.out.print("true");
else
System.out.print("false");
break;
case '2':
if(Point.getPointNum(s)!=4){
System.out.print("wrong number of points");
return ;
}
abcd = new Quadrilateral(s,1,2,3,4);//需要先判断点的个数是否有四个
if(!abcd.isQuadrilateral()) {//是否为四边形,点重合是假的,直接判断是否为四边形即可
System.out.print("not a quadrilateral");
return ;
}
if(abcd.isLozenge())
System.out.print("true ");
else
System.out.print("false ");
if(abcd.isRectangle())
System.out.print("true ");
else
System.out.print("false ");
if(abcd.isSquare())
System.out.print("true");
else
System.out.print("false");
break;
case '3':
if(Point.getPointNum(s)!=4){
System.out.print("wrong number of points");
return ;
}
abcd=new Quadrilateral(s,1,2,3,4);//需要先判断点的个数是否有四个
if(!abcd.isQuadrilateral()) {//是否为四边形,点重合是假的,直接判断是否为四边形即可
System.out.print("not a quadrilateral");
return ;
}
if(abcd.isConvexQuadrilateral())
System.out.print("true ");
else
System.out.print("false ");
System.out.print(abcd.getPerimeter()+" "+abcd.getArea());
break;
case '4':
if(Point.getPointNum(s)!=6){
System.out.print("wrong number of points");
return ;
}
a=new Point(s, 1);
b=new Point(s, 2);
ab=new Line(a, b);
cdef=new Quadrilateral(s,3,4,5,6);//需要先判断点的个数是否有六个
if(a.isCoincident(b)) {//判断两点是否重合
System.out.print("points coincide");
return ;
}
if(!cdef.isQuadrilateral()&&!cdef.canFormTriangle()) {
System.out.print("not a quadrilateral or triangle");
return ;
}
Line CD=cdef.ab.changeToLine();
Line DE=cdef.bc.changeToLine();
Line EF=cdef.cd.changeToLine();
Line CF=cdef.ad.changeToLine();
if(ab.isSameLine(CD)&&!cdef.a.isCoincident(cdef.b)||ab.isSameLine(DE)&&!cdef.c.isCoincident(cdef.b)||ab.isSameLine(EF)&&!cdef.c.isCoincident(cdef.d)||ab.isSameLine(CF)&&!cdef.a.isCoincident(cdef.d)) {//直线与四边形或三角形边线是否重合
System.out.print("The line is coincide with one of the lines");
return ;
}
if(cdef.isQuadrilateral()) {//能构成四边形
if(cdef.getIntersetionNum(ab)==2)
System.out.print("2 "+Common.round(cdef.getDividedArea(ab)[0], 3)+" "+Common.round(cdef.getDividedArea(ab)[1], 3));
else
System.out.print(cdef.getIntersetionNum(ab));
}else if(cdef.canFormTriangle()) {//能构成三角形
xyz=cdef.formTriangle();
if(xyz.getIntersetionNum(ab)==2) {
double []S;
S=xyz.getDividedArea(ab);
System.out.print("2 "+Common.round(S[0], 3)+" "+Common.round(S[1], 3));
}
else
System.out.print(xyz.getIntersetionNum(ab));
}else {//不符合四边形或三角形
System.out.print("not a quadrilateral or triangle");
}
break;
case '5':
if(Point.getPointNum(s)!=5){
System.out.print("wrong number of points");
return ;
}
a=new Point(s, 1);
Quadrilateral bcde;
bcde=new Quadrilateral(s, 2, 3, 4, 5);
Segment bc=new Segment(bcde.a,bcde.b);
Segment be=new Segment(bcde.a,bcde.d);
Segment cd=new Segment(bcde.b,bcde.c);
Segment de=new Segment(bcde.c,bcde.d);
if(bcde.isQuadrilateral()) {//能构成四边形
if(bc.isPointOnSegment(a)||be.isPointOnSegment(a)||cd.isPointOnSegment(a)||de.isPointOnSegment(a)) {
System.out.print("on the quadrilateral");
return ;
}
Triangle abc;
Triangle acd;
Triangle ade;
Triangle abe;
abc=new Triangle(s,1,2,3);
acd=new Triangle(s,1,3,4);
ade=new Triangle(s,1,4,5);
abe=new Triangle(s,1,2,5);
double S1=abc.getArea();
double S2=acd.getArea();
double S3=ade.getArea();
double S4=abe.getArea();
double S=bcde.getArea();
if(S1+S2+S3+S4==S) {
System.out.print("in the quadrilateral");
}else {
System.out.print("outof the quadrilateral");
}
}else if(bcde.canFormTriangle()) {//能构成三角形
xyz=bcde.formTriangle();
Segment xy=new Segment(xyz.a,xyz.b);
Segment xz=new Segment(xyz.a,xyz.c);
Segment yz=new Segment(xyz.b,xyz.c);
if(xy.isPointOnSegment(a)|| xz.isPointOnSegment(a)||yz.isPointOnSegment(a)){//判断点a是否在三角形线上
System.out.print("on the triangle");
return ;
}
Triangle axy=new Triangle();
Triangle ayz=new Triangle();
Triangle axz=new Triangle();
axy.a=a;
axy.b=xyz.a;
axy.c=xyz.b;
ayz.a=a;
ayz.b=xyz.b;
ayz.c=xyz.c;
axz.a=a;
axz.b=xyz.a;
axz.c=xyz.c;
double tS1=axy.getArea();
double tS2=ayz.getArea();
double tS3=axz.getArea();
double tS=xyz.getArea();
if(Math.abs(tS1+tS2+tS3-tS)<1e-12){
System.out.print("in the triangle");
}else {
System.out.print("outof the triangle");
}
}else {
System.out.print("not a quadrilateral or triangle");
return ;
}
}
}
}
SourceMonitor的生成报表内容:
整体复杂度偏高,如平均复杂度达到了13,整体代码还是不合格的,原因大概是没有整合类方法里面冗余的部分代码,继承多边形可以很好地解决。
4-7-3 设计一个银行业务类
源码:
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner input = new Scanner(System.in);
BankBusiness.welcome();
BankBusiness account = new BankBusiness(input.next(),input.next());
account.deposit(input.next(),input.nextDouble());
account.withdraw(input.next(),input.nextDouble());
account.withdraw(input.next(),input.nextDouble());
account.withdraw(input.next(),input.nextDouble());
BankBusiness.welcomeNext();
input.close();
}
}
class BankBusiness {
public static String bankName="中国银行";
private String name;
private String password;
private double balance;
//----------------------------------------------------------
/* 输入:账户名name、密码password String,String
* 输出:
* 功能:构造方法,开通账户
*/
BankBusiness(String name,String password){
this.name=name;
this.password=password;
this.balance=0;
//input.close();
}
//----------------------------------------------------------
/* 输入:无
* 输出:
* 功能:用户到来时显示“中国银行欢迎您的到来!”,其中“中国银行”自动使用bankName的值。
*/
public static void welcome(){
System.out.println(bankName+"欢迎您的到来!");
}
//----------------------------------------------------------
/* 输入:无
* 输出:
* 功能:用户离开时显示“请收好您的证件和物品,欢迎您下次光临!”
*/
public static void welcomeNext(){
System.out.println("请收好您的证件和物品,欢迎您下次光临!");
}
//----------------------------------------------------------
/* 输入:密码password,交易额x String,double
* 输出:
* 功能:用户的存款(deposit)操作
*/
public void deposit(String password,double x){
if(!password.matches(this.password))
System.out.println("您的密码错误!");
else{
this.balance+=x;
System.out.println("您的余额有"+this.balance+"元。");
}
}
//----------------------------------------------------------
/* 输入:密码password,交易额x String,double
* 输出:
* 功能:用户的取款(withdraw)操作
*/
public void withdraw(String password,double x){
if(!password.matches(this.password))
System.out.println("您的密码错误!");
else{//密码正确
if(this.balance<x)
System.out.println("您的余额不足!");
else{
this.balance-=x;
System.out.println("请取走钞票,您的余额还有"+this.balance+"元。");
}
}
}
}
SourceMonitor的生成报表内容:
期中考试 7-1 点与线(类设计)
import java.util.Scanner;
public class Main {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
Point point1=new Point(input.nextDouble(), input.nextDouble());
Point point2=new Point(input.nextDouble(), input.nextDouble());
Line line=new Line(point1,point2, input.next());
if(Check.isLegal(point1.getX())&&Check.isLegal(point1.getY())&&Check.isLegal(point2.getX())&&Check.isLegal(point2.getY())){
line.display();
}else{
System.out.println("Wrong Format");
}
}
}
class Check{
public static boolean isLegal(double x){
if(x>0&&x<=200)
return true;
return false;
}
}
class Line{
private Point point1,point2;
String color;
Line(){
point1=new Point();
point2=new Point();
}
Line(Point point1,Point point2,String color){
this.point1=point1;
this.point2=point2;
this.color=color;
}
public Point getPoint1(){
return point1;
}
public void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getDistance(){
double x1=this.point1.getX();
double x2=this.point2.getX();
double y1=this.point1.getY();
double y2=this.point2.getY();
return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
public void display(){
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();
System.out.println("The line's length is:"+String.format("%.2f",this.getDistance()));//Common.round(getDistance(),2)
}
}
class Point{
private double x,y;
public Point(){
}
public Point(double x,double y){
this.x=x;
this.y=y;
}
public double getX(){
return this.x;
}
public void setX(double x){
this.x=x;
}
public double getY(){
return this.y;
}
public void setY(double y){
this.y=y;
}
public void display(){
System.out.println("("+String.format("%.2f",this.x)+","+String.format("%.2f",this.y)+")");
}
}
SourceMonitor的生成报表内容:
期中考试 7-2 点线面问题重构(继承与多态)
源码:
import java.util.Scanner;
public class Main {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
Point point1=new Point(input.nextDouble(), input.nextDouble());
Point point2=new Point(input.nextDouble(), input.nextDouble());
Line line=new Line(point1,point2, input.next());
Plane plane=new Plane(line.getColor());
Element element;
if(Check.isLegal(point1.getX())&&Check.isLegal(point1.getY())&&Check.isLegal(point2.getX())&&Check.isLegal(point2.getY())){
element = point1;//起点Point
element.display();
element = point2;//终点Point
element.display();
element = line;//线段
element.display();
element = plane;//面
element.display();
}else{
System.out.println("Wrong Format");
}
}
}
abstract class Element{
public abstract void display();
}
class Check{
public static boolean isLegal(double x){
if(x>0&&x<=200)
return true;
return false;
}
}
class Plane extends Element{
private String color;
Plane(){
}
Plane(String color){
this.color=color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void display() {
System.out.println("The Plane's color is:"+this.color);
}
}
class Line extends Element{
private Point point1,point2;
String color;
Line(){
point1=new Point();
point2=new Point();
}
Line(Point point1,Point point2,String color){
this.point1=point1;
this.point2=point2;
this.color=color;
}
public Point getPoint1(){
return point1;
}
public void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getDistance(){
double x1=this.point1.getX();
double x2=this.point2.getX();
double y1=this.point1.getY();
double y2=this.point2.getY();
return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
public void display(){
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();
System.out.println("The line's length is:"+String.format("%.2f",this.getDistance()));
}
}
class Point extends Element{
private double x,y;
public Point(){
}
public Point(double x,double y){
this.x=x;
this.y=y;
}
public double getX(){
return this.x;
}
public void setX(double x){
this.x=x;
}
public double getY(){
return this.y;
}
public void setY(double y){
this.y=y;
}
public void display(){
System.out.println("("+String.format("%.2f",this.x)+","+String.format("%.2f",this.y)+")");
}
}
SourceMonitor的生成报表内容:
期中考试 7-3 点线面问题再重构(容器类)
源码:
import java.util.Scanner;
import java.util.ArrayList;
public class Main {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
Point point;
Point point1;
Point point2;
Line line;
Plane plane;
Element element;
GeometryObject geometryObject = new GeometryObject();
int choice,flag=0;
choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://insert Point object into list
point=new Point(input.nextDouble(), input.nextDouble());
geometryObject.add(point);
if(!Check.isLegal(point.getX())||!Check.isLegal(point.getY()))
flag=1;
break;
case 2://insert Line object into list
point1=new Point(input.nextDouble(), input.nextDouble());
point2=new Point(input.nextDouble(), input.nextDouble());
line=new Line(point1,point2, input.next());
geometryObject.add(line);
if(!Check.isLegal(point1.getX())||!Check.isLegal(point1.getY())||!Check.isLegal(point2.getX())||!Check.isLegal(point2.getY())){
flag=1;
}
break;
case 3://insert Plane object into list
plane=new Plane(input.next());
geometryObject.add(plane);
break;
case 4://delete index - 1 object from list
int index = input.nextInt();
if(index>0&&index<=geometryObject.getList().size())
geometryObject.remove(index-1);
}
choice = input.nextInt();
}
if(flag==1){
System.out.println("Wrong Format");
}else{
for(Element element1:geometryObject.getList()){
element1.display();
}
}
}
}
class GeometryObject{
ArrayList <Element> list=new ArrayList<>();
GeometryObject(){
}
public void add(Element element){
list.add(element);
}
public void remove(int index){
list.remove(index);
}
public ArrayList <Element> getList(){
return this.list;
}
}
abstract class Element{
public abstract void display();
}
class Check{
public static boolean isLegal(double x){
if(x>0&&x<=200)
return true;
return false;
}
}
class Plane extends Element{
private String color;
Plane(){
}
Plane(String color){
this.color=color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void display() {
System.out.println("The Plane's color is:"+this.color);
}
}
class Line extends Element{
private Point point1,point2;
String color;
Line(){
point1=new Point();
point2=new Point();
}
Line(Point point1,Point point2,String color){
this.point1=point1;
this.point2=point2;
this.color=color;
}
public Point getPoint1(){
return point1;
}
public void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getDistance(){
double x1=this.point1.getX();
double x2=this.point2.getX();
double y1=this.point1.getY();
double y2=this.point2.getY();
return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
public void display(){
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();
System.out.println("The line's length is:"+String.format("%.2f",this.getDistance()));//Common.round(getDistance(),2)
}
}
class Point extends Element{
private double x,y;
public Point(){
}
public Point(double x,double y){
this.x=x;
this.y=y;
}
public double getX(){
return this.x;
}
public void setX(double x){
this.x=x;
}
public double getY(){
return this.y;
}
public void setY(double y){
this.y=y;
}
public void display(){
System.out.println("("+String.format("%.2f",this.x)+","+String.format("%.2f",this.y)+")");
}
}
SourceMonitor的生成报表内容:
分析:switch导致最高复杂度偏高,但整体还是合格的。
采坑心得:
1.考虑相等问题的同时,需要判断是否需要考虑精度问题,有很多点是没加精度判断过不去的,精度不能设置太大也不能太小,合适就好,我的话精度1e-6或者1e-12,具体问题具体分析即可。
2.之前的代码在之前的题目过了不代表就没有bug,比如三角形的类方法在三角形的题目上没有测出来,点全过了,但在五边形题目上出bug了,这时就需要返工了,设计方法时尽量多考虑各种各样的情况,设计完之后有时间的可以罗列各种点来测试方法的健全性。
3.由于我三角形,四边形和五边形部分方法是暴力列举情况的,而且没有用到List继承多边形,光是初始化就写了一大堆代码,建议写到四边形就可以写多边形继承了,能让后面写五边形时轻松不少,如果还用暴力的话容易爆PTA内存,写完了,交不了也是白搭,还是要返工改代码。
改进建议
1.可以将输入处理整理成一个类,如DealInput类。
2.建立多边形类,里面放三角形/四边形/五边形/n边形的共同属性和方法,让n边形做子类,继承多边形,这样可以减少不少冗余的代码。
3.List比数组好用很多,还可以作父类的容器,在期中考试第三小题可以深刻体会到。
总结
在这三次大作期间,学到了不少东西,从四边形的痛苦暴力(分割面积),再到五边形的痛苦暴力(还是分割面积),写完前两次意识到应该要写多边形继承,但迟迟没有时间整理代码且当时对继承并不算熟悉运用,再后来到了期中考试,多态的子类继承父类的表示方法让我意识到多态化代码的必要性,这无疑能减少大量冗余代码。
标签:return,Point,System,五边形,PTA,new,四边形,public From: https://www.cnblogs.com/DaMing5475/p/16837907.html