好久没有发过文章了,今天心情好,分享以下今天的java作业吧。
题目要求是,构造多边形,并在点无法构造多边形时抛出对应的异常原因。
直接上代码:
1.构造点坐标:
public class Point
{
public int x,y;
public Point(int x,int y) throws IllegalArgumentException
{
this.x = x;
this.y = y;
if(x<0||y<0)
{
throw new IllegalArgumentException("点坐标不能小于0");
}
}
public String toString()
{
return "("+this.x+","+this.y+")";
}
}
2.开始我们多边形的构造吧:
public class Polygon {
public Point[] points;
public Polygon(Point[] points) throws IllegalArgumentException
{
this.points = points;
double[] slopes = new double[points.length];
//判断是否大于三个点
if(points.length<3)
{
throw new IllegalArgumentException("多边形不能小于3个点");
}
//==============================先对各个点的x坐标进行排序,是x最小的点排在第一个=================================
for (int g = 0; g < points.length-1; g++) {
//第一轮,两两比较
for (int t = 0; t < points.length-g-1; t++) {
if (points[t].x>points[t+1].x) {
Point temp1=points[t];
points[t]=points[t+1];
points[t+1]=temp1;
}
}
}
/*
for(int y=0;y<points.length;y++)
{
System.out.println(points[y]);
}
*/
slopes[0] = 100000000000000.0;//将低一个直接赋值为一个巨大的值,也就是默认第一个点位置不变
//对除了第一个点的所有点求与第一个点的斜率
for(int f=1;f<points.length;f++)
{
if(points[0].x-points[f].x==0)
slopes[f] = 10000000000000.0;
else
slopes[f]=Slope(points[0],points[f]);
}
/*
for(int y=0;y<slopes.length;y++)
{
System.out.println(slopes[y]);
}
*/
//利用冒泡排序法通过对斜率的排序来对坐标顺序进行更改
for (int l = 0; l < points.length-1; l++) {
//第一轮,两两比较
for (int p = 0; p < points.length-1; p++) {
if (slopes[p]<slopes[p+1]) {
double temp=slopes[p];
slopes[p]=slopes[p+1];
slopes[p+1]=temp;
Point temp1=points[p];
points[p]=points[p+1];
points[p+1]=temp1;
}
}
}
/*
for(int y=0;y<points.length;y++)
{
System.out.println(points[y]);
}
*/
//=====================================判断相邻两边是否共线=======================================================
double av0 = (points[0].y - points[points.length-1].y)/(points[0].x -points[points.length-1].x);
for(int j = 0;j<points.length-2;j++)
{
if(points[j].x -points[j+1].x==0&&points[j+1].x -points[j+2].x!=0)
continue;
else if(points[j].x -points[j+1].x!=0&&points[j+1].x -points[j+2].x==0)
continue;
else if(points[j].x -points[j+1].x==0&&points[j+1].x -points[j+2].x==0)
throw new IllegalArgumentException("多边形任意相邻两条边不能共线");
else
{
double av1 = (points[j].y - points[j+1].y)/(points[j].x -points[j+1].x);
double av2 = (points[j+1].y - points[j+2].y)/(points[j+1].x -points[j+2].x);
if(av1==av2)
throw new IllegalArgumentException("多边形任意相邻两条边不能共线");
if(av0==av2)
throw new IllegalArgumentException("多边形任意相邻两条边不能共线");
}
}
//==================================判断内角和是否合理=========================================
double h0 = LineLength(points[0],points[1]);
double h1 = LineLength(points[0],points[points.length-1]);
double h2 = LineLength(points[points.length-1],points[points.length-2]);
double hh1 = LineLength(points[1],points[points.length-1]);
double hh2 = LineLength(points[0],points[points.length-2]);
double Ca = Math.toDegrees(Math.acos((hh1 * hh1 - h1 * h1 - h0 * h0) / (-2 * h1 * h0)));
double Cb = Math.toDegrees(Math.acos((hh2 * hh2 - h1 * h1 - h2 * h2) / (-2 * h1 * h2)));
double sumAngle = Ca+Cb;
//System.out.println(sumAngle);
for(int k = 0;k<points.length-2;k++)
{
double a = LineLength(points[k],points[k+1]);
double b = LineLength(points[k+1],points[k+2]);
double c = LineLength(points[k],points[k+2]);
double C = Math.toDegrees(Math.acos((c * c - a * a - b * b) / (-2 * a * b)));
//System.out.println(C);
sumAngle = sumAngle + C;
}
System.out.println(sumAngle);//这里的角度之和是浮点数,因为去的位数有限,只能无限逼近正确值
int theBEST = (int) Math.ceil(sumAngle);//将这个数值四舍五入转换为整型
if(theBEST!=180*(points.length-2))
throw new IllegalArgumentException("多边形内角和应为(n-2)*pi");
}
public double LineLength(Point point1,Point point2)
{
//返回两点间的距离
return Math.sqrt(Math.pow((point1.x-point2.x),2)+Math.pow((point1.y-point2.y),2));
}
public double Slope(Point point1,Point point2)
{
//返回两点间的斜率
double e1 = (point1.y-point2.y);
double e2 = (point1.x-point2.x);
return e1/e2;
}
public String toString()
{
String str = points.length+"个点"+this.points[0].toString();
for(int i = 1;i<points.length;i++)
str +=","+this.points[i].toString();
return str;
}
就用了一点时间所以写的有些繁琐,大体说一下思路吧,首先多边形我们是不确定它到底有几条边,所以在初始化的时候要用列表来存储所有的点。
思路:取x坐标最大的点A(如果最大x坐标的点不止一个,则取Y坐标最小的点),依次计算A点与其余各点的连线与水平线之间夹角的正切值,然后按照正切值排序,依次连接排序后的各点即组成一个简单图形。
原理:其它所有点都在A点的左侧,所有夹角的范围为-Pi/2~Pi/2,单调递增函数。
利用以上算法即可实现多边形的构造,但未必就是合格的多边形
对于异常处理,主要是用来验证这些点是否能够连成多边形:
1.点的数量必须大于3,小学生都知道。
2.相邻的两边不能共线,共线的话就会合成一条边,但目前还不能确定点是否可以组成多边形
3.那么当内角和必须等于(n-2)*pi时,就弥补了前两个条件的漏洞。
测试代码:
public static void main(String[] args)
{
Point point4 = new Point(1,1);
Point point5 = new Point(1,2);
Point point6 = new Point(2,1);
Point point7 = new Point(2,2);
Point points[] = {point4,point5,point6,point7};
Polygon a2 = new Polygon(points);
String a21 = a2.toString();
System.out.println(a21);
}
随便找了个正方形验证一下:
结果没有抛出异常,大家可以改改数据,抛抛异常,挺好玩的哦。
如果这片文章对你有所帮助的话,那么请点个赞,关个注呦,后续会更新更多内容~