Java 第二阶段总结

前言

这里只对四边形、五边形、以及期中考试第三题做分析。因为另外的题目挺简单的(十几行能解决的那都不是事www)。主要考察对类的设计,正则的使用,以及图形的各种性质等等。用一些ArrayList等库类可以更方便地解决问题。难度的话,我感觉还是五边形的下半部分更难一些()。如果加些时间应该可以多拿几分吧QAQ.

设计分析

类代码

这里先放四边形和五边形大作业的类代码块,代码都有注释,有需要的可以看看。下面单独的分析就不放代码了,只做分析。(类包括四边形、五边形、多边形以及点线的类代码。)

1)点类:

也没啥方法。我就后面加了个处理点集的方法:用来去除重复点和三点共线的中间点

点击查看代码
import java.util.ArrayList;

/**
 * 点类
 */
public class Point {
	//x、y 坐标
	private double x;
	private double y;

	public Point() {

	}

	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	// get 、set 方法
	public void setX(double x) {
		this.x = x;
	}

	public void setY(double y) {
		this.y = y;
	}

	public double getX() {
		return x;
	}

	public double getY() {
		return y;
	}

	/**
	 * 计算两点之间的距离
	 * 
	 * @param p 计算距离的点
	 * @return 返回距离值double
	 */
	public double getDistanceTo(Point p) {
		return Math.sqrt(Math.pow(p.getX() - this.x, 2) + Math.pow(p.getY() - this.y, 2));
	}

	/**
	 * 比较两点是否相等
	 * 
	 * @param p 比较的点
	 * @return 返回是否相等的 bool 值
	 */
	public boolean equals(Point p) {
		if (p.getX() == x && p.getY() == y) {
			return true;
		}
		return false;
	}

	@Override
	public String toString() {
		return "Point [x=" + x + ", y=" + y + "]";
	}

	/**
	 * 处理传入的点集 除去重合的点,以及 除去三点共线的中间点
	 * 还有bug 不能通过所有测试点
	 */
	public static Point[] disposePointSet(Point[] vertexes) {
		int[] flag = new int[vertexes.length]; // 标记
		for (int i = 0; i < flag.length; i++)
			flag[i] = 0;
		int num =vertexes.length;
		// 检查每一个点是否重合 选择是否进行判断
		for (int i = 0; i < vertexes.length; ++i) {
			for (int j = i + 1; j < vertexes.length; ++j) {
				if (vertexes[i].equals(vertexes[j])) {
					flag[j] = 1;
					num--;
				}
			}
		}

		// 任意三点共线 则去掉一个中间点 需要在去除重复点的基础上
		for (int i = 0; i < vertexes.length; ++i) {
			if (Line.isThreePointsCollinear(vertexes[(i-1+vertexes.length)%vertexes.length],vertexes[i],vertexes[(i+1+vertexes.length)%vertexes.length])) {
				flag[i] = 1;
				num--;
			}
		}
		//处理
		Point[] p = new Point[num];
		for (int i = 0,j = 0; j < flag.length;j++)
			if (flag[j] != 1) {
				p[i++] = new Point(vertexes[j].getX(),vertexes[j].getY());
			}
		
//		for(int i=0;i< p.length;i++) {
//			System.out.println(p[i].toString());
//		}

		return p;
	}
}

2)线类:

线类用的是直线的一般式 ,用y=kx+b会不会更好一点。这个类都是前面写的了 懒得改了
我的建议是 可以用向量积(叉乘点乘)去判断和计算位置关系或者距离等值 会更方便些

点击查看代码
//直线 Ax + By + C = 0
public class Line {
	// 构成直线的两个点
	private Point p1;
	private Point p2;
	// 直线的三个参数
	private double A;
	private double B;
	private double C;

	public Line() {
	}

	public Line(Point s1, Point s2) {
		this.A = s2.getY() - s1.getY();
		this.B = s1.getX() - s2.getX();
		this.C = s1.getY() * s2.getX() - s1.getX() * s2.getY();
		this.p1 = s1;
		this.p2 = s2;
	}

	// get、set 方法
	public Point getP1() {
		return p1;
	}

	public void setP1(Point x) {
		this.p1 = x;
	}

	public Point getP2() {
		return p2;
	}

	public void setP2(Point y) {
		this.p2 = y;
	}

	public double getA() {
		return A;
	}

	public void setA(double a) {
		A = a;
	}

	public double getB() {
		return B;
	}

	public void setB(double b) {
		B = b;
	}

	public double getC() {
		return C;
	}

	public void setC(double c) {
		C = c;
	}

	/**
	 * 判断两点是否能构成一条直线,即两点不能重合
	 * 
	 * @return 返回能否构成直线的bool值
	 */
	public boolean isLegal() {
		if (p1.getX() == p2.getX() && p1.getY() == p2.getY()) {
			return true;
		}
		return false;
	}

	/**
	 * 判断 该直线是否有斜率
	 * 
	 * @return 返回直线是否有斜率的bool值
	 */
	public boolean haveSlope() {
		if (p1.getX() != p2.getX())
			return true;
		else
			return false;
	}

	/**
	 * 计算直线的斜率 (y1-y2)/(x1-x2)
	 * 
	 * @return 返回直线的斜率
	 */
	public double getSlope() {
		return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
	}

	/**
	 * 计算点到直线的距离
	 * 
	 * @param p 传入该点
	 * @return 返回点到直线的距离
	 */
	public double getDistanceToLine(Point p) {
		double ji = Math.sqrt(A * A + B * B);
		return Math.abs(A * p.getX() + B * p.getY() + C) / ji;
	}

	/**
	 * 判断点是否在线上
	 * 
	 * @param p 需要判断的点
	 * @return 返回点是否在直线上的bool值
	 */
	public boolean isPointOnLine(Point p) {
		if (((p1.getX() - p.getX()) * (p2.getY() - p.getY()) - (p1.getY() - p.getY()) * (p2.getX() - p.getX())) == 0) {
			return true;
		}
		return false;
	}

	/**
	 * 判断 两线是否为同一条线 y = kx + b 判断k和y是否相等
	 * 
	 * @param l 需要判断的线
	 * @return 返回两条线是否为同一条线的bool值
	 */
	public boolean isSameLine(Line l) {
		if (this.getSlope() == l.getSlope() && this.isPointOnLine(l.getP1()) && this.isPointOnLine(l.getP2())) {
			return true;
		}
		return false;
	}

	/**
	 * 判断两直线是否平行
	 * 
	 * @param l 需要判断的直线
	 * @return 返回两直线是否平行的bool值
	 */
	public boolean isParallelWithLine(Line l) {
		if (l.getSlope() == getSlope())
			return true;
		else
			return false;
	}

	/**
	 * 计算两直线的交点
	 * 
	 * @param l 需要判断的直线
	 * @return 返回交点的坐标
	 */
	public Point getIntersectPoint(Line l) {
		double d = l.getA() * this.getB() - l.getB() * this.getA();
		return new Point((l.getB() * this.getC() - l.getC() * this.getB()) / d,
				(l.getC() * this.getA() - l.getA() * this.getC()) / d);
	}

	/**
	 * 判断两直线是否垂直
	 * 
	 * @param l 需要判断的线
	 * @return 返回直线是否垂直的bool值
	 */
	public boolean isVerticalLine(Line l) {
		if (p1.getDistanceTo(l.p1) == l.getDistanceToLine(this.p1)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断点是否在线的左侧
	 * 
	 * @param l 传入线
	 * @param p 需要判断位置的点
	 * @return 返回点是否在线的左侧的bool值
	 */
	public boolean isPointOnLineLeft(Point p) {
		if (((p1.getX() - p.getX()) * (p2.getY() - p.getY()) - (p1.getY() - p.getY()) * (p2.getX() - p.getX())) > 0) {
			return true;
		}
		return false;
	}

	/**
	 * 判断点是否在线的右侧
	 * 
	 * @param l 传入线
	 * @param p 需要判断的点
	 * @return 返回点是否在线的右侧的bool值
	 */
	public boolean isPointOnLineRight(Point p) {
		if ((p1.getX() - p.getX()) * (p2.getY() - p.getY()) - (p1.getY() - p.getY()) * (p2.getX() - p.getX()) < 0) {
			return true;
		}
		return false;
	}

	/**
	 * 判断点是否在构成线的两点之间 不包括点重合
	 * 
	 * @param p 需要判断的点
	 * @return 返回点是否在线段两点之间的bool值
	 */
	public boolean isBetweenLineOfPoint(Point p) {
		if ((p.getDistanceTo(p1) + p.getDistanceTo(p2)) == p1.getDistanceTo(p2) && !p.equals(p1) && !p.equals(p2))
			return true;
		else
			return false;
	}
	/**
	 * 三点共线 且任意两点不重合 
	 * @param 传入三个点
	 * @return 返回三点是否共线的Boolean 值
	 */
	public static boolean isThreePointsCollinear(Point p,Point p1,Point p2) {
		if(!p.equals(p1)&&!p.equals(p2)&&!p2.equals(p1)&&((p1.getX() - p.getX()) * (p2.getY() - p.getY()) - (p1.getY() - p.getY()) * (p2.getX() - p.getX())) == 0) {
			return true;
		}
		return false;
	}
}

3)多边形类:

多边形类只写了一些基本的判断方法,如下

点击查看代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;

public class Polygon {
	protected Line[] sides;
	protected Point[] vertexes;

	/**
	 * 多边形构造方法 这里默认为 p.length = size 即有相同多的点去构成对应的多边形 默认按点顺序连接
	 * 
	 * @param p    构成多边形的点集Point[]
	 * @param size 需要构成多边形的边数int
	 */
	public Polygon(Point[] p, int size) {
		//
		if (p.length != size)
			throw new RuntimeException("polygon constructor error");
		// 检查每一个点是否重合 选择是否进行判断
		for (int i = 0; i < p.length; ++i) {
			for (int j = i + 1; j < p.length; ++j) {
				if (p[i].equals(p[j])) {
				}
			}
		}
		vertexes = p;
		sides = new Line[size];
		// 构造边
		for (int i = 0; i < p.length; ++i) {
			sides[i] = new Line(vertexes[i], vertexes[(i + 1) % p.length]);
		}
	}

	/**
	 * 判断点集是否能构成对应的n边形
	 * 
	 * @param size 对应构成多边形的边数
	 * @return 返回是否能构成对应的多边形
	 */
	public boolean isThePolygon(int size) {
		int num = vertexes.length;
		// 检查每一个点是否重合 选择是否进行判断
		for (int i = 0; i < vertexes.length; ++i) {
			for (int j = i + 1; j < vertexes.length; ++j) {
				if (vertexes[i].equals(vertexes[j])) {
					num--;
				}
			}
		}
		// 任意三点共线 则去掉一个中间点
		for (int i = 0; i < sides.length; ++i) {
			if (sides[i].isPointOnLine(vertexes[(i + 2) % vertexes.length])) {
				num--;
			}
		}
		// 非相邻边无交点判断 即按顺序相连接
		for (int i = 0; i < sides.length; i++) {
			for (int j = i + 2; j < i + 2 + sides.length - 3; j++) {
				// 不平行且交点未在边上
				if (!sides[i].isParallelWithLine(sides[j % sides.length])
						&& sides[i].isBetweenLineOfPoint(sides[i].getIntersectPoint(sides[j % sides.length]))) {
					return false;
				}
			}
		}
		if (num == size)
			return true;
		else
			return false;
	}
	
	/**
	 *  暴力计算分割的面积
	 */
	public void splitPolygon() {
		
	}
	
	/**
	 * 判断多边形的凹凸 需判断sides.length>3 即四边及以上才具有凹凸性 利用向量的叉乘 若两边叉乘值小于0 则夹角大于180
	 * 
	 * @return 凸返回true 凹返回false
	 */
	public boolean isConcaveOrConvex() {
		double multip = 0;
		double a, b, c, d;
		for (int i = 0; i < vertexes.length; i++) {
			// 向量1
			a = vertexes[i].getX() - vertexes[(i + vertexes.length - 1) % vertexes.length].getX();
			b = vertexes[i].getY() - vertexes[(i + vertexes.length - 1) % vertexes.length].getY();
			// 向量2
			c = vertexes[(i + 1) % vertexes.length].getX() - vertexes[i].getX();
			d = vertexes[(i + 1) % vertexes.length].getY() - vertexes[i].getY();
			// 叉乘 交叉相乘
			multip = (a * d) - (c * b);
			if (multip < 0)
				return false;
		}
		return true;
	}

	/**
	 * 计算对应多边形的周长 循环计算每边长度相加
	 * 
	 * @return 返回该多边形的周长
	 */
	public double getPerimeter() {
		double sum = 0;
		for (int i = 0; i < vertexes.length; i++) {
			sum += vertexes[i].getDistanceTo(vertexes[(i + 1) % vertexes.length]);
		}
		return sum;
	}

	/**
	 * 计算对应多边形的面积 利用叉乘的定义
	 * 
	 * @return 返回该多边形的面积
	 */
	public double getArea() {
		double area = 0;
		double a, b, c, d;
		// 从第二点开始遍历节点
		for (int i = 1; i < vertexes.length - 1; i++) {
			// 向量a
			a = vertexes[i].getX() - vertexes[0].getX();
			b = vertexes[i].getY() - vertexes[0].getY();
			// 向量b
			c = vertexes[i + 1].getX() - vertexes[0].getX();
			d = vertexes[i + 1].getY() - vertexes[0].getY();
			// 叉乘
			area += a * d - b * c;

		}
		return area / 2;
	}
	
//	public int getIntersectionNumPolygon(Line l) {
//		
//	}
	
	/**
	 * 判断点是否与多边形的顶点重合
	 * 
	 * @param p 需要判断的点
	 * @return 返回该点是否与多边形顶点重合的bool值
	 */
	public boolean isPolygonVertex(Point p) {
		for (Point vertex : vertexes) {
			if (p.equals(vertex))
				return true;
		}
		return false;
	}

	/**
	 * 判断点是否在多边形的边上 包括顶点重合的情况
	 * 
	 * @param p 需要判断的点
	 * @return 返回该点是否在边上的bool值
	 */
	public boolean isPointOnPolygonSide(Point p) {
		// 分别与每边比较
		for (int i = 0; i < sides.length; ++i) {
			if ((p.getDistanceTo(vertexes[i]) + p.getDistanceTo(vertexes[(i + 1) % vertexes.length])) == sides[i].getP1()
					.getDistanceTo(sides[i].getP2()))
				return true;
		}
		return false;
	}

	/**
	 * 判断点是否在多边形上 分别判断顶点和边的情况
	 * 
	 * @param p 需要判断的点
	 * @return 返回是否在多边形边上的bool值
	 */
	public boolean isPointOnPolygon(Point p) {
		if (isPolygonVertex(p) || isPointOnPolygonSide(p)) {
			return true;
		} else
			return false;
	}

	/**
	 * 判断线是否是多边形的边 即与边重合
	 * 
	 * @param l
	 * @return
	 */
	public boolean haveCoincideLine(Line l) {
		for (Line line : sides) {
			if (l.isSameLine(line)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断 点是否在多边形里 射线法判断 以传入点 p(x0,y0)、p1(x0 + 1, y0) 构造一线 l 计算 l 与多边形各边交点, 
	 * 并统计交点 x坐标大于 x0 的数量 c 若c为奇数则点一定在多边形内 c为偶数则在多边形外
	 * 
	 * @param p 需要判断的点
	 * @return 是否在多边形里的bool值
	 */
	public boolean isPointInPolygon(Point p) {
		Traingle tra[] =new Traingle[vertexes.length];
		double sum=0;
		for(int i=0;i<vertexes.length;i++) {
			tra[i] = new Traingle(new Point[] {p,vertexes[i],vertexes[(i+1+vertexes.length)%vertexes.length]});
		}
		for(int i=0;i<tra.length;i++)
			sum += tra[i].getArea();
		return sum == this.getArea(); 
//		int cnt = 0;
//		Point p1 = new Point(p.getX() + 1, p.getY());
//		Line l = new Line(p1, p);
//		for (Line line : sides) {
//			Point cross = line.getIntersectPoint(l);
//			if (line.isBetweenLineOfPoint(cross))
//				if (cross.getX() > p.getX()) {
//					++cnt;
//				}
//		}
//		return cnt % 2 != 0;
	}
}

4)四边形类:

点击查看代码
public class Quadrangle extends Polygon {
	// 构造函数
	public Quadrangle(Point[] p) {
		super(p, 4);
	}

	// 平行四边形
	public boolean isParallelQuard() {
		if (this.vertexes[0].getDistanceTo(vertexes[1]) == this.vertexes[2].getDistanceTo(vertexes[3])
				&& this.vertexes[1].getDistanceTo(vertexes[2]) == this.vertexes[3].getDistanceTo(vertexes[0])) {
			return true;
		} else
			return false;
	}

	// 矩形
	public boolean isRectangle() {
		if (this.isParallelQuard()) {
			if (this.sides[0].isVerticalLine(this.sides[1])) {
				return true;
			}
		}
		return false;
	}

	// 菱形
	public boolean isRhombus() {
		if (this.isParallelQuard()) {
			if (this.vertexes[0].getDistanceTo(vertexes[1]) == this.vertexes[2].getDistanceTo(vertexes[1])) {
				return true;
			}
		}
		return false;
	}

	// 正方形
	public boolean isSquare() {
		if (this.isRectangle()) {
			if (this.vertexes[0].getDistanceTo(vertexes[1]) == this.vertexes[1].getDistanceTo(vertexes[2])) {
				return true;
			}
		}
		return false;
	}

	// 返回四边形交点数量
	public int getIntersectionNum(Line l) {
		int num = 0, leftn = 0, rightn = 0;
		for (int i = 0; i < this.vertexes.length; i++) {
			if (l.isPointOnLineLeft(vertexes[i])) {
				leftn++;
			}
			if (l.isPointOnLineRight(vertexes[i])) {
				rightn++;
			}
		}
		// 四边形判断 凹凸
		if (this.isConcaveOrConvex()) {
			if (leftn == 0 || leftn == 4)
				num = 0;
			else if ((leftn == 3 && rightn == 0) || (leftn == 0 && rightn == 3))
				num = 1;
			else
				num = 2;
		} else {
			if (leftn == 0 || leftn == 4)
				num = 0;
			else if ((leftn == 3 && rightn == 0) || (leftn == 0 && rightn == 3))
				num = 1;
			else if ((leftn == 1 && rightn == 2) || (leftn == 2 && rightn == 1))
				num = 3;
			else if (leftn == 2 && rightn == 2)
				num = 4;
			else
				num = 2;
		}
		return num;
	}

	// 分割面积 四边形分割
	public Polygon splitQuadrangle(Line l) {
		Polygon polygon = new Polygon();
		Point[] p = new Point[2];
		// 分割成两个四边形
		for (int i = 0; i < 2; i++) {
			if (this.isPointOnPolygon(l.getIntersectPoint(sides[i]))
					&& this.isPointOnPolygon(l.getIntersectPoint(sides[i + 2]))) {
				p[0] = new Point(l.getIntersectPoint(sides[i]).getX(), l.getIntersectPoint(sides[i]).getY());
				p[1] = new Point(l.getIntersectPoint(sides[i + 2]).getX(), l.getIntersectPoint(sides[i + 2]).getY());
				polygon = new Quadrangle(new Point[] { p[0], vertexes[i + 1], vertexes[i + 2], p[1] });
			}
		}

		// 分割成一个三角和一个四边形
		for (int i = 0; i < sides.length; i++) {
			if (this.isPointOnPolygon(l.getIntersectPoint(sides[i]))
					&& this.isPointOnPolygon(l.getIntersectPoint(sides[(i + 1) % 4]))) {
				p[0] = new Point(l.getIntersectPoint(sides[i]).getX(), l.getIntersectPoint(sides[i]).getY());
				p[1] = new Point(l.getIntersectPoint(sides[(i + 1) % 4]).getX(),
						l.getIntersectPoint(sides[(i + 1) % 4]).getY());
				polygon = new Traingle(new Point[] {p[0], p[1], vertexes[(i + 1) % 4]});
				break;
			}
		}
		return polygon;
		
	}
}

5)五边形类:

点击查看代码
import java.util.ArrayList;

public class Pentagon extends Polygon {

	public Pentagon(Point[] p) {
		super(p, 5);
	}

	/**
	 * 求直线与五边形的交点数量
	 * 
	 * @param l 需要判断的直线
	 * @return 返回五边形交点数量
	 */
	public int getIntersectionNum(Line l) {
		int num = 0,left = 0,right=0;
		for (int i = 0; i < vertexes.length; i++) {
			if (l.isPointOnLineLeft(vertexes[i])) {
				left++;
			}if(l.isPointOnLineRight(vertexes[i])) {
				right++;
			}
		}
		if(left==5||left==0)
			num=0;
		else if((left==4 &&right==0)||(left==0 &&right==4))
			num=1;
		else num=2;
		return num;
	}
	
	/**
	 * 求线切割后的面积
	 * @param l 传入线
	 */
	public void splitByLine(Line l) {
		int place[] =new int[2],j = 0;//存 交点在线上的位置 包括交点与顶点重合
		int flag = 0; //动态确定加入点的位置
		ArrayList<Point> points = new ArrayList<Point>();
		for(int i=0;i<vertexes.length;i++)
			points.add(vertexes[i]);
		//对交点操作
		for(int i=0;i<vertexes.length&&j<2;i++) {
				if (vertexes[i].equals(sides[i].getIntersectPoint(l))) {
					place[j++] = i;
				}
				else if(sides[i].isBetweenLineOfPoint(sides[i].getIntersectPoint(l))) {
					points.add(i+1+flag, sides[i].getIntersectPoint(l));
					flag++;
					place[j++] = i + flag;
				}
		}
		
		//计算面积
		Point p[] = new Point[place[1]-place[0]+1];
		for(int i=0;i<p.length;i++) {
			p[i] = new Point(points.get(i).getX(),points.get(i).getY());
		}
		Polygon po =new Polygon(p,p.length);
		String temp = String.format("%.3f",po.getArea());
                double area1 = Double.parseDouble(temp);
                temp = String.format("%.3f",this.getArea() - po.getArea());
                double area2 = Double.parseDouble(temp);
                System.out.print(" " + Math.min(area1,area2) + " "
				+ Math.max(area1,area2));
	}
}

6)输入处理类:

对字符串进行处理,先格式匹配判断合法,再分离出对应的点集

点击查看代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Inputer {
	private String str;

	public Inputer(String string) {
		str = string;
	}

	/**
	 * 对传入的字符串进行匹配 判断输入是否符合要求
	 * 
	 * @return 返回是否匹配成功的bool值
	 */
	public boolean matchString() {
		String regEx = "^[1-6]:([+-]?\\d+(\\.\\d+)?,[+-]?\\d+(\\.\\d+)?\\s?)+$";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		if (!m.matches()) {
			System.out.print("Wrong Format");
			return false;
		}
		//特判 0x 的情况
		String po = str.substring(2, str.length());
		String[] x = po.split("[, ]");
		for (String i : x) {
			String[] j = i.split("\\.");
			if (!j[0].matches("[+-]?(0|[1-9][0-9]*)")) {
				System.out.print("Wrong Format");
				return false;
			}
		}
		return true;
	}

	// 返回 选项
	public String selectNum() {
		return str.substring(0, 1);
	}

	/**
	 * 对字符串进行处理 分离点集
	 * 
	 * @return 返回输入的点集
	 */
	public Point[] disposeString() {
		String[] num = str.split("[:, ]"), a = str.split(" ");
		Point[] p = new Point[a.length];
		for (int i = 1, j = 0; i < num.length && j < a.length; i += 2, j++) {
			p[j] = new Point();
			p[j].setX(Double.parseDouble(num[i]));
			p[j].setY(Double.parseDouble(num[i + 1]));
		}
		return p;
	}
}

7-2 点线形系列4-凸四边形的计算

当时做这题的时候还没有写多边形类,就是把每种情况都列出来(反正也就两三种情况 ovo),就感觉还在写c,对类没有清楚的认识。

题目要求如下

用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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"。

这题写到面一直有两个点过不去,de了半天才发现1,3 位置点重复也行,就加了一个判断。另一个测试点是逻辑判断问题,就是四边形,三角形要先判断是否能构成,再判断线与边重合的情况(好像是这样,时间久有点忘了QAQ)

类图以及报表:

点线形系列5-凸五边形的计算

做这题之前把类重构好,直接用多边形类真的很方便,可以少写很多东西。当时写的时候时间有点紧,第二部分就没写多少。凑合看QAQ。

题目要求如下

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的
顶点相邻。
选项包括:
1:输入五个点坐标,判断是否是五边形,判断结果输出 true/false。
2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周
长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出"not a pentagon"
3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个五边形、四边形或三角形,输出直线与五
边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的
面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若
后五个点不符合五边形输入,若前两点重合,输出"points coincide"。
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"。
以上 3、4、5、6 选项中,若输入的点无法构成多边形,则输出"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
输入格式:
基本格式:选项+":"+坐标 x+","+坐标 y+" "+坐标 x+","+坐标 y。点的 x、y 坐标之间以英文","
分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过 3 位,只保留小数点后 3 位,多余部分采用四舍五入规则
进到最低位。小数点后若不足 3 位,按原始位数显示,不必补齐。例如:1/3 的结果按格式
输出为 0.333,1.0 按格式输出为 1.0

类图以及报表:

期中考试-7-3 点线面问题再重构

期中考试的内容真的很简单啊,这里就只看第三题,前面两题直接把以前写的点线类拿过来用即可,没什么好讲的。

在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。

在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList类型的对象(若不了解泛型,可以不使用
增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象
在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:
1:向容器中增加Point对象
2:向容器中增加Line对象
3:向容器中增加Plane对象
4:删除容器中第index - 1个数据,若index数据非法,则无视此操作
0:输入结束
示例代码如下:
choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://insert Point object into list ... break; case 2://insert Line object into list ... break; case 3://insert Plane object into list ... break; case 4://delete index - 1 object from list int index = input.nextInt(); ... } choice = input.nextInt(); }
输入结束后,按容器中的对象顺序分别调用每个对象的display()方法进行输出。

以下情况为无效作业

  • 无法运行
  • 设计不符合所给类图要求
  • 未通过任何测试点测试
  • 判定为抄袭

输入格式:
switch(choice) { case 1://insert Point object into list 输入“点”对象的x,y值 break; case 2://insert Line object into list 输入“线”对象两个端点的x,y值 break; case 3://insert Plane object into list 输入“面”对象的颜色值 break; case 4://delete index - 1 object from list 输入要删除的对象位置(从1开始) ... }
输出格式:

  • Point、Line、Plane的输出参考题目2
  • 删除对象时,若输入的index超出合法范围,程序自动忽略该操作

代码如下:

点击查看代码
import java.util.ArrayList;
import java.util.Scanner;

public class Mid_Text {
	public static void main(String[] args) {
	    Scanner in = new Scanner(System.in);
            GeometryObject g = new GeometryObject();
	    int choice = in.nextInt();
	    double x,y;
	    String color;
	    while(choice != 0) {
	        switch(choice) {
	        case 1://insert Point object into list 
	            x = in.nextDouble();
	            y = in.nextDouble();
	            if(x <=0 || x>200 || y <=0 || y>200) {
	    			System.out.print("Wrong Format");
	    			break;
	    		}
	            Point p = new Point(x,y);
	            g.add(p);
	            break;
	        case 2://insert Line object into list
	        	x = in.nextDouble();
	            y = in.nextDouble();
	            if(x <=0 || x>200 || y <=0 || y>200) {
	    			System.out.print("Wrong Format");
	    			break;
	            }
	    		Point p1 = new Point(x,y);
	    		x = in.nextDouble();
	            y = in.nextDouble();
	            if(x <=0 || x>200 || y <=0 || y>200) {
	    			System.out.print("Wrong Format");
	    			break;
	            }
	    		Point p2 = new Point(x,y);
	        	color = in.next();
	    		Line l = new Line(p1,p2,color);
	    		g.add(l);
	            break;
	        case 3://insert Plane object into list
	            Plane plane = new Plane();
	            color = in.next();
	            plane.setColor(color);
	            g.add(plane);
	            break;
	        case 4://delete index - 1 object from list
	            int index = in.nextInt();
	            if(g.getList().size() < index)
	            	break;
	            else 
                    g.remove(index);
	        }
	        choice = in.nextInt();
	    }
		for(int i=0;i<g.getList().size();i++) {
			g.getList().get(i).display();
		}
	}
	
}
abstract class Element{
	public abstract void display();
}
class Point extends Element{
	private double x;
	private double y;

	public Point() {

	}

	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	// get 、set 方法
	public void setX(double x) {
		this.x = x;
	}

	public void setY(double y) {
		this.y = y;
	}

	public double getX() {
		return x;
	}

	public double getY() {
		return y;
	}
	@Override
	public void display() {
		System.out.printf("(%.2f,%.2f)\n", x,y);
	}
	/**
	 * 计算两点之间的距离
	 * 
	 * @param p 计算距离的点
	 * @return 返回距离值double
	 */
	public double getDistanceTo(Point p) {
		return Math.sqrt(Math.pow(p.getX() - this.x, 2) + Math.pow(p.getY() - this.y, 2));
	}
}
class Line extends Element{
	// 构成线段的两个点
	private Point point1;
	private Point point2;
	private String color;
	public Line() {
		
	}

	public Line(Point p1, Point p2,String color) {
		this.point1 = p1;
		this.point2 = p2;
		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() {
		return Math.sqrt(Math.pow(point1.getX() - point2.getX(), 2) + Math.pow(point1.getY() - point2.getY(), 2));
	}
	@Override
	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.print("The line's length is:");
		System.out.printf("%.2f\n", this.getDistance());
	}
}
class Plane extends Element{
	String color;

	public Plane(){
		
	}
	public 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 GeometryObject{
	private ArrayList<Element> list = new ArrayList<Element>();
	
	public GeometryObject() {
		
	}
	public void remove(int index) {
		list.remove(index - 1);
	}
	
	public void add(Element element) {
		list.add(element);
	}
	
	public ArrayList<Element> getList() {
		return list;
	}

}

类图以及报表:

踩坑心得

发现自己debug的能力真的不行,有时候会因为一个测试点de半天都发现不了。有时候bug de出来了,但又会出现新的bug。属于是正常操作了QAQ
需要对输出的数格式化处理时,String.format()与System.out.printf() 都能用,只不过得看情况选择。

改进建议

  1. 写代码时,应该先弄清楚类与类之间的关系,设计好类的结构,画好类图,这样思路才能更清晰。
  2. 可以多用用Java库中写好的类方法,以及像ArrayList、StringBuffer等可变容量的结构,这样会使程序更加灵活,不用每次都去更改数组的大小。
  3. 可以在类中改写toString方法,可以更方便的进行调试分析。需不要每次都加一个System.out.print去输出信息。、
  4. 每个类方法以及属性,包括方法中的每个步骤都尽量在旁边写注释,这样才不至于在写完后就忘了怎么来的。
  5. 每个类应该遵循单一职责的原则,即属于该类的职责就放到该类下,反之则不放入。(在五边形的分割面积时就偷懒直接在类方法下直接输出了T_T ,其实可以直接写一个output方法,对输出的内容单独进行处理,这样条理就十分清晰了)

总结

总的来说,经过这几次大作业的学习,收获还是非常多的。学习到了很多关于java的知识点,比如说Obeject类等。

posted @ 2022-10-29 15:57  不羡仙z  阅读(71)  评论(0)    收藏  举报