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

发布时间:2026/11/2 15:58:35

C# 两个凸多边形之间的切线(Tangents between two Convex Polygons) 如果您喜欢此文章请收藏、点赞、评论谢谢祝您快乐每一天。给定两个凸多边形我们的目标是找出连接它们的下切线和上切线。如下图所示TRL和TLR分别代表上切线和下切线。例如输入第一个多边形[[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 的上方我们沿b逆时针方向移动到下一个点形成直线2。这条直线现在位于多边形b 的上方这很好。但是它穿过多边形a 因此我们沿a顺时针方向移动到下一个点形成直线 3。直线3仍然穿过多边形a因此我们继续移动到直线 4。然而直线 4穿过多边形b因此我们继续移动到直线 5。最后直线 5不穿过任何一个多边形因此它是给定多边形的正确上切线。为了找到下切线我们需要反向穿过多边形即如果直线穿过多边形 b则接下来顺时针移动如果直线穿过多边形 a则接下来逆时针移动。上切线算法L ←连接多边形 a 的最右点和 b 的最左点的线段。当 L 穿过任意多边形时当 L 穿过多边形 b 时L ← L多边形 b 上的点向上移动。当 L 穿过多边形 a 时L ← L多边形 a 上的点向上移动。下切线算法L ←连接多边形 a 的最右点和 b 的最左点的线段。当L 穿过任意多边形时 { 当L 穿过 b时 L ← Lb 上的点向下移动。当L 穿过 a时 L ← La 上的点向下移动。 }请注意上述代码仅计算了上切线。类似的方法也可用于求下切线。using System;public class UpperTangentFinder{static int Quad(int x, int y){if (x 0 y 0) return 1;if (x 0 y 0) return 2;if (x 0 y 0) return 3;return 4;}static int Orientation(int[] a, int[] b, 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;return res 0 ? 1 : -1;}static bool Compare(int[] p1, int[] p2, int[] mid){int[] p { p1[0] - mid[0], p1[1] - mid[1] };int[] q { p2[0] - mid[0], p2[1] - mid[1] };int quadP Quad(p[0], p[1]);int quadQ Quad(q[0], q[1]);if (quadP ! quadQ)return quadP quadQ;return (p[1] * q[0]) (q[1] * p[0]);}static int[,] SortPoints(int[,] polygon){int n polygon.GetLength(0);int[] mid { 0, 0 };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;}for (int i 0; i n - 1; i){for (int j i 1; j n; j){int[] p1 { polygon[i, 0], polygon[i, 1] };int[] p2 { polygon[j, 0], polygon[j, 1] };if (!Compare(p1, p2, mid)){int tempX polygon[i, 0], tempY polygon[i, 1];polygon[i, 0] polygon[j, 0];polygon[i, 1] polygon[j, 1];polygon[j, 0] tempX;polygon[j, 1] tempY;}}}for (int i 0; i n; i){polygon[i, 0] / n;polygon[i, 1] / n;}return polygon;}static int[,] FindUpperTangent(int[,] a, int[,] b){int n1 a.GetLength(0);int n2 b.GetLength(0);int maxa int.MinValue;for (int i 0; i n1; i)maxa Math.Max(maxa, a[i, 0]);int minb int.MaxValue;for (int i 0; i n2; i)minb Math.Min(minb, b[i, 0]);a SortPoints(a);b SortPoints(b);if (minb maxa){int[,] temp a;a b;b temp;n1 a.GetLength(0);n2 b.GetLength(0);}int ia 0, ib 0;for (int i 1; i n1; i)if (a[i, 0] a[ia, 0])ia i;for (int i 1; i n2; i)if (b[i, 0] b[ib, 0])ib i;int inda ia, indb ib;bool done false;while (!done){done true;while (Orientation(new int[] { b[indb, 0], b[indb, 1] },new int[] { a[inda, 0], a[inda, 1] },new int[] { a[(inda 1) % n1, 0],a[(inda 1) % n1, 1] }) 0){inda (inda 1) % n1;}while (Orientation(new int[] { a[inda, 0], a[inda, 1] },new int[] { b[indb, 0], b[indb, 1] },new int[] { b[(n2 indb - 1) % n2, 0],b[(n2 indb - 1) % n2, 1] }) 0){indb (n2 indb - 1) % n2;done false;}}int[,] result new int[2, 2];result[0, 0] a[inda, 0];result[0, 1] a[inda, 1];result[1, 0] b[indb, 0];result[1, 1] b[indb, 1];return result;}public static void Main(string[] args){int[,] a new int[,] {{2, 2},{3, 1},{3, 3},{5, 2},{4, 0}};int[,] b new int[,] {{0, 1},{1, 0},{0, -2},{-1, 0}};int[,] tangent FindUpperTangent(a, b);for (int i 0; i 2; i){Console.WriteLine(tangent[i, 0] tangent[i, 1]);}}}输出上切线(upper tangent) (0,1) (3,3)时间复杂度O(n1 log (n1) n2 log(n2))辅助空间O(1)如果您喜欢此文章请收藏、点赞、评论谢谢祝您快乐每一天。
延伸阅读

更多相关文章

2026/10/30 11:27:29

ADC 采样数据乱跳?分享我用了多年的滤波函数

简介ADC采集数据我们项目开发中经常用到,那么你是如何处理采集到的数据的呢?说实话我看到有部分同学直接拿来使用的,这样数据一旦飘逸那就是不稳定因素,有很大的潜在风险,下面介绍一下我用过的处理方式,欢迎…

2026/10/29 13:16:51

Rust for ML:机器学习系统级优化实战指南

1. 项目概述:为什么一个机器学习工程师要学 Rust?“Rustic Learning: Machine Learning in Rust — Part 1: Introduction to Rust”这个标题乍看像是一门课程的开篇,但背后藏着一个正在发生的行业转向——不是“用 Rust 写个玩具模型”&…

2026/11/3 2:09:51

深入理解Seata:微服务分布式事务解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 2:09:51

Delphi VCL程序最小化隐藏到托盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 2:09:51

模型说“我不能“?用 dsh-purge 分清模型拒绝和宿主拦截

模型说"我不能"?用 dsh-purge 分清模型拒绝和宿主拦截 【免费下载链接】dsh-purge DeepSeek Harness 破甲:让所有模型都能破甲,不同模型可换不同提示词;默认提示词面向国模「小码酱」。Jailbreak for every model — sw…

2026/11/3 2:09:51

【72】水上垃圾数据集(有v5/v8模型)/YOLO水上垃圾检测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑