C/C++ 两个凸多边形之间的切线(Tangents between two Convex Polygons)

给定两个凸多边形,我们的目标是确定连接它们的下切线和上切线。

如下图所示,T RLT 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\ p1, vector\ p2) { return compare(p1, p2, mid); }); // Divide back to original coordinates for (int i = 0; i \< n; i++) { polygon\[i\]\[0\] /= n; polygon\[i\]\[1\] /= n; } return polygon; } // Finds the upper tangent between two convex polygons a and b // Returns two points forming the upper tangent vector\\> findUpperTangent(vector\\> a, vector\\> b) { int n1 = a.size(), n2 = b.size(); // Find the rightmost point of polygon a and leftmost point of polygon b int maxa = INT_MIN; for (auto\& p : a) maxa = max(maxa, p\[0\]); int minb = INT_MAX; for (auto\& p : b) minb = min(minb, p\[0\]); // Sort both polygons counter-clockwise a = sortPoints(a); b = sortPoints(b); // Ensure polygon a is to the left of polygon b if (minb \< maxa) swap(a, b); n1 = a.size(); n2 = b.size(); // Find the rightmost point in a int ia = 0, ib = 0; for (int i = 1; i \< n1; i++) if (a\[i\]\[0\] \> a\[ia\]\[0\]) ia = i; // Find the leftmost point in b for (int i = 1; i \< n2; i++) if (b\[i\]\[0\] \< b\[ib\]\[0\]) ib = i; // Initialize starting points int inda = ia, indb = ib; bool done = false; // Find upper tangent using orientation checks while (!done) { done = true; // Move to next point in a if necessary while (orientation(b\[indb\], a\[inda\], a\[(inda + 1) % n1\]) \> 0) inda = (inda + 1) % n1; // Move to previous point in b if necessary while (orientation(a\[inda\], b\[indb\], b\[(n2 + indb - 1) % n2\]) \< 0) { indb = (n2 + indb - 1) % n2; done = false; } } // Return the points forming the upper tangent return {a\[inda\], b\[indb\]}; } // Main driver code int main() { vector\\> a = {{2, 2}, {3, 1}, {3, 3}, {5, 2}, {4, 0}}; vector\\> b = {{0, 1}, {1, 0}, {0, -2}, {-1, 0}}; vector\\> tangent = findUpperTangent(a, b); for(auto it:tangent){ cout\<\

相关推荐
数据皮皮侠2 小时前
中国城市间地理距离矩阵(2024)
大数据·数据库·人工智能·算法·制造
3GPP仿真实验室2 小时前
深度解析基站接收机核心算法:从 MRC 到 IRC 的空间滤波演进
算法
Boop_wu2 小时前
[Java 算法] 动态规划(1)
算法·动态规划
WolfGang0073212 小时前
代码随想录算法训练营 Day18 | 二叉树 part08
算法
hanlin033 小时前
刷题笔记:力扣第43、67题(字符串计算)
笔记·算法·leetcode
yang_B6213 小时前
最小二乘法 拟合平面
算法·平面·最小二乘法
放下华子我只抽RuiKe53 小时前
深度学习全景指南:硬核实战版
人工智能·深度学习·神经网络·算法·机器学习·自然语言处理·数据挖掘
yangtuoni4 小时前
vscode调试C++程序
c++·ide·vscode
吴秋霖4 小时前
【某音电商】protobuf聊天协议逆向
python·算法·protobuf