给定一个三维坐标系和矩形棱镜具有非负起点和非负大小(例如从(0, 2, 5)
开始并且大小为(9, 20, 5)
):我该如何才能最好地检查如果另一个矩形棱镜与已经在坐标系中的一个棱镜相交?最终,目标是对所有存在的棱镜执行此检查,能够测试一个应该足以完成此任务。
信息:起点和大小是非负长的3元组。我正在寻找一种速度适中的优雅解决方案。
我的项目是在java中,但任何数学公式,伪代码或描述都绰绰有余。
答案 0 :(得分:5)
将您的棱镜存放在R-Tree中。对于矩形同轴棱镜,搜索和插入应该是log(n)
。
R-Trees有一些Python包。使用Rtree 0.6.0,您的代码将非常简单:
>>> from rtree import Rtree
>>> idx = Rtree()
>>> minx, miny, maxx, maxy = (0.0, 0.0, 1.0, 1.0)
>>> idx.add(0, (minx, miny, maxx, maxy))
>>> list(idx.intersection((1.0, 1.0, 2.0, 2.0)))
[0L]
>>> list(idx.intersection((1.0000001, 1.0000001, 2.0, 2.0)))
[]
将您的数据存储在sqlite
数据库中,该数据库可以使用极少量的代码(many java implementations)在文件或内存中创建。创建一个名为prisms
的表,其列为id
,min_x
,min_y
,min_z
,max_x
,{{1} },max_y
。索引每一行。
插入为max_z
,检查交叉点是Magnus Skog's approach,给定O(1)
:
new_min_x, new_min_y, new_min_z, new_max_x, new_max_y, new_max_z
答案 1 :(得分:2)
假设你有两个棱镜A和B.如果B与A相交,那就是不完全向右,向左,向上,向下等的否定。
if not (B.x > A.x+A.dx or B.x+B.dx < A.x or
B.y > A.y+A.dy or B.y+B.dy < A.y or
B.z > A.z+A.dz or B.z+B.dz < A.z)
// B intersects A
答案 2 :(得分:1)
从(0, 2, 5)
开始且大小为(9, 20, 5)
的棱镜在(9, 22, 10)
结束。
要检查重叠棱镜(A和B),请使用这些棱镜的起点和终点。两个棱镜必须在所有方面重叠。
要检查X维度的重叠,请使用:
If (A.startX <= B.endX) and (B.startX <= A.endX)
因此:
If
(A.startX <= B.endX) and (B.startX <= A.endX)
and (A.startY <= B.endY) and (B.startY <= A.endY)
and (A.startZ <= B.endZ) and (B.startZ <= A.endZ)
Then
(A and B overlap)
当两个棱镜只有一个共同点时,上面的检查将导致True
。如果您不希望这样,并且您希望重叠空间不仅仅是一个点或一个线段或一个矩形表面,而是一个棱镜,那么将<=
替换为<
。
答案 3 :(得分:0)
以同样的方式检查一条线上的线段。如果B的开始或结束位于A的开始和结束之间,则它们重叠。
唯一的区别是它们必须在所有三个维度上重叠。