给定两个凸多边形,我们的目标是确定连接它们的下切线和上切线。
如下图所示,T RL 和T LR分别代表上切线和下切线。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。
例子:
输入: 第一个多边形:[[2, 2], [3, 3], [5, 2], [4, 0], [3, 1]]
第二个多边形:[[-1, 0], [0, 1], [1, 0], [0, -2]].
输出: 上切线 - 连接 (0,1) 和 (3,3) 的线下切线 - 连接 (0,-2) 和 (4,0) 的线
****解释:****该图像清晰地显示了连接两个多边形的结构和切线

方法:
为了找到上切线,我们首先选择两个点:多边形a的最右边的点和多边形 b 的最左边的点。连接这两点的线标记为线 1 。由于这条线穿过多边形b (即,它没有完全位于其上方),我们沿逆时针方向移动到b 上的下一个点,形成线 2 。这条线现在位于多边形b 上方,这很好。但是,它与多边形a 相交,因此我们沿顺时针方向移动到a 上的下一个点,创建线 3 。线 3 仍然与多边形a 相交,促使再次移动到线 4 。然而,线 4与多边形 b 相交,因此我们继续到线 5 。最后,线 5不与任何一个多边形相交,使其成为给定多边形的正确上切线。

为了找到下切线,我们需要反向移动多边形,即,如果直线穿过多边形 b,则我们接下来顺时针移动,如果直线穿过多边形 a,则我们接下来逆时针移动。
上切线算法:
L ← 连接 a 最右边点和 b 最左边点的线。while (L 穿过任意多边形) { while(L 穿过 b) L ← L' : b 上的点向上移动。while(L 穿过 a) L ← L' : a 上的点向上移动。}
下切线算法:
L ← 连接 a 最右边点和 b 最左边点的线。 while (L 穿过任意多边形) { while (L 穿过 b) L ← L' : b 上的点向下移动。 while (L 穿过 a) L ← L' : a 上的点向下移动。 }
注意,上面的代码只计算了上切线。类似的方法也可以用来计算下切线。
示例代码:
#include <bits/stdc++.h>
using namespace std;
// Determines the quadrant of a point relative to origin
int quad(vector<int> p) {
if (p[0] >= 0 && p[1] >= 0)
return 1;
if (p[0] <= 0 && p[1] >= 0)
return 2;
if (p[0] <= 0 && p[1] <= 0)
return 3;
return 4;
}
// Returns the orientation of ordered triplet (a, b, c)
// 0 -> Collinear, 1 -> Clockwise, -1 -> Counterclockwise
int orientation(vector<int> a, vector<int> b, vector<int> c) {
int res = (b[1] - a[1]) * (c[0] - b[0]) -
(c[1] - b[1]) * (b[0] - a[0]);
if (res == 0)
return 0;
if (res > 0)
return 1;
return -1;
}
// Compare function to sort points counter-clockwise around center
bool compare(vector<int> p1, vector<int> q1, vector<int> mid) {
vector<int> p = {p1[0] - mid[0], p1[1] - mid[1]};
vector<int> q = {q1[0] - mid[0], q1[1] - mid[1]};
int one = quad(p);
int two = quad(q);
if (one != two)
return (one < two);
return (p[1] * q[0] < q[1] * p[0]);
}
// Sorts the polygon points counter-clockwise
vector<vector<int>> sortPoints(vector<vector<int>> polygon) {
vector<int> mid = {0, 0};
int n = polygon.size();
// Calculate center (centroid) of the polygon
for (int i = 0; i < n; i++) {
mid[0] += polygon[i][0];
mid[1] += polygon[i][1];
polygon[i][0] *= n;
polygon[i][1] *= n;
}
// Sort points based on their angle from the center
sort(polygon.begin(), polygon.end(),
mid\](vector\