我正在解决以下问题:
给定二维平面上的两个正方形,求一条直线使把这两个正方形切成两半。假设顶部和底部正方形的各边平行于x轴。
这是书中的解决方案:
public class Square {
public double left;
public double top;
public double bottom;
public double right;
public double size;
public Square(double left, double top, double size) {
this.left = left;
this.top = top;
this.bottom = top + size;
this.right = left + size;
this.size = size;
}
public Point middle() {
return new Point((this.left + this.right)/2.0, (this.top + this.bottom)/2.0);
}
public boolean contains(Square other) {
if (this.left <= other.left && this.right >= other.right && this.top <= other.top && this.bottom >= other.bottom) {
return true;
}
return false;
}
/* Return the point where the line segment connecting mid1 and
* mid2 intercepts the edge of square 1. That is, draw a line
* from mid2 to mid1, and continue it out until the edge of
* the square. */
public Point extend(Point mid1, Point mid2, double size) {
/* Find what direction the line mid2 -> mid1 goes */
double xdir = mid1.x < mid2.x ? -1 : 1;
double ydir = mid1.y < mid2.y ? -1 : 1;
/* If mid1 and mid2 have the same x value, then the slope
* calculation will throw a divide by 0 exception. So, we
* compute this specially. */
if (mid1.x == mid2.x) {
return new Point(mid1.x, mid1.y + ydir * size / 2.0);
}
double slope = (mid1.y - mid2.y) / (mid1.x - mid2.x);
double x1 = 0;
double y1 = 0;
/* Calculate slope using the equation (y1 - y2) / (x1 - x2).
* Note: if the slope is “steep” (>1) then the end of the
* line segment will hit size / 2 units away from the middle
* on the y axis. If the slope is “shallow” (<1) the end of
* the line segment will hit size / 2 units away from the
* middle on the x axis. */
if (Math.abs(slope) == 1) {
x1 = mid1.x + xdir * size / 2.0;
y1 = mid1.y + ydir * size / 2.0;
} else if (Math.abs(slope) < 1) {
x1 = mid1.x + xdir * size / 2.0;
y1 = slope * (x1 - mid1.x) + mid1.y;
} else {
y1 = mid1.y + ydir * size / 2.0;
x1 = (y1 - mid1.y) / slope + mid1.x;
}
return new Point(x1, y1);
}
public Line cut(Square other) {
/* Calculate where a line between each middle would collide with the edges of the squares */
Point p1 = extend(this.middle(), other.middle(), this.size);
Point p2 = extend(this.middle(), other.middle(), -1 * this.size);
Point p3 = extend(other.middle(), this.middle(), other.size);
Point p4 = extend(other.middle(), this.middle(), -1 * other.size);
/* Of above points, find start and end of lines. Start is farthest left (with top most as a tie breaker)
* and end is farthest right (with bottom most as a tie breaker */
Point start = p1;
Point end = p1;
Point[] points = {p2, p3, p4};
for (int i = 0; i < points.length; i++) {
if (points[i].x < start.x || (points[i].x == start.x && points[i].y < start.y)) {
start = points[i];
} else if (points[i].x > end.x || (points[i].x == end.x && points[i].y > end.y)) {
end = points[i];
}
}
return new Line(start, end);
}
public String toString() {
return "(" + left + ", " + top + ")|(" + right + "," + bottom + ")";
}
}
我有以下问题:
扩展函数中的size参数是什么?什么的大小?边吗?整个正方形(我们如何量化整个正方形的大小?)区域吗?
在cut()函数中,p1到p4最终在做什么?为什么我们需要4个点呢?
根据我的理解,这条线连接两个中心是必要的,也是足够的。
假设正方形的上下边平行于x轴。
我不知道为什么这个假设是必要的
这个答案可能与TS无关,但如果你也想知道这个答案,参数"size"是误导-它指的是正方形的长度(例如3x3正方形的长度为3)。为什么是四点?因为这个问题假设这条线代表两个"最远"的点,它们穿过两个正方形。每个正方形有两个点,它们有可能成为直线的起点/终点。