面向对象程序设计第三次大作业心得
通过这几次的大作业,最深刻的感受就是一定要写好框架并将功能函数封装到类里面去,随着题目难度的增大,代码量,功能函数的数量以及代码逻辑复杂度都在直线上升,这时候封装好类函数就会使得我们的代码整洁且清晰易懂,差距真的会很大!如果前面没有封装好,建议可以重新写过一遍封装好再往下写,这并不会浪费时间,反而会为后面节省了很多时间.第三次大作业主要考察正则匹配的使用,以及类类方法的封装和使用.
题目集三 7-1
输入连个点的坐标,计算两点之间的距离
输入格式:
4个double类型的实数,两个点的x,y坐标,依次是x1、y1、x2、y2,两个点的坐标之间以空格分隔,每个点的x,y坐标以英文“,”分隔。例如:0,0 1,1或0.1,-0.3 +3.5,15.6。
若输入格式非法,输出"Wrong Format"。
若输入格式合法但坐标点的数量超过两个,输出“wrong number of points”。
输出格式:
计算所得的两点之间的距离。例如:1.4142135623730951
输入样例:
整数输入。例如:
0,0 1,1
输出样例:
在这里给出相应的输出。例如:
1.4142135623730951
输入样例1:
带符号double类型实数输入。例如:
+2,-2.3 0.9,-3.2
输出样例1:
在这里给出相应的输出。例如:
1.42126704035519
输入样例2:
格式非法。例如:
++2,-2.3 0.9,-3.2
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
输入样例3:
点的数量超过两个。例如:
+2,-2.3 0.9,-3.2 +2,-2.3
输出样例3:
在这里给出相应的输出。例如:
wrong number of points
在开始计算之前,弄明白正则才是本题的最大难点!有很多特殊的非法输入格式,如01.1(不能0开头然后接非0整数),正确的式子也有多种情况,如下:
1.非零数字开头 如1 , 1.13 , 34 , 4.2
2.零 如0.0 , 0
3.零开头的数字 如0.1 , 0.88
当然,最重要的是每个数字前还可以有正负号!情况真的很多
我的单个数据的正则表达式为^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)
下面是我的point类:
class point{
double x,y;//点的坐标x,y
public static void jisuan(point a,point b){//计算两点距离
double num,number;
num=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
number=Math.sqrt(num);
System.out.print(number);
}
}
然后就是核心思路,判断每个点的输入是否符合正则表达式,然后检测点的数量是否合法(注:点的数量不合法同时存在点的正则不合法,则输出Wrong Format),不合法则输出相应的错误,点的格式和点的数量均合法则继续进行后续操作,先总字符串进行切割(以" "为分割符)将两个点的坐标分割开,然后再对点的坐标进行切割(以","为分割符)获得两个字符数据,最后将字符数据转化为double型数据,最后进行计算然后输出结果(注意区分点和单个数据,点是由两个数据加","构成)
该功能部分代码如下:
if(!n.isEmpty()) { String reg="^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?),[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)\\s[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?),[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)?"; if(!n.matches(reg)) { String reg2="^((-|\\+)?\\d+(.\\d+)?,(-|\\+)?\\d+(.\\d+)?\\s){2,}\\S+"; if(n.matches(reg2)) System.out.printf("wrong number of points"); else System.out.printf("Wrong Format"); }//不匹配 判断是否是因为输入点过多 else { String[] n1=n.split(" "); String[] z=n1[0].split(","); String[] x=n1[1].split(","); p1.x=Double.valueOf(z[0]); p1.y=Double.valueOf(z[1]); p2.x=Double.valueOf(x[0]); p2.y=Double.valueOf(x[1]); point.jisuan(p1,p2); } }//if n1不为空
注意split函数的使用,要声明字符串数组来接收切割后的字符串,切割后的字符串依次放在字符串数组0,1...中

题目集三7-2
用户输入一组选项和数据,进行与直线有关的计算。选项包括:
1:输入两点坐标,计算斜率,若线条垂直于X轴,输出"Slope does not exist"。
2:输入三个点坐标,输出第一个点与另外两点连线的垂直距离。
3:输入三个点坐标,判断三个点是否在一条线上,输出true或者false。
4:输入四个点坐标,判断前两个点所构成的直线与后两点构成的直线是否平行,输出true或者false.
5:输入四个点坐标,计算输出前两个点所构成的直线与后两点构成的直线的交点坐标,x、y坐标之间以英文分隔",",并输出交叉点是否在两条线段之内(不含四个端点)的判断结果(true/false),判断结果与坐标之间以一个英文空格分隔。若两条线平行,没有交叉点,则输出"is parallel lines,have no intersection point"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。
例如:1:0,0 1,1
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
不论哪个选项,如果格式、点数量都符合要求,但构成任一条线的两个点坐标重合,输出"points coincide",
输出格式:
见题目描述。
输入样例1:
选项1,两点重合。例如:
1:-2,+5 -2,+5
输出样例:
在这里给出相应的输出。例如:
points coincide
输入样例2:
选项1,斜率无穷大的线。例如:
1:-2,3 -2,+5
输出样例:
在这里给出相应的输出。例如:
Slope does not exist
输入样例3:
选项1,斜率无穷大。例如:
1:-2,3 -2,+5
输出样例:
在这里给出相应的输出。例如:
Slope does not exist
输入样例4:
选项1,符合格式输入,带符号/不带符号数混合。例如:
1:-2.5,3 -2,+5.3
输出样例:
在这里给出相应的输出。例如:
4.6
输入样例5:
选项2,计算第一个点到另外两点连线的垂直距离。例如:
2:0,1 1,0 2,0
输出样例:
在这里给出相应的输出。例如:
1.0
输入样例6:
选项3,判断三个点是否在一条线上。例如:
3:0,1 2,2 5,3
输出样例:
在这里给出相应的输出。例如:
false
输入样例7:
选项4,判断两条线是否平行。例如:
4:0,1 0,2 2,1 3,0
输出样例:
在这里给出相应的输出。例如:
false
输入样例8:
选项5,判断两条线的交点。例如:
5:0,0 -1,-1 0,2 3,-1
输出样例:
在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:
1.0,1.0 true
输入样例9:
选项5,判断两条线的交点。但两条线平行例如:
5:0,0 -1,-1 2,3 3,4
输出样例:
在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:
is parallel lines,have no intersection point
思路:
在开始之前再次建议还没写的同学或者写了一半的同学可以将自己的类和方法封装好,我在写完这题时并未封装所以在写第四次大作业前,又花了很多时间重写,将各个功能函数封装好,以下仅为思路,并未封装,仅思路供参考
第一步正则匹配,我分了两步正则匹配,所以有两个正则表达式,第一次正则检测功能号[1-5]和":"是否合法,如果合法将字符串对":"进行切割,取出只含点和" "的字符串s,接着对字符串s进行切割,取出每个点的字符串存于字符串数组str1中,接着进行第二次正则匹配,检测每个点是否合法,如果不合法则输出"Wrong Format",如果均合法则判断点的数量是否合法,如果不合法则输出"wrong number of points",相关核心代码如下:
String reg="[1-5]:(.*)+";//第一次正则表达式
String reg1="?),(-|\\+)?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?)";//第二次正则表达式
int num;//
boolean geshi=true,geshu=true,px=true;
if(!n.matches(reg)) System.out.print("Wrong Format");
else{//第一个数字范围为[1-5]
num=n.charAt(0)-'0';
String[] s=n.split(":");
String[] str1=s[1].split(" ");//分割每个点 存在字符数组str1中
for(int q=0;q<str1.length&&geshi;q++)//遍历检测每个点是否合法
if(!str1[q].matches(reg1)) geshi=false;
//五个功能函数,暂时不表,在后文
}
检测完所有的非法数据以后,先进行功能一,如果点的个数和格式均合法,则计算斜率并输出,相关核心代码如下:
if(num==1&&geshi){//功能一
if(str1.length!=2) geshu=false;
else{//个数格式均正确
point a=new point();
point b=new point();
String[] str2=str1[0].split(",");//分割坐标
String[] str3=str1[1].split(",");//分割坐标
a.x=point.getc(str2[0]);
a.y=point.getc(str2[1]);
b.x=point.getc(str3[0]);
b.y=point.getc(str3[1]);
if(a.x==b.x){
if(b.y==a.y) System.out.print("points coincide");
else System.out.print("Slope does not exist");
}
else{//计算斜率
double k;
k=(a.y-b.y)/(a.x-b.x);
System.out.print(k);
}//计算斜率
}//个数格式均正确
}//功能一
功能二:已知点的坐标和直线的两点求点到直线距离,首先求出直线的一般方程,A=y2-y1,B=x1-x2,C=x2*y1-x1-y2,再利用点到直线距离的方程求出距离,相关功能核心代码如下:
else if(num==2&&geshi){//功能二
if(str1.length!=3) geshu=false;
else{//个数格式均正确
point a=new point();
point b=new point();
point c=new point();
String[] str2=str1[0].split(",");//分割坐标
String[] str3=str1[1].split(",");//分割坐标
String[] str4=str1[2].split(",");//分割坐标
a.x=point.getc(str2[0]);
a.y=point.getc(str2[1]);
b.x=point.getc(str3[0]);
b.y=point.getc(str3[1]);
c.x=point.getc(str4[0]);
c.y=point.getc(str4[1]);
if(b.x==c.x&&b.y==c.y) System.out.print("points coincide");
else {//点不重合 计算垂直距离
double A,B,C,d;
A=c.y-b.y;
B=b.x-c.x;
C=c.x*b.y-b.x*c.y;
d=Math.abs(A*a.x+B*a.y+C)/Math.sqrt(A*A+B*B);
System.out.print(d);
}//点不重合 计算垂直距离
}//个数格式均正确
}//功能二
功能三:先判断点是否重合(能否构成直线),然后用数学式子(c.y-a.y)*(b.x-a.x)==(b.y-a.y)*(c.x-a.x)判断三点是否共线,值得一提的是,这里会遇到精度问题所以需要把式子改成Math.abs((c.y-a.y)*(b.x-a.x)-(b.y-a.y)*(c.x-a.x))<1e-6来避免失精
else if(num==3&&geshi){//功能三
if(str1.length!=3) geshu=false;
else{//个数格式均正确
point a=new point();
point b=new point();
point c=new point();
String[] str2=str1[0].split(",");//分割坐标
String[] str3=str1[1].split(",");//分割坐标
String[] str4=str1[2].split(",");//分割坐标
a.x=point.getc(str2[0]);
a.y=point.getc(str2[1]);
b.x=point.getc(str3[0]);
b.y=point.getc(str3[1]);
c.x=point.getc(str4[0]);
c.y=point.getc(str4[1]);
if((a.x==b.x&&a.y==b.y)||(a.x==c.x&&a.y==c.y)||(b.x==c.x&&b.y==c.y)) System.out.print("points coincide");
else{//三点不重合 判断是否共线
if(Math.abs((c.y-a.y)*(b.x-a.x)-(b.y-a.y)*(c.x-a.x))<1e-6) System.out.print("true");
else System.out.print("false");
}//三点不重合 判断是否共线
}//个数格式均正确
}//功能三
功能四:因为我是用的斜率判断是否平行,所以需要分两种情况,一种是垂直于x轴(即斜率不存在),另一种是不垂直于x轴,垂直于x的平行非常好判断,,不垂直的话比较斜率即可
else if(num==4&&geshi){//功能四
if(str1.length!=4) geshu=false;
else{//个数格式均正确
point a=new point();
point b=new point();
point c=new point();
point d=new point();
String[] str2=str1[0].split(",");//分割坐标
String[] str3=str1[1].split(",");//分割坐标
String[] str4=str1[2].split(",");//分割坐标
String[] str5=str1[3].split(",");//分割坐标
a.x=point.getc(str2[0]);
a.y=point.getc(str2[1]);
b.x=point.getc(str3[0]);
b.y=point.getc(str3[1]);
c.x=point.getc(str4[0]);
c.y=point.getc(str4[1]);
d.x=point.getc(str5[0]);
d.y=point.getc(str5[1]);
if((a.x==b.x&&a.y==b.y)||(c.x==d.x&&c.y==d.y)) System.out.print("points coincide");
else {//点均不重合 判断是否平行
if((a.x-b.x==0)||(c.x-d.x==0)){//垂直x轴的情况
if(a.x-b.x==0&&c.x-d.x==0) System.out.print("true");
else System.out.print("false");
}//垂直x轴的情况
else {//不垂直x轴的情况
double k1,k2;
k1=(a.y-b.y)/(a.x-b.x);
k2=(c.y-d.y)/(c.x-d.x);
if(k1==k2) System.out.print("true");
else System.out.print("false");
}//不垂直x轴的情况
}//点均不重合 判断是否平行
}//个数格式均正确
}//功能四
注:如果用斜率取判断平行一定要考虑没有斜率这种情况,个人建议直线用一般方程(aX+bY+c=0),后面几次大作业均采用一般式
功能五:首先延用功能四进行是否平行的判断,如果不平行,则计算出交点坐标,接下来判断是否在线段上,判断是否在线段上有两种思路,先讲我的写法,因为是两条线段上的点,所以满足线性关系,只需要比较x坐标或者y坐标即可,交点的x坐标均小于线段两端点的x坐标或者交点的x坐标均大于线段两端点的坐标x表示交点x不在该线段上(j.x<=a.x&&j.x<=b.x)||(j.x>=a.x&&j.x>=b.x),第二钟方法就是比较两端点的x的大小,交点的x只要满足大于最大值,小于最大值就表示在线段上,第二种方法更易懂,相关核心代码如下:
else if(num==5&&geshi){//功能五
if(str1.length!=4) geshu=false;
else{//个数格式均正确
boolean fw=true;
point a=new point();
point b=new point();
point c=new point();
point d=new point();
point j=new point();
String[] str2=str1[0].split(",");//分割坐标
String[] str3=str1[1].split(",");//分割坐标
String[] str4=str1[2].split(",");//分割坐标
String[] str5=str1[3].split(",");//分割坐标
a.x=point.getc(str2[0]);
a.y=point.getc(str2[1]);
b.x=point.getc(str3[0]);
b.y=point.getc(str3[1]);
c.x=point.getc(str4[0]);
c.y=point.getc(str4[1]);
d.x=point.getc(str5[0]);
d.y=point.getc(str5[1]);
if((a.x==b.x&&a.y==b.y)||(c.x==d.x&&c.y==d.y)) System.out.print("points coincide");
else {//点均不重合 判断是否平行
if((a.x-b.x==0)||(c.x-d.x==0)){//垂直x轴的情况
if(a.x-b.x==0&&c.x-d.x==0) System.out.print("is parallel lines,have no intersection point");
else px=false;
}//垂直x轴的情况
else {//不垂直x轴的情况
double k1,k2;
k1=(a.y-b.y)/(a.x-b.x);
k2=(c.y-d.y)/(c.x-d.x);
if(k1==k2) System.out.print("is parallel lines,have no intersection point");
else px=false;
}//不垂直x轴的情况
}//点均不重合 判断是否平行
if(!px){//不平行
j.x=((a.x-b.x)*(c.x*d.y-d.x*c.y)-(c.x-d.x)*(a.x*b.y-b.x*a.y))/((c.x-d.x)*(a.y-b.y)-(a.x-b.x)*(c.y-d.y));
j.y=((a.y-b.y)*(c.x*d.y-d.x*c.y)-(a.x*b.y-b.x*a.y)*(c.y-d.y))/((c.x-d.x)*(a.y-b.y)-(a.x-b.x)*(c.y-d.y));
System.out.print(j.x);
System.out.print(',');
System.out.print(j.y);
System.out.print(" ");
if(((j.x<=a.x&&j.x<=b.x)||(j.x>=a.x&&j.x>=b.x))&&((j.y<=c.y&&j.y<=d.y)||(j.y>=c.y&&j.y>=d.y))) System.out.print("false");
else System.out.print("true");
}//不平行
}//个数格式均正确
}//功能五
最后就是非法输入的输出
if(!geshi) System.out.print("Wrong Format");
else if(!geshu) System.out.print("wrong number of points");
个人建议还是把各个功能函数封装好,博主由于第一次写的时候没注意,导致代码很多重复代码,并且函数很长不易于修改,博主下一题开始均采用类和封装好各个功能函数


题目集三7-3
用户输入一组选项和数据,进行与三角形有关的计算。选项包括:
1:输入三个点坐标,判断是否是等腰三角形、等边三角形,判断结果输出true/false,两个结果之间以一个英文空格符分隔。
2:输入三个点坐标,输出周长、面积、重心坐标,三个参数之间以一个英文空格分隔,坐标之间以英文","分隔。
3:输入三个点坐标,输出是钝角、直角还是锐角三角形,依次输出三个判断结果(true/false),以一个英文空格分隔,
4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
如果输入的三个点无法构成三角形,输出"data error"。
注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0
选项4中所输入线的两个点坐标重合,输出"points coincide",
输入样例1:
选项4,定义线的两点重合。例如:
4:1,0 1,0 0,0 2,0 4,0
输出样例:
在这里给出相应的输出。例如:
points coincide
输入样例2:
选项4,构成三角形的三个点在一条线上,无法构成三角形。例如:
4:1,0 0,2 0,0 0,0 4,0
输出样例:
在这里给出相应的输出。例如:
data error
输入样例3:
选项1,判断等腰、等边三角形。例如:
1:-2,0 2,0 0,4
输出样例:
两个判断结果。例如:
true false
输入样例4:
选项2,输出边长、面积、重心坐标。例如:
2:0,0 3,0 0,1
输出样例:
在这里给出相应的输出。例如:
7.162278 1.5 1.0,0.333333
输入样例5:
选项3,钝角、直角、锐角的判断。例如:
3:0,1 1,0 2,0
输出样例:
在这里给出相应的输出。例如:
true false false
输入样例6:
选项4,直线与三角形交点的数量等于2,输出数量值以及三角形被分割的两部分面积。例如:
4:1,0 0,2 0,0 0,2 4,0
输出样例:
在这里给出相应的输出。例如:
2 1.0 3.0
输入样例7:
选项4,直线与三角形交点的数量少于两个,只输出数量值。例如:
4:-1,0 1,2 0,1 0,-1 2,0
输出样例:
在这里给出相应的输出。例如:
1
输入样例8:
选项5,用射线法判断点是否在三角形内部。例如:
5:0.5,0.5 0,0 0,2 4,0
输出样例:
在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:
in the triangle
输入样例9:
选项5,用射线法判断点是否在三角形内部。例如:
5:0,0 -1,-1 2,3 3,4
输出样例:
在这里给出相应的输出。例如:
outof the triangle
思路:
首先构建point类,line类还有Triangle类
class point{
double x,y;
void get(String str){把字符串转化为double数据然后存入点中
String[] str1=str.split(",");
this.x=Double.valueOf(str1[0]);
this.y=Double.valueOf(str1[1]);
}
class line{
double a,b,c;//直线方程的一般式
point p1,p2;//线段的两个端点
boolean panduan(point p1,point p2){//判断能否构成直线,且存入相关数据
if(p1.x==p2.x&&p1.y==p2.y)
return true;
else {
this.a=p2.y-p1.y;
this.b=p1.x-p2.x;
this.c=p2.x*p1.y-p1.x*p2.y;
this.p1=p1;
this.p2=p2;
return false;
}
}
//判断交点是否在线段l2上(包含端点) l1为直线 l2为线段 交点坐标存在p中
public static boolean jiaodian(line l1,line l2,point p){
p.x=(l2.c * l1.b - l1.c * l2.b) / (l1.a * l2.b - l2.a * l1.b);
if(l1.b!=0)
p.y=-(l1.a*p.x+l1.c)/l1.b;
else if(l2.b!=0)
p.y=-(l2.a*p.x+l2.c)/l2.b;
if(l2.b==0){
if((p.y<l2.p1.y&&p.y<l2.p2.y)||(p.y>l2.p1.y&&p.y>l2.p2.y))
return false;
else return true;
}
if(l2.a==0)
{
if((p.x<l2.p1.x&&p.x<l2.p2.x)||(p.x>l2.p1.x&&p.x>l2.p2.x))
return false;
else return true;
}
if((p.x<l2.p1.x&&p.x<l2.p2.x)||(p.x>l2.p1.x&&p.x>l2.p2.x)||(p.y<l2.p1.y&&p.y<l2.p2.y)||(p.y>l2.p1.y&&p.y>l2.p2.y))
return false;
return true;
}
public boolean online(point e)//判断是否在线段上(不含端点) (前提是已经判定点在直线上)
{
if(this.b==0)
{
if((e.y<=this.p1.y&&e.y<=this.p2.y)||(e.y>=this.p1.y&&e.y>=this.p2.y))
return false;
else return true;
}
if(this.a==0)
{
if((e.x<=this.p1.x&&e.x<=this.p2.x)||(e.x>=this.p1.x&&e.x>=this.p2.x))
return false;
else return true;
}
if((e.x<=this.p1.x&&e.x<=this.p2.x)||(e.x>=this.p1.x&&e.x>=this.p2.x)||(e.y<=this.p1.y&&e.y<=this.p2.y)||(e.y>=this.p1.y&&e.y>=this.p2.y))
return false;
return true;
}
public static boolean pingxing(line d,line e)//判断两直线是否平行
{
if(d.a==0)
{
if(e.a==0)
return true;
return false;
}
if(d.b==0)
{
if(e.b==0)
return true;
return false;
}
if(d.a*e.b==e.a*d.b)
return true;
return false;
}
public static boolean chonghe(line d,line e)//判断两直线是否重合
{
if(!line.pingxing(d,e))
return false;
if(d.a==0&&d.b*e.c==e.b*d.c)
return true;
if(d.a==0&&d.b*e.c!=e.b*d.c)
return false;
if(d.a*e.c==e.a*d.c)
return true;
return false;
}
public boolean gongxian(point d)//判断点跟直线是否共线
{
double ans=Math.abs(this.a*d.x+this.b*d.y+this.c);
if(ans==0) return true;
else return false;
}
}
class Triangle{
point p1,p2,p3;
line l1,l2,l3;
double b1,b2,b3;
boolean panduan(point p1,point p2,point p3){//计算三边长度 存入边长和点的坐标 判断能否构成三角形
double a, b, c;
boolean f;
a = Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
b = Math.sqrt((p1.x - p3.x) * (p1.x - p3.x) + (p1.y - p3.y) * (p1.y - p3.y));
c = Math.sqrt((p3.x - p2.x) * (p3.x - p2.x) + (p3.y - p2.y) * (p3.y - p2.y));
if (a + b > c && a + c > b && b + c > a ) {
this.p1=p1;
this.p2=p2;
this.p3=p3;
this.b1=a;
this.b2=b;
this.b3=c;
return true;
}
else return false;
}
public static int same(double a,double b,double c){//判断有多少边相等
if(Math.abs(a-b)<=1e-6&&Math.abs(b-c)<=1e-6) return 2;
else if(Math.abs(a-b)<=1e-6||Math.abs(b-c)<=1e-6||Math.abs(a-c)<=1e-6) return 1;
else return 0;
}//判断有多少边相等
public static double mianji(point p1,point p2,point p3){//求三角形面积
return Math.abs((p1.x*p2.y+p2.x*p3.y+p3.x*p1.y-p1.x*p3.y-p2.x*p1.y-p3.x*p2.y)/2);
}//求三角形面积
void max(){//把最长的边放在b1的位置
double n;
if(this.b2>=this.b1&&this.b2>=this.b3) {
n=this.b1;
this.b1=this.b2;
this.b2=n;
}
else if(this.b3>=this.b1&&this.b3>=this.b2) {
n=this.b1;
this.b1=this.b3;
this.b3=n;
}
}
}
前三个功能调用函数进行数学计算即可
if(!s.matches(reg)) System.out.print("Wrong Format");
else {//选项必须为1-5
Triangle t=new Triangle();
int num=s.charAt(0)-'0';
String[] str=s.split(":");
String[] str1=str[1].split(" ");//分割每个点 存在字符数组str1中(带",")
for(int q=0;q<str1.length&&geshi;q++)//遍历检测每个点是否合法
if(!str1[q].matches(reg1)) geshi=false;
if(num==1&&geshi){//功能一
if(str1.length!=3) geshu=false;
else{//点的个数合法
point p1=new point(),p2=new point(),p3=new point();
p1.get(str1[0]);
p2.get(str1[1]);
p3.get(str1[2]);
if(!t.panduan(p1,p2,p3)) System.out.print("data error");
else{//可以构成三角形 判断等边等腰情况
if(Triangle.same(t.b1,t.b2,t.b3)==2) System.out.print("true true");
if(Triangle.same(t.b1,t.b2,t.b3)==1) System.out.print("true false");
if(Triangle.same(t.b1,t.b2,t.b3)==0) System.out.print("false false");
}//可以构成三角形 判断等边等腰情况
}//点的个数合法
}//功能一
else if(num==2&&geshi){//功能二
if(str1.length!=3) geshu=false;
else{//点的个数合法
point p1=new point(),p2=new point(),p3=new point();
p1.get(str1[0]);
p2.get(str1[1]);
p3.get(str1[2]);
if(!t.panduan(p1,p2,p3)) System.out.print("data error");
else{//可以构成三角形
double zc,mj;
zc=t.b1+t.b2+t.b3;
mj=Triangle.mianji(p1,p2,p3);
point.shuchu(zc);
System.out.print(" ");
point.shuchu(mj);
System.out.print(" ");
point.shuchu((p1.x+p2.x+p3.x)/3);
System.out.print(",");
point.shuchu((p1.y+p2.y+p3.y)/3);
}//可以构成三角形
}//点的个数合法
}//功能二
else if(num==3&&geshi){//功能三
if(str1.length!=3) geshu=false;
else{//点的个数合法
point p1=new point(),p2=new point(),p3=new point();
p1.get(str1[0]);
p2.get(str1[1]);
p3.get(str1[2]);
if(!t.panduan(p1,p2,p3)) System.out.print("data error");
else{//可以构成三角形
t.max();//保证t.b1为最长边
if(t.b2*t.b2+t.b3*t.b3-t.b1*t.b1<-1e-6) System.out.print("true");
else System.out.print("false");
System.out.print(" ");
if(Math.abs(t.b2*t.b2+t.b3*t.b3-t.b1*t.b1)<1e-6) System.out.print("true");
else System.out.print("false");
System.out.print(" ");
if(t.b2*t.b2+t.b3*t.b3-t.b1*t.b1>1e-6) System.out.print("true");
else System.out.print("false");
}//可以构成三角形
}//点的个数合法
}//功能三
功能四先判断是否平行于任意边
1.平行于任意边: (1)判断是否与任意边重合
(2)判断有几个交点:如果有两个则输出面积(端点和两交点构成三角形)
2.不平行于任意边:(1)判断有几个交点:如果有两个交点:1.有一个交点为端点(端点,交点,除端点外任一端点构成三角形) 2.两个点均不为端点(两个交点加交点所在直线相交的那个端点构成三角形)
else if(num==4&&geshi){//功能四
if(str1.length!=5) geshu=false;
else{//点的个数合法
line l=new line();
point p1=new point(),p2=new point(),p3=new point(),p4=new point(),p5=new point();
double s1,sz;
int number=0;
t.l1=new line();
t.l2=new line();
t.l3=new line();
p1.get(str1[0]);
p2.get(str1[1]);
p3.get(str1[2]);
p4.get(str1[3]);
p5.get(str1[4]);
if(l.panduan(p1,p2)) System.out.println("points coincide");
else if(!t.panduan(p3,p4,p5)) System.out.println("data error");
if(!l.panduan(p1,p2)&&t.panduan(p3,p4,p5)){//可以构成三角形 且可以构成直线
sz=Triangle.mianji(p3,p4,p5);
t.l1.panduan(p3,p4);
t.l2.panduan(p3,p5);
t.l3.panduan(p4,p5);
point pm=new point(),pn=new point(),pp=new point();
if(line.pingxing(l,t.l1)){
if(line.chonghe(l,t.l1)) System.out.print("The point is on the edge of the triangle");
else {//平行但不重合
if(line.jiaodian(l,t.l2,pm)){
number++;
}
if(line.jiaodian(l,t.l3,pn)){
number++;
}
if(number==1) System.out.print("1");
else if(number==2){
if(pm.x==pn.x&&pm.y==pn.y){
number--;
System.out.print(number);
}
else {//边上有两个交点
line.jiaodian(t.l2,t.l3,pp);
s1=Triangle.mianji(pm,pn,pp);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}//边上有两个交点
}
else System.out.print(0);
}//平行但不重合
}
else if(line.pingxing(l,t.l2)){
if(line.chonghe(l,t.l2)) System.out.print("The point is on the edge of the triangle");
else {//平行但不重合
if(line.jiaodian(l,t.l1,pm)){
number++;
}
if(line.jiaodian(l,t.l3,pn)){
number++;
}
if(number==1) System.out.print("1");
else if(number==2){
if(pm.x==pn.x&&pm.y==pn.y){
number--;
System.out.print(number);
}
else {//边上有两个交点
line.jiaodian(t.l1,t.l3,pp);
s1=Triangle.mianji(pm,pn,pp);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}//边上有两个交点
}
else System.out.print(0);
}//平行但不重合
}
else if(line.pingxing(l,t.l3)){
if(line.chonghe(l,t.l3)) System.out.print("The point is on the edge of the triangle");
else {//平行但不重合
if(line.jiaodian(l,t.l2,pm)){
number++;
}
if(line.jiaodian(l,t.l1,pn)){
number++;
}
if(number==1) System.out.print("1");
else if(number==2){
if(pm.x==pn.x&&pm.y==pn.y){
number--;
System.out.print(number);
}
else {//边上有两个交点
line.jiaodian(t.l2,t.l1,pp);
s1=Triangle.mianji(pm,pn,pp);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}//边上有两个交点
}
else System.out.print(0);
}//平行但不重合
}
else{//不平行
if(l.gongxian(t.p1)){//有一个交点为端点1
if(line.jiaodian(l,t.l3,pm)){//边l3上还有一个交点
s1=Triangle.mianji(t.p1,pm,t.p3);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}//边l3上还有一个交点
else{//边l3上没有一个交点
System.out.print("1");
}//边l3上没有一个交点
}//有一个交点为端点1
else if(l.gongxian(t.p2)){//有一个交点为端点2
if(line.jiaodian(l,t.l2,pm)){//边l3上还有一个交点
s1=Triangle.mianji(t.p2,pm,t.p1);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}//边l3上还有一个交点
else{//边l3上没有一个交点
System.out.print("1");
}//边l3上没有一个交点
}//有一个交点为端点2
else if(l.gongxian(t.p3)){//有一个交点为端点3
if(line.jiaodian(l,t.l1,pm)){//边l3上还有一个交点
s1=Triangle.mianji(t.p3,pm,t.p1);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}//边l3上还有一个交点
else{//边l3上没有一个交点
System.out.print("1");
}//边l3上没有一个交点
}//有一个交点为端点3
else {//端点均不为交点
boolean a=false,b=false,c=false;
point newp=new point();
if(line.jiaodian(l,t.l1,pm)){
a=true;
number++;
}
if(line.jiaodian(l,t.l2,pn)){
b=true;
number++;
}
if(line.jiaodian(l,t.l3,pp)){
c=true;
number++;
}
if(number==0){
System.out.print("0");
}
else{
if(a&&b){
line.jiaodian(t.l1,t.l2,newp);
s1=Triangle.mianji(pm,pn,newp);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}
if(c&&b){
line.jiaodian(t.l2,t.l3,newp);
s1=Triangle.mianji(pn,pp,newp);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}
if(a&&c){
line.jiaodian(t.l1,t.l3,newp);
s1=Triangle.mianji(pm,pp,newp);
if(s1<sz-s1) {
System.out.print("2 ");
point.shuchu(s1);
System.out.print(" ");
point.shuchu(sz-s1);
}
else {
System.out.print("2 ");
point.shuchu(sz-s1);
System.out.print(" ");
point.shuchu(s1);
}
}
}
}//端点均不为交点
}
}//可以构成三角形 且可以构成直线
}//点的个数合法
}//功能四
功能五才用面积法:
点与任意两个端点构成三个三角形,三个三角形面积和等于大三角形面积则在三角形上或者三角形内,通过三角形三条边判断点是否在边上
else if(num==5&&geshi){//功能五
if(str1.length!=4) geshu=false;
else{//点的个数合法
point p1=new point(),p2=new point(),p3=new point(),p4=new point();
p1.get(str1[0]);
p2.get(str1[1]);
p3.get(str1[2]);
p4.get(str1[3]);
t.l1=new line();t.l2=new line();t.l3=new line();
t.l1.panduan(p2,p3);
t.l2.panduan(p2,p4);
t.l3.panduan(p3,p4);
if(!t.panduan(p2,p3,p4)) System.out.print("data error");
else{//可以构成三角形
if((p1.x==p2.x&&p1.y==p2.y)||(p1.x==p3.x&&p1.y==p3.y)||(p1.x==p4.x&&p1.y==p4.y)){
System.out.print("on the triangle");
}
else if(t.l1.gongxian(p1)&&t.l1.online(p1)){//
System.out.print("on the triangle");
}
else if(t.l2.gongxian(p1)&&t.l2.online(p1)){//
System.out.print("on the triangle");
}
else if(t.l3.gongxian(p1)&&t.l3.online(p1)){//
System.out.print("on the triangle");
}
else{
double s1,s2,s3,sz;
s1=Triangle.mianji(p1,p2,p3);
s2=Triangle.mianji(p1,p2,p4);
s3=Triangle.mianji(p1,p3,p4);
sz=Triangle.mianji(p2,p3,p4);
if(s1+s2+s3-sz<=1e-6){
System.out.print("in the triangle");
}
else System.out.print("outof the triangle\n");
}
}//可以构成三角形
}//点的个数合法
}//功能五


心得:
通过这次大作业熟悉了类的使用,强化了用类封装的意识

浙公网安备 33010602011771号