找到从矩形到点数组的最近点
Find nearest point from a rectangle to array of points
我有一个矩形和点 (pts) 数组。点可以在矩形内,也可以不在矩形内。我需要在矩形内找到一些点 P(x, y) 到 P 之间的最大距离,并且来自 pts 的每个点将是最小的。
换句话说,对于矩形内的所有 space,我需要选择函数 Dist 的值最小的一个点。
float Dist(Vector2 p, Vector2[] pts)
{
float d = float.MinValue;
foreach (Vector2 point in pts)
{
float dx = point.x - p.x;
float dy = point.y - p.y;
d = Math.Max(d, Math.Sqrt(dx * dx + dy * dy));
}
return d;
}
移除位于矩形内的点 P 的约束会将其变成 the smallest circle problem,它具有线性最坏情况解和简单的随机预期线性时间解。你的问题也可以化为最小圆问题,线性时间内解决。
对于矩形左侧垂直边 l 左侧的每个点 A,考虑其相对于 l 的镜像 A'。如果圆心在矩形内部的圆包含点 A,则它也必须包含 A'。让我们为左侧的左侧、右侧的右侧、上侧的上方和下侧的下方的每个点构造相应的镜像,并将它们添加到集合中。对于“角”点,如图中的 B 点,我们还添加了它们镜像的镜像(B''' 点必须也在包含 B 的任何圆中)。请注意在构造的集合中,每个点如何位于矩形的水平边界之间,或者在矩形的水平边之一上具有镜像。垂直边也是如此。事实证明,所得到的点集的最小外接圆的中心始终位于矩形内。
确实,考虑最小外接圆的水平直径。必须至少有一个点位于圆的封闭(即包括端点)上半部分,否则圆半径可能会缩小。但是矩形的上边界不允许严格位于直径以下,否则我们的点穿过水平线的镜像将结束在圆之外。以此类推,矩形的下边界不能在直径之上,左边界不能在垂直直径的右边,右边界不能在垂直直径的左边。这意味着圆心在矩形内部,Q.E.D。
Vector2 Center(Rectangle rectangle, Vector2[] pts) {
extended_pts = []
foreach (Vector2 point in pts) {
extended_pts.append(point)
if (point.x < rectangle.x_min) {
extended_pts.append((2*rectangle.x_min - point.x, point.y));
if (point.y < rectangle.y_min)
extended_pts.append((2*rectangle.x_min - point.x, 2*rectangle.y_min - point.y));
if (point.y > rectangle.y_max)
extended_pts.append((2*rectangle.x_min - point.x, 2*rectangle.y_max - point.y));
}
if (point.x > rectangle.x_max)
extended_pts.append((2*rectangle.x_max - point.x, point.y));
if (point.y < rectangle.y_min)
extended_pts.append((2*rectangle.x_max - point.x, 2*rectangle.y_min - point.y));
if (point.y > rectangle.y_max)
extended_pts.append((2*rectangle.x_max - point.x, 2*rectangle.y_max - point.y));
if (point.y < rectangle.y_min)
extended_pts.append((point.x, 2*rectangle.y_min - point.y));
if (point.y > rectangle.y_max)
extended_pts.append((point.x, 2*rectangle.y_max - point.y));
}
return SmallestCircleCenter(extended_pts);
}
我有一个矩形和点 (pts) 数组。点可以在矩形内,也可以不在矩形内。我需要在矩形内找到一些点 P(x, y) 到 P 之间的最大距离,并且来自 pts 的每个点将是最小的。
换句话说,对于矩形内的所有 space,我需要选择函数 Dist 的值最小的一个点。
float Dist(Vector2 p, Vector2[] pts)
{
float d = float.MinValue;
foreach (Vector2 point in pts)
{
float dx = point.x - p.x;
float dy = point.y - p.y;
d = Math.Max(d, Math.Sqrt(dx * dx + dy * dy));
}
return d;
}
移除位于矩形内的点 P 的约束会将其变成 the smallest circle problem,它具有线性最坏情况解和简单的随机预期线性时间解。你的问题也可以化为最小圆问题,线性时间内解决。
对于矩形左侧垂直边 l 左侧的每个点 A,考虑其相对于 l 的镜像 A'。如果圆心在矩形内部的圆包含点 A,则它也必须包含 A'。让我们为左侧的左侧、右侧的右侧、上侧的上方和下侧的下方的每个点构造相应的镜像,并将它们添加到集合中。对于“角”点,如图中的 B 点,我们还添加了它们镜像的镜像(B''' 点必须也在包含 B 的任何圆中)。请注意在构造的集合中,每个点如何位于矩形的水平边界之间,或者在矩形的水平边之一上具有镜像。垂直边也是如此。事实证明,所得到的点集的最小外接圆的中心始终位于矩形内。
确实,考虑最小外接圆的水平直径。必须至少有一个点位于圆的封闭(即包括端点)上半部分,否则圆半径可能会缩小。但是矩形的上边界不允许严格位于直径以下,否则我们的点穿过水平线的镜像将结束在圆之外。以此类推,矩形的下边界不能在直径之上,左边界不能在垂直直径的右边,右边界不能在垂直直径的左边。这意味着圆心在矩形内部,Q.E.D。
Vector2 Center(Rectangle rectangle, Vector2[] pts) {
extended_pts = []
foreach (Vector2 point in pts) {
extended_pts.append(point)
if (point.x < rectangle.x_min) {
extended_pts.append((2*rectangle.x_min - point.x, point.y));
if (point.y < rectangle.y_min)
extended_pts.append((2*rectangle.x_min - point.x, 2*rectangle.y_min - point.y));
if (point.y > rectangle.y_max)
extended_pts.append((2*rectangle.x_min - point.x, 2*rectangle.y_max - point.y));
}
if (point.x > rectangle.x_max)
extended_pts.append((2*rectangle.x_max - point.x, point.y));
if (point.y < rectangle.y_min)
extended_pts.append((2*rectangle.x_max - point.x, 2*rectangle.y_min - point.y));
if (point.y > rectangle.y_max)
extended_pts.append((2*rectangle.x_max - point.x, 2*rectangle.y_max - point.y));
if (point.y < rectangle.y_min)
extended_pts.append((point.x, 2*rectangle.y_min - point.y));
if (point.y > rectangle.y_max)
extended_pts.append((point.x, 2*rectangle.y_max - point.y));
}
return SmallestCircleCenter(extended_pts);
}