- 前言
(1)前言:经过了前面的作业感觉后面的作业都没有像前面的那么折磨,可能已经习惯了折磨的感觉,写起来特别顺手。
(2)设计与分析:
7-2 点线形系列4-凸四边形的计算
用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
选项4中,若前两个输入线的点重合,输出"points coincide"。
首先是input类 ,判断是否格式正确,返回点的集合的功能。
查看代码
static class input{
String ss;
input(String ss){
this.ss=ss;
}
boolean islegal(){
String s="[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)";
return this.ss.matches(s + "," + s + "(\\s" + s +","+ s + ")+" + "[\\s]*");
}
int diannum( ){
return this.ss.split("\\s").length;
}
String [] dian(){
return ss.split(" ");
}
dian [] getPoint(){
dian a[] = new dian[20];
String[] s1=ss.split(" ");
for(int i=0;i<this.dian().length;++i){
String [ ] ss1=s1[i].split(",");
double x1=Double.parseDouble(ss1[0]);
double y1=Double.parseDouble(ss1[1]);
a[i]= new dian(x1,y1);
}
return a;
}
}
这是四边形的类,写的有点辣鸡,大部分功能是枚举情况,没有什么好看的,可以看后面第五次作业优化的版本。
static class Quad {
dian p1, p2, p3, p4;
jian ab,ac,ad,bc,cd,bd;
Quad(dian x1, dian x2, dian x3, dian x4){
this.p1=x1;
this.p2=x2;
this.p3=x3;
this.p4=x4;
ab=new jian(p1,p2);
ad = new jian(p1,p4);
bc= new jian(p2,p3);
cd = new jian(p3,p4);
ac= new jian(p1,p3);
bd= new jian(p2,p4);
}
double getCircumference(){
return p1.distance(p2)+p2.distance(p3)+p3.distance(p4)+p4.distance(p1);
}
public int istri() //判断是否为三角形,并判断哪三点共线
{
//判断是三角形的条件为有且只有一种三点共线的情况
if(p1.isequlity(p2)||p1.isequlity(p3)||p1.isequlity(p4))
{
if(p2.isequlity(p3)||p2.isequlity(p4)||p3.isequlity(p4))
{
return 0;
}
else return 1;
}
if(p2.isequlity(p3)||p2.isequlity(p4))
{
if(p1.isequlity(p2)||p1.isequlity(p3)||p1.isequlity(p4)
||p3.isequlity(p4))
return 0;
else return 2;
}
if(p3.isequlity(p4))
{
if(p1.isequlity(p2)||p1.isequlity(p3)||p1.isequlity(p4)
||p2.isequlity(p3)||p2.isequlity(p4))
return 3;
else return 0;
}
int count=0;
if(ac.onxianduan(p2))//1 3 quad.bd.onxianduan(quad.p1)
{
tri sanjiaoxing1=new tri(p1,p3,p4);
if(sanjiaoxing1.istri()) count=2;
}
if(bd.onxianduan(p3))//2 4
{
if(count!=0) return 0;
else
{
tri sanjiaoxing1=new tri(p1,p2,p4);
if(sanjiaoxing1.istri()) count=3;
}
}
if(ac.onxianduan(p4))//
{
if(count!=0) return 0;
else
{
tri sanjiaoxing1=new tri(p1,p2,p3);
if(sanjiaoxing1.istri()) count=4;
}
}
if(bd.onxianduan(p1))
{
if(count!=0) return 0;
else
{
tri sanjiaoxing1=new tri(p2,p3,p4);
if(sanjiaoxing1.istri()) count=1;
}
}
return count;
}
double getArea(){
tri t1= new tri(p1,p2,p3);
tri t2= new tri(p1,p3,p4);
tri t3= new tri(p1,p2,p4);
tri t4= new tri(p4,p2,p3);
return min(t1.mianji()+t2.mianji(),t3.mianji()+t4.mianji());
}
boolean isQuad(){
if(cd.jiaodiannum_2xianduan(ab)==1||bc.jiaodiannum_2xianduan(ad)==1) return false;
return !(ab.tongxian(p3)||ab.tongxian(p4)||bc.tongxian(p4)||ad.tongxian(p3));
}
boolean isParallelogram(){
if(!this.isQuad()) return false;
return (ab.pingxing(cd)&&ad.pingxing(bc));
}
boolean isDiamond(){
return p1.distance(p2)==p1.distance(p4)&&this.isParallelogram();
}
boolean isSquare(){
return this.isRectangular()&&this.isDiamond();
}
boolean isRectangular(){
if(!this.isQuad()) return false;
if(mul(sub(p1,p2),sub(p1,p4))==0)
return true;
return false;
}
boolean isConvex_Quadrilateral(){
//叉乘法
// double t1 = (p4.x-p1.x)*(p2.y-p1.y)-(p4.y-p1.y)*(p2.x-p1.x);
// double t2 = (p1.x-p2.x)*(p3.y-p2.y)-(p1.y-p2.y)*(p3.x-p2.x);
// double t3 = (p2.x-p3.x)*(p4.y-p3.y)-(p2.y-p3.y)*(p4.x-p3.x);
// double t4 = (p3.x-p4.x)*(p1.y-p4.y)-(p3.y-p4.y)*(p1.x-p4.x);
// return t1 * t2 * t3 * t4 > 0;
//面积法
tri s1= new tri(p1,p2,p3);
tri s2= new tri(p3,p4,p1);
tri s3 =new tri(p2,p3,p4 );
tri s4 = new tri(p4,p1,p2);
return doubleequal(s1.mianji()+s2.mianji(),s3.mianji()+s4.mianji());
}
public void inpoint(dian a){
dian [] w={this.p1,this.p2,this.p3,this.p4};
jian x1=new jian(this.p1,this.p2);
jian x2=new jian(this.p2,this.p3);
jian x3 =new jian (this.p3,this.p4);
jian x4 =new jian (this.p4,this.p1);
if( x1.tongxian(a)){
if((a.x>=min(x1.x.x,x1.y.x)&&a.x<=max(x1.x.x,x1.y.x))&&(a.y<=max(x1.x.y,x1.y.y)&&a.y>=min(x1.x.y,x1.y.y))){
System.out.println("on the quadrilateral");return ;
}
}
if( x2.tongxian(a)){
if((a.x>=min(x2.x.x,x2.y.x)&&a.x<=max(x2.x.x,x2.y.x))&&(a.y<=max(x2.x.y,x2.y.y)&&a.y>=min(x2.x.y,x2.y.y))){
System.out.println("on the quadrilateral");return ;
}
}
if( x3.tongxian(a)){
if((a.x>=min(x3.x.x,x3.y.x)&&a.x<=max(x3.x.x,x3.y.x))&&(a.y<=max(x3.x.y,x3.y.y)&&a.y>=min(x3.x.y,x3.y.y))){
System.out.println("on the quadrilateral");return ;
}
}
if( x4.tongxian(a)){
if((a.x>=min(x4.x.x,x4.y.x)&&a.x<=max(x4.x.x,x4.y.x))&&(a.y<=max(x4.x.y,x4.y.y)&&a.y>=min(x4.x.y,x4.y.y))){
System.out.println("on the quadrilateral");return ;
}
}
int i;
int count=0;
for(i=0;i<4;++i){
dian p1=w[i];
dian p2=w[(i+1)%4];
if(p1.y==p2.y) continue;
if(a.y<=min(p1.y,p2.y))continue;
if(a.y>=max(p1.y,p2.y))continue;
double tep=(a.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
if(tep>a.x) count++;
}
if((count&1)==1) System.out.println("in the quadrilateral");
else System.out.println("outof the quadrilateral");
}
void jiaodiannum_quad(jian a){
if(a.isequality(ab)||a.isequality(bc)||a.isequality(cd)||a.isequality(ad))
{
System.out.println("The line is coincide with one of the lines");
return;
}
int sum = ab.jiaodiannum(a)+bc.jiaodiannum(a)+cd.jiaodiannum(a)+ad.jiaodiannum(a);
if(sum==0){
System.out.println(sum);
return;
}
if(sum==3){
System.out.print("2 ");
if(a.jiaodiannum(ab)==0){
if(ad.jiaodian(a).isequlity(cd.jiaodian(a))){
dian tep= a.jiaodian(bc);
tri t=new tri(tep,p3,p4);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else {
dian tep= a.jiaodian(ad);
tri t=new tri(tep,p3,p4);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
}
else if(a.jiaodiannum(bc)==0){
System.out.print("2 ");
if(ad.jiaodian(a).isequlity(ab.jiaodian(a))){
dian tep= a.jiaodian(cd);
tri t=new tri(tep,p1,p4);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else {
dian tep= a.jiaodian(ab);
tri t=new tri(tep,p1,p4);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
}
else if(a.jiaodiannum(cd)==0){
System.out.print("2 ");
if(bc.jiaodian(a).isequlity(ab.jiaodian(a))){
dian tep= a.jiaodian(ad);
tri t=new tri(tep,p1,p2);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else {
dian tep= a.jiaodian(bc);
tri t=new tri(tep,p1,p2);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
}
else {
System.out.print("2 ");
if(bc.jiaodian(a).isequlity(cd.jiaodian(a))){
dian tep= a.jiaodian(ab);
tri t=new tri(tep,p2,p3);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else {
dian tep= a.jiaodian(cd);
tri t=new tri(tep,p2,p3);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
}
}
else if(sum==4){
System.out.print("2 ");
if((bc.jiaodian(a).isequlity(cd.jiaodian(a)))&&(ad.jiaodian(a).isequlity(ab.jiaodian(a)))){
tri t1= new tri(p1,p2,p3);
System.out.println(data(min(t1.mianji(),this.getArea()-t1.mianji()))+" "+data(max(t1.mianji(),this.getArea()-t1.mianji())));
}
else {
tri t1= new tri(p1,p2,p4);
System.out.println(data(min(t1.mianji(),this.getArea()-t1.mianji()))+" "+data(max(t1.mianji(),this.getArea()-t1.mianji())));
}
}
else if(sum==2){
System.out.print("2 ");
if(ab.jiaodiannum(a)==1&&cd.jiaodiannum(a)==1){
dian d1= ab.jiaodian(a);
dian d2= cd.jiaodian(a);
Quad q1= new Quad(d1,d2,p1,p4);
Quad q2= new Quad(d1,d2,p2,p3);
System.out.println(data(min(q1.getArea(), q2.getArea()))+" "+data(max(q1.getArea(), q2.getArea())));
}
else if(ad.jiaodiannum(a)==1&&bc.jiaodiannum(a)==1){
dian d1= ad.jiaodian(a);
dian d2= bc.jiaodian(a);
Quad q1= new Quad(d1,d2,p1,p4);
Quad q2= new Quad(d1,d2,p2,p3);
System.out.println(data(min(q1.getArea(), q2.getArea()))+" "+data(max(q1.getArea(), q2.getArea())));
}
if(ab.jiaodiannum(a)==1&&bc.jiaodiannum(a)==1){
dian d1= ab.jiaodian(a);
dian d2= bc.jiaodian(a);
tri t= new tri(d1,d2,p2);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else if(ab.jiaodiannum(a)==1&&ad.jiaodiannum(a)==1){
dian d1= ab.jiaodian(a);
dian d2= ad.jiaodian(a);
tri t= new tri(d1,d2,p1);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else if(bc.jiaodiannum(a)==1&&cd.jiaodiannum(a)==1){
dian d1= cd.jiaodian(a);
dian d2= bc.jiaodian(a);
tri t= new tri(d1,d2,p3);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
else if(cd.jiaodiannum(a)==1&&ad.jiaodiannum(a)==1){
dian d1= ad.jiaodian(a);
dian d2= cd.jiaodian(a);
tri t= new tri(d1,d2,p4);
System.out.println(data(min(t.mianji(),this.getArea()-t.mianji()))+" "+data(max(t.mianji(),this.getArea()-t.mianji())));
}
}
}
}
类图: 这类图就像面向过程一样,相互之间没有关联,后面的继承就可以链接起来了。
SourceMonitor生成报表内容如下:
点线形系列5-凸五边形的计算
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
这二道题可以写在一起,至于为什么分开来,可能是怕行数超过限制吧。
这道题写的代码我写了好久,把前面的代码都重构了一遍,呜呜呜,真的累,不过效果还是很好的。
首先是多边形的类:几乎把三边行和四边形的方法和属性都放在了里面。比如点和线,周长,面积,多边形的分割面积等等。
查看代码
public class Graph{
Point[] point;
Line[] line;
int side;
Graph() {}
Graph(Point[] point, int n) {
this.point= new Point[n];
this.line= new Line[n];
side=n;
for (int i = 0; i < n; i++)
this.point[i] = new Point(point[i].x, point[i].y);
for (int i = 0; i < n; i++)
line[i] = new Line(point[i], point[(i + 1) % point.length]);
}
// boolean isGraph(){
// for (int i = 0; i < side; i++) {
// Line tep = new Line()
// if()
// }
// }
/**
*
* @param tep 线
* @return 是否线与多边形重复
*/
boolean EdgeCoincidence(Line tep){
for(Line a:line)
if(a.isequality_xianduan(tep))
return true;
return false;
}
/**
*
* @param tep 点
* @return 是否点与多边形重复
*/
boolean PointCoincidence(Point tep){
for(Point a:point)
if(a.isequlity(tep))
return true;
return false;
}
/**
*
* @param tep
* @return 点是否在多边形边上
*/
boolean Point_onedge(Point tep){
for(Line a:line)
if(a.onxianduan(tep))
return true;
return false;
}
/**
*
* @return 周长
*/
double getCircumference() {
double ans = 0;
for (int i = 0; i < side; i++)
ans += point[i].distance(point[(i + 1) % point.length]);
return ans;
}
/**
*
* @return 面积
*/
double getArea() {
if(side<3) return 0;
Point[] point=ClockwiseSortPoints(this.point,side);//排序
double area = 0;
for (int i=1;i<side-1;i++)
area += cross(sub(point[i],point[0]),sub(point[i+1],point[0]));
area /= 2; return(area < 0 ? -area : area);
}
/**
*
* @param a 多边形
* @return 多边形与多边形的公共面积
*/
double Public_Area(Graph a){
Point[] s= new Point[10];
Point tep =new Point();
int count=0;
for(Line a1:line)
for(Line a2:a.line)
if(a1.jiaodian(a2)!=null){
if(a1.jiaodiannum_2xianduan(a2)==1)
s[count++] = a1.jiaodian(a2);
}
s=tep.Coincidentpoints(s,count);
int sum =tep.len(s);
for(int i = 0;i <side;i++)
if (a.Point_In_Graph(point[i]))
s[sum++]= point[i];
for (int i = 0;i < a.side;i++)
if (this.Point_In_Graph(a.point[i]))
s[sum++]= a.point[i];
Graph graph= new Graph(s,sum);
System.out.println(data(graph.getArea()));
return graph.getArea();
}
/**
*
* @param a 线
* 分割多边形
*/
void Division_Graph(Line a){
if(this.EdgeCoincidence(a))
{
System.out.println("The line is coincide with one of the lines");
return;
}
int sum =0,count=0,count1=0;
Point [] x = new Point[10];
Line [] k = new Line[10];
for(Line l: line){
if(l.jiaodiannum(a)!=0){
sum+=l.jiaodiannum(a);
x[count++]=l.jiaodian(a);
k[count1++]= l;
}
}
Point s =new Point();
x= s.Coincidentpoints(x,count);
if(s.len(x)==0||s.len(x)==1){
System.out.println(x.length);
return;
}
System.out.print("2 ");
int i = 0,j;
Point [] tep =a.Line_MinPoint(point);
for ( i = 2; i < 2+s.len(tep); i++)
x[i]=tep[i-2];
Graph graph = new Graph(x,s.len(x));
System.out.println(data(min(this.getArea() - graph.getArea(), graph.getArea())) + " " + data(max(this.getArea() - graph.getArea(), graph.getArea())));
}
/**
*
* @param a 多边形
* @return 是否多边形与多边形分离
*/
boolean Separate(Graph a ){
boolean flag =false;
for(Line a1:this.line)
for(Line a2:a.line){
if(a1.jiaodiannum_2xianduan(a2)==1)
flag= true;
}
return !flag;
}
/**
*
* @param a
* @return 是否连接
*/
boolean Connection(Graph a){
int flag1= 0,flag2 =0;
for(Line a2:a.line){
if(this.EdgeCoincidence(a2))
flag1++;
}
for(Point a1:a.point){
if(this.PointCoincidence(a1))
flag2++ ;
}
boolean flag= false;
for (Line a1:line )
for(Line a2:a.line)
if(a1.jiaodiannum_2xianduan(a2)==1)
if(!this.PointCoincidence(a1.jiaodian(a2)))
flag= true;
if(flag) return false;
return flag1==1||flag2==1;
}
/**
*
* @param a
* @return 是否重合
*/
boolean Coincides (Graph a){
if(this.side!=a.side) return false;
int sum=0;
for(Point a1:point)
for(Point a2:a.point)
if(a1.isequlity(a2))
sum++;
return sum==side;
}
/**
*
* @param a
* @return 是否包含
*/
boolean Contains(Graph a){// a在this中
boolean flag= false;
for(Point a2:a.point){
if(!this.Point_In_Graph(a2)&&!this.Point_onedge(a2))
flag =true;
}
return !flag;
}
/**
*
* @param a
* @return 是否交错
*/
boolean Interlaced(Graph a){
if(this.Coincides(a)) return false;
boolean flag= false;
for (Line a1:line )
for(Line a2:a.line)
if(a1.jiaodiannum_2xianduan(a2)==1)
flag= true;
return flag;
}
/**
*
* @param a
* @return 是否被包含
*/
boolean Inside(Graph a){// this在a中
boolean flag= false;
for(Point a2:this.point)
if(!a.Point_In_Graph(a2)&&!a.Point_onedge(a2))
flag =true;
return !flag;
}
/**
*
* @param a
* @output 输出关系
*/
void Relationship(Graph a){
String [] ss= new String[8];
ss[3]="triangle";
ss[4]="quadrilateral";
ss[5]="pentagon";
if(this.Separate(a)){//no overlapping area between the previous triangle/quadrilateral/ pentagon and the following triangle/quadrilateral/ pentagon
System.out.print("no overlapping area between the previous "+ss[side]+" and the following "+ss[a.side]);
}
else if(this.Connection(a)){
System.out.print("the previous "+ss[side]+" is connected to the following "+ss[a.side]);
}
else if(this.Coincides(a)){
System.out.print("the previous "+ss[side]+" coincides with the following "+ss[a.side]);
}
else if(this.Inside(a)){
System.out.print("the previous "+ss[side]+" is inside the following "+ss[a.side]);
}
else if(this.Contains(a)){
System.out.print("the previous "+ss[side]+" contains the following "+ss[a.side]);
}
else if(this.Interlaced(a)){
System.out.print("the previous "+ss[side]+" is interlaced with the following "+ss[a.side]);
}
}
// void Point_In_Graph(Point a) {
// for (Line l : line)
// if (l.tongxian(a))
// if ((a.x >= min(l.x.x, l.y.x) && a.x <= max(l.x.x, l.y.x)) && (a.y <= max(l.x.y, l.y.y) && a.y >= min(l.x.y, l.y.y))) {
// System.out.println("on the quadrilateral");
// return;
// }
// int count = 0;
// for (int i = 0; i < side; ++i) {
// Point p1 = point[i];
// Point p2 = point[(i + 1) % side];
// if (p1.y == p2.y) continue;
// if (a.y <= min(p1.y, p2.y)) continue;
// if (a.y >= max(p1.y, p2.y)) continue;
// double tep = (a.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
// if (tep > a.x) count++;
// }
// if ((count & 1) == 1) System.out.println("in the quadrilateral");
// else System.out.println("outof the quadrilateral");
// }
/**
*
* @param a
* @return 是否在多边形中 在边上return false
*/
boolean Point_In_Graph(Point a) {
for (Line l : line)
if (l.tongxian(a))
if ((a.x >= min(l.x.x, l.y.x) && a.x <= max(l.x.x, l.y.x)) && (a.y <= max(l.x.y, l.y.y) && a.y >= min(l.x.y, l.y.y)))
return false;
int count = 0;
for (int i = 0; i < side; ++i) {
Point p1 = point[i];
Point p2 = point[(i + 1) % side];
if (p1.y == p2.y) continue;
if (a.y < min(p1.y, p2.y)) continue;
if (a.y >= max(p1.y, p2.y)) continue;
double tep = (a.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
//if(doubleequal(tep,a.x)) continue;
if (tep > a.x) count++;
}
return (count & 1) == 1;
}
/**
*
* @return 是否凹凸多边形
*/
boolean isConvex_Quadrilateral(){
int len = side;
double ans = 1;
for(int i=0;i<len;i++) {
double t = (point[i%len].x-point[(i+1)%len].x)*(point[(i+2)%len].y-point[(i+1)%len].y)-(point[i%len].y-point[(i+1)%len].y)*(point[(i+2)%len].x-point[(i+1)%len].x);
ans = ans*t;
}
return ans < 0.000001;
}
}
我来介绍一下分割面积和求面积吧:
分割面积:
分割面积
void Division_Graph(Line a){
if(this.EdgeCoincidence(a))
{
System.out.println("The line is coincide with one of the lines");
return;
}
int sum =0,count=0,count1=0;
Point [] x = new Point[10];
Line [] k = new Line[10];
for(Line l: line){
if(l.jiaodiannum(a)!=0){
sum+=l.jiaodiannum(a);
x[count++]=l.jiaodian(a);
k[count1++]= l;
}
}
Point s =new Point();
x= s.Coincidentpoints(x,count);
if(s.len(x)==0||s.len(x)==1){
System.out.println(x.length);
return;
}
System.out.print("2 ");
int i = 0,j;
Point [] tep =a.Line_MinPoint(point);
for ( i = 2; i < 2+s.len(tep); i++)
x[i]=tep[i-2];
Graph graph = new Graph(x,s.len(x));
System.out.println(data(min(this.getArea() - graph.getArea(), graph.getArea())) + " " + data(max(this.getArea() - graph.getArea(), graph.getArea())));
}
得到线一边最少的点
public Point[] Line_MinPoint(Point [] a){
Point[] ans1 = new Point[8];
Point[] ans2 = new Point[8];
int count=0,count1=0;
for(Point i :a)
if(!this.onxianduan(i))
if((this.x.x-i.x)*(this.y.y-i.y)-(this.x.y-i.y)*(this.y.x-i.x)>0)
ans1[count++] = i;
else
ans2[count1++]=i;
if(min(count,count1)==count)
return ans1;
else
return ans2;
}
求面积时要先对点进行排序:
点排序
static boolean PointCmp(Point a, Point b, Point center) {
if (a.x >= 0 && b.x < 0)
return true;
if (a.x == 0 && b.x == 0)
return a.y > b.y;
//向量OA和向量OB的叉积
double det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y);
if (det < 0)
return true;
if (det > 0)
return false;
//向量OA和向量OB共线,以距离判断大小
double d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y);
double d2 = (b.x - center.x) * (b.x - center.y) + (b.y - center.y) * (b.y - center.y);
return d1 > d2;
}
static Point[] ClockwiseSortPoints(Point[] vPoints, int n) {
//计算重心
double x = 0, y = 0;
for (int i = 0; i < n; i++) {
x += vPoints[i].x;
y += vPoints[i].y;
}
Point center = new Point(x / n, y / n);
//冒泡排序
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (PointCmp(vPoints[j], vPoints[j + 1], center)) {
Point tmp = vPoints[j];
vPoints[j] = vPoints[j + 1];
vPoints[j + 1] = tmp;
}
return vPoints;
}
求面积
double getArea() {
if(side<3) return 0;
Point[] point=ClockwiseSortPoints(this.point,side);//排序
double area = 0;
for (int i=1;i<side-1;i++)
area += cross(sub(point[i],point[0]),sub(point[i+1],point[0]));
area /= 2; return(area < 0 ? -area : area);
}
接下来的是五边形的类:
五边形
public class Pentagon extends Graph{
Pentagon(Point [] points){
super(points,5);
}
boolean isPentagon(){
if((line[0].jiaodiannum_2xianduan(line[3])!=0)||(line[0].jiaodiannum_2xianduan(line[2])!=0)
||(line[1].jiaodiannum_2xianduan(line[4])!=0)
||(line[2].jiaodiannum_2xianduan(line[4])!=0)||(line[1].jiaodiannum_2xianduan(line[3])!=0))
return false;
//三点共线
Line[] ll= { new Line(point[0],point[2]),new Line(point[1],point[3]),new Line(point[2],point[4]),
new Line(point[3],point[0]),new Line(point[1],point[4])} ;
if(ll[0].onxianduan(point[1])||ll[1].onxianduan(point[2])||ll[2].onxianduan(point[3])||ll[3].onxianduan(point[4])||ll[4].onxianduan(point[0]))
return false;
return true;
}
Point[] jugde( ){
if(this.isPentagon()) return point;
Point a = new Point();
Point[] ans =a.Coincidentpoints(point,5);
if(ans.length == 3) return ans;
if(ans.length == 4){
Quad quad = new Quad(ans[0],ans[1],ans[2],ans[3]);
if(quad.isQuad())
return ans;
else if(quad.line[4].onxianduan(quad. point[1])){
Point [] tep = {ans[0],ans[2],ans[3]};
return tep;
}
else if(quad.line[4].onxianduan(quad.point[3])){
Point [] tep = {ans[0],ans[1],ans[2]};
return tep;
}
else if(quad.line[5].onxianduan(quad.point[2])){
Point [] tep = {ans[0],ans[1],ans[3]};
return tep;
}
else if(quad.line[5].onxianduan(quad.point[0])){
Point [] tep = {ans[1],ans[2],ans[3]};
return tep;
}
}
int count=0;
int sum=0;
Point [] l= new Point[10];
for (int i = 0; i < line.length; i++)
for (int j = i+1; j < line.length; j++)
if(line[i].isequality(line[j])){
count ++;
if(line[i].jiaodian_tongxainxianduan(line[j])!=null)
l[sum++] =(line[i].jiaodian_tongxainxianduan(line[j]));
}
Point x= new Point();
l=x.Coincidentpoints(l,sum);
l= x.Delete(point,5,l,x.len(l));
return l;
}
}
其中最重要的是jugde方法,判断是什么形状,并返回点的集合。
类图:
SourceMonitor生成报表内容如下:
额额,这复杂度还是蛮高的,写的时候还没有觉得自己写这样的高,自我感觉良好。
(3)采坑心得:对源码的提交过程中出现的问题及心得进行总结,务必做到详实,拿数据、源码及测试结果说话,切忌假大空
(4)改进建议:对相应题目的编码改进给出自己的见解,做到可持续改进
(5)总结:对本阶段(6-9周)综合性总结,学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见。
标签:总结,p2,p1,return,tri,PTA,new,JAVA,mianji From: https://www.cnblogs.com/xzlSpiderman/p/16833266.html