确定一组点是在正方形内部还是外部

2024-05-29

我有其中两个:

bool isPointOnShape(int a, int b)
{

}

bool isPointInShape(int a, int b)
{

}

假设我有一个正方形,第一个点(左下角)是 x,y (0,0) 第二个点(左上角)是 (0,2),第三个点是 (2,2),第四个点是 (0,2) 。

形状上的点将为 (0,1) (1,2) (2,1) (1,0) 形状上的点为 (1,1)

如何找出形状/形状中的点并返回真实值以便我可以将其存储在某个地方?


我将为任何可以分成直线段的形状提供通用解决方案。

因此,正如您可能已经猜到的那样,我首先将您的“形状”视为完成循环的段列表。或者简单地放置一个代表循环的点的循环列表,例如,您的正方形将是以下点列表:

0, 0
0, 2
2, 2
2, 0

请注意,我们认为每个点到下一个点都有线段,并且最后一个点连接到第一个点。另外,我们要求连续的点都不相等,第一个点和最后一个点也不相等。如果有的话,必须在继续之前将其删除。


现在,对于每个片段,我们可以确定边界框。例如给定这个片段:

a = (0, 2)
b = (2, 2)

那么 x 中的值范围是 [0, 2],y 中的值范围是 [2, 2],这就是该段的边界框。

接下来您需要的是线段线的导向向量。为此,首先计算线段的长度:

length = sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y))

进而:

director.x = (a.x - b.x)/length
director.y = (a.y - b.y)/length

注 1:当长度为 0 时,则表示段无效。这就是为什么我们不想要重复的点。

注2:使用指向矢而不是直线方程会使事情变得更容易。


现在,给定一个点 p,您可以确定该点是否在一个线段中(如果它是列表中的点之一)。对于其余情况,我们首先查看它是否位于轴对齐边界框内。只需检查范围即可完成此操作:

if
(
    (p.x >= box.left && p.x <= box.right) &&
    (p.y >= box.top && p.y <= box.bottom) // with origin at the top-left corner
)
{
     //It is inside of the bounding box
}

如果是,那么我们计算从点到线的距离,如果是 0然后就上线了。现在,由于浮点运算,您可以测试距离是否小于或等于 epsilon,其中 epsilon 是一个非常小的数字。

我们使用这个公式:

distance vector = (a - p) - ((a - p) · director) * director
distance = the norm of distance vector

其中“·”表示点积,“*”表示标量积。

剩下的就是迭代这些线段,为每个线段计算距离,如果任何一个线段的距离小于 epsilon,则该点位于“形状上”。


好吧,但是“形状”呢?

好吧,借助拓扑学的一点帮助,我们可以确定一个点是否在内部。这与 Windows 用于填充多边形或多段线的算法相同(例如在 Microsoft Paint 中徒手确定选定区域内的内容)。

事情是这样的:

计算从外面到达该点需要穿过的路段数。如果数字是对,那么它在外面,如果它是奇数,那么它在里面。

您可以选择从哪个方向到达该点。我选择左边。

您将再次迭代这些段。对于每一个,我们需要确定它是否在垂直范围内。为此,请使用边界框:

if ((p.y >= box.top && p.y <= box.bottom))
{
     //In the vertical range
}

现在,确定该段是在左侧还是右侧:

if (p.x < box.left)
{
     //The segment is at the left
}
else if (p.x > box.right)
{
     //The segment is at the right
}
else
{
     //The segment is close, need further calculation
}

如果该线段很近,我们需要计算到该线段的矢量距离并检查其方向。

向量距离?好吧,我们已经有了它,我们正在用它的范数来确定距离。现在,不采用范数,而是验证 x 坐标的符号。小于0则为右,大于0则为左。如果为0...则表示该段是水平的(因为距离向量始终垂直于该段),可以跳过该段*。

*:事实上,如果该线段是水平的并且在垂直范围内,则表示它在该线段处。片段是否“正常”?

现在,您需要计算左侧线段的数量,如果是奇数,则该点位于形状内部。否则就出局了。这也可以通过上方、右侧或下方的段来完成。我刚刚选了左边。


对于迭代所有段的成本较高的大型形状,您可以将段存储在某些空间分区数据结构中。这超出了本文的范围。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

确定一组点是在正方形内部还是外部 的相关文章

随机推荐

  • c# itextsharp如何获取数字签名图像

    是否可以使用 C 代码使用 itextsharp 获取 pdf 文件中任何数字签名的图像 PdfReader pdf new PdfReader location pdf AcroFields acroFields pdf AcroFiel
  • 适用于 Windows 8 的 Express 与适用于 Windows 桌面的 Express

    在 Visual Studio Express 2012 页面上有 2 个选项 适用于 Windows 8 的 Express and 适用于 Windows 桌面的 Express 这两者有什么区别 Express for Windows
  • Libpng、调色板 png 是否带 alpha?

    如何知道调色板 png 是否带有 alpha 我获取有关图像的信息png get IHDR 之后我看看color type PNG COLOR TYPE PALETTE 但我找不到如何知道这个 png 图像是否有 alpha 通道 PNG
  • 将 Blazor Webassemble 项目包含到现有 ASP.NET Core 项目中

    创建新的 Blazor Web assembly 项目时 有一个复选框ASP NET Core hosted https learn microsoft com en us aspnet core blazor host and deplo
  • 无论线程如何,对象是否总是能看到其最新的内部状态?

    假设我有一个带有简单整数计数变量的可运行对象 每次可运行对象运行时该变量都会递增 该对象的一个 实例被提交以在计划的执行程序服务中定期运行 class Counter implements Runnable private int coun
  • Webkit 是否有 CSS3 网格布局的有效实现?

    CSS 网格布局 编辑草案 2011 年 11 月 21 日 http dev w3 org csswg css3 grid align 我正在制作一个原型 该原型将在选定的设备和浏览器上向客户展示 目前我并不担心跨浏览器兼容性 IE10开
  • gestureRecognizer shouldReceiveTouch 持续存在于已释放的视图中导致崩溃

    我有一个相当简单的 UITableView 它在堆栈上推送一个新视图 新视图有一个像这样初始化的gestureRecognizer synthesize swipeGestureLeft void viewDidLoad swipeGest
  • 如何使鼠标事件传播到“滚动”容器中的小部件?

    所以我知道官方文档上写着 请注意 鼠标事件不会传播到滚动容器内的小部件 但我想做的正是 如何使鼠标事件通过这个小部件传播 有办法吗 我想做的就是让 待办事项应用程序 变得很棒 但为此我实际上需要拥有物品 这将是我想要完成的任务 所以我想要一
  • Rails 2.3.14:如何序列化 ActionController::Request 对象?

    我需要编写一些根据 Rails 2 3 14 控制器收到的请求对象类型执行操作的方法 但是 我不想启动整个应用程序 甚至不想启动控制器 我只想拥有这样一个对象的编组副本 以便我可以在 Rails 环境之外使用 不幸的是 ActionCont
  • Rails 中的 ActionController::RoutingError (没有路由匹配 [GET] "/favicon.ico")

    我尝试过使用 还有这个 但我仍然在日志文件中看到此错误 ActionController RoutingError No route matches GET favicon ico favicon ico 位于 public 文件夹中 我也
  • 上下文菜单未在 SwiftUI 中更新

    我正在尝试设置 SwiftUI contextMenu带有一个切换按钮Bool价值 上下文菜单的按钮文本应该在以下情况下更改 Bool切换 但上下文菜单不会更新 有没有办法强制更新上下文菜单 描述问题的示例代码 import SwiftUI
  • Swift 中计算只读属性与函数

    在 Swift WWDC 简介会话中 只读属性description被证明 class Vehicle var numberOfWheels 0 var description String return numberOfWheels wh
  • 处理 SavedInstances 并恢复活动

    基本上我的应用程序有 2 个活动 说 A 和 B A 启动 B Activity B 播放音乐并且还有通知 情况 1 当视图仍在活动 B 上时 我按主页按钮 然后单击通知 活动 B 将打开 其视图完好无损并播放音乐 因为在清单中我使用 an
  • 如何删除django中级联的一对一相关模型?

    背景 我在 Django 1 8 5 中定义了以下模型 class PublishInfo models Model pass class Book models Model info models OneToOneField Publis
  • 加速度计适用于 iphone/ipad 模拟器吗?

    据我所知 当我在 XCode 中使用 iPad 模拟器时 我的应用程序应该会触发加速计事件 但事实并非如此 我用谷歌搜索了一下 似乎加速度计没有在模拟器中实现 这是正确的吗 如果是这样 为什么他们会有 硬件 gt 摇动手势 菜单选项 我的代
  • VxWorks调度程序如何执行?

    想知道如何调用调度程序以便它可以切换任务 即使是抢占式调度或循环调度 调度程序也应该参与其中以进行任何类型的任务切换 假设一个低优先级任务有一个无限循环 调度程序什么时候介入并切换到更高优先级的任务 查询是 1 谁调用调度器 在VxWork
  • 在辅助功能模式下未检测到手势

    我正在编写一个应用程序 我需要在屏幕顶部放置一个标签 每当用户触摸它 或在其上方滑动手指 时 我需要大声读出标签文本 我尝试了以下方法 首先制作标签的可访问性元素 YES labelInfo setIsAccessibilityElemen
  • 单击另一个项目/小部件时展开/打开微调器?

    当用户单击另一个按钮时 我试图展开微调器 例如 我有一个带有值的微调器和一个 确定 按钮 当用户单击 确定 按钮而不从微调器中选择任何值时 微调器会自行扩展 是否可以在无需用户与微调器交互的情况下获得扩展微调器的事件 只需致电Spinner
  • 如何安装最新的mono和monodevelop?

    我尝试在 centOS 6 3 上安装 mono 和 monodevelop 几个小时后 我能够安装 mono 但 monodevelop 失败 我真的很惊讶在 Linux 上安装最新的 mono monodevelop 版本是多么困难和耗
  • 确定一组点是在正方形内部还是外部

    我有其中两个 bool isPointOnShape int a int b bool isPointInShape int a int b 假设我有一个正方形 第一个点 左下角 是 x y 0 0 第二个点 左上角 是 0 2 第三个点是