- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
想象一下,您在x,y和z方向上的0D和 d 米之间有一个3D空间(这是一个长度为 d 的立方体)。现在假设我想将其分解为较小的多维数据集的3D数组。我们想要每个方向上的和立方体。这意味着每个多维数据集的长度,宽度和高度为 d / n (您可以假设d / n完全除法)。
可以将其保存在以下数组中:Cube* cubes[n][n][n];
现在让我们假设我们可以有一个半径为 r 的球体,并且位置 p ,其中 p 可以在3d空间内的任何位置,而 r 没有任何约束。查找和返回与该球面相交的所有多维数据集的最有效方法是什么?
当前,我正在遍历数组中的所有多维数据集,并使用毕达哥拉斯定理检查每个多维数据集与 p 之间的距离,我在下面为其编写了伪代码。
Cube* getIntersectingCubes(r,p) {
Cube* cubes[n][n][n];
Cube* result[];
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
for(int k=0;k<n;k++) {
if(distanceBetween(cubes[i][j][k],p) < r) {
result.add(cubes[i][j][k]);
}
}
}
}
return result;
}
但是,绝对有更好的方法可以做到这一点。如何返回相同的输出,但要检查尽可能少的多维数据集?
最佳答案
如果仍然难以确定坐标系和算法,请从图表开始:
本质上,您拥有的是3D多维数据集网格,您可以按照自己喜欢的任何方式选择点p
,只要它们完全描述了多维数据集即可。您要确定的是半径r
与哪个多维数据集相交的多维数据集的任何部分。您可以使用三个 vector 来处理。您只需将多维数据集原点视为 vector 。您知道每个立方体的边长(d / n
)可用于形成第二个 vector (称它为p
或p_extent
的范围),可以将其添加到原点 vector 中以确定立方体中的最远点。因此p_extent
等于d/n
i + d/n
j + d/n
k 。
您可以创建一个结构以帮助将坐标作为 vector 处理,例如:
typedef struct {
double x, y, z;
} vect_pos;
使用两个 vector ,您可以简单地将它们加在一起(例如
p
+
p_extent
)以形成一个 vector ,该 vector 描述立方体中距原点最远的点。 (您希望多维数据集内的 vector 的方向与原点 vector 具有相同的符号方向(因此,您可以将其与该方向上的单位 vector 相乘)。例如,您的点是
-3
i
-1
j 和
2
k ,您可以将
p_extent
vector 乘以
-1
i
-1
j
1
k 。 。
x, y, z
加在一起,您可以简单地使用 vector 加法,例如
/* vector addition */
vect_pos vect_add (const vect_pos *a, const vect_pos *b)
{
vect_pos c = { .x = 0. };
c.x = a->x + b->x;
c.y = a->y + b->y;
c.z = a->z + b->z;
return c;
}
在多维数据集的某个角选择坐标的最后一个皱纹需要您解决的问题是,原点 vector 不会总是指向最接近原点的角(上图中的图片,如果您旋转原点计数器,
vector_pos
将指向该位置,绕轴顺时针方向旋转90度(您可以选择以立方体的中心作为原点,但是计算的次数是原来的两倍)。
p
是否在最接近的角和最远的角之间(该立方体仍然是相同的立方体)。原点和描述的最远角,您可以简单地使用vector-distance公式计算每个点到原点的距离,如果
r
在两者之间,则球体与该立方体相交。
/* point in cube closest to origin */
vect_pos closest_pt (const vect_pos *p, const int len)
{
vect_pos c = { p->x >= 0 ? p->x : p->x + len,
p->y >= 0 ? p->y : p->y + len,
p->z >= 0 ? p->z : p->z + len };
return c;
}
(在坐标为正的原点
r
处选择多维数据集,可以在坐标为负的情况下简单地添加多维数据集的边长,以选择多维数据集上最接近的点作为原点)
/* vector distance */
double vect_dist (const vect_pos *p)
{
return sqrt (p->x * p->x + p->y * p->y + p->z * p->z);
}
要检查
0, 0, 0
是否落在每个多维数据集的最近距离与最远距离之间,可以将其与一个简短函数一起使用,该简短函数可以在与原点相同的方向上选择范围 vector ,将 vector 相加,然后将每个距离与
r
比较,例如
/* does r intersect cube at postition p */
int intersect (vect_pos *p, const double r, const int len)
{
vect_pos c = closest_pt (p, len), /* closest pt to origin */
p_extent = { .x = c.x >= 0 ? len : -len, /* length, unit vector */
.y = c.y >= 0 ? len : -len, /* pointing outward */
.z = c.z >= 0 ? len : -len },
p_farthest = vect_add (&c, &p_extent); /* farthest point in cube */
double nearest = vect_dist (&c), /* distance to nearest */
farthest = vect_dist (&p_farthest); /* distance to farthest */
return nearest <= r && r <= farthest; /* return radius in between */
}
基本上就是这样。您可以添加简短功能以方便地输出点,例如
void prn_pos (const vect_pos *p)
{
printf ("(% d, % d, % d)\n",
(int)p->x, (int)p->y, (int)p->z);
}
然后添加一个允许输入
r
,
main()
和
r
的
d
并输出结果:
int main (int argc, char **argv) {
double r = argc > 1 ? strtod (argv[1], NULL) : .9; /* r */
int d = argc > 2 ? strtol (argv[2], NULL, 0) : 1, /* d */
n = argc > 3 ? strtol (argv[3], NULL, 0) : d, /* n */
dn = 0, /* d/n */
nc = 0, /* number of cubes in each direction */
total = 0, /* total cubes in search grid */
intersecting = 0; /* number of cubes that intersect sphere */
if (r < 0 || d < 0) { /* validate length inputs */
fputs ("error: negtive length in input of r or d.\n", stderr);
return 1;
}
if (!n || n < 0) { /* validate n not zero or negative */
fputs ("error: n - divide by zero or negative.\n", stderr);
return 1;
}
if (d < r) { /* ensure d >= r */
int min_d = ceil (r);
n *= min_d / d;
d = min_d;
}
if (d % n) { /* validate d equally divisible by n */
fputs ("error: d not equally divisible by n.\n", stderr);
return 1;
}
dn = d / n; /* cube side length */
nc = ceil (r / dn) + 1; /* limit of cubes needed per-direction */
total = nc * nc * nc * 8; /* total number of cubes in search grid */
printf ("\nOut of %d cubes, the following intersect sphere of radius %.2f\n\n",
total, r);
for (int i = -d; i <= d; i += dn) /* loop -d to d */
for (int j = -d; j <= d; j += dn)
for (int k = -d; k <= d; k += dn) {
vect_pos p = { i, j, k }; /* vector to cube origin */
if (intersect (&p, r, dn)) { /* does it intersect sphere? */
prn_pos (&p); /* output cube origin */
intersecting++; /* increment count */
}
}
printf ("\nintersecting cubes: %d\n", intersecting);
}
添加标题:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
然后针对数学库
n
编译链接,您就有一个可以测试的程序。如果未提供
-lm
,
r
或
d
的参数,则该代码将
n
,
.90
和
1
作为默认值。请注意,在每个维度上,循环限制从
1
到
-(next int above r)
至少是最小的,或者由
(next int above r)
给出,以大于且不小于
d
的限制。
r
和
r = .9
和
d = 1
的默认情况:
$ ./bin/cube-sphere-intersect
Out of 64 cubes, the following intersect sphere of radius 0.90
(-1, -1, -1)
(-1, -1, 0)
(-1, 0, -1)
(-1, 0, 0)
( 0, -1, -1)
( 0, -1, 0)
( 0, 0, -1)
( 0, 0, 0)
intersecting cubes: 8
如果在网格上绘制多维数据集,则这些是围绕原点的8个多维数据集。
n = 1
,
r = 5.5
和
d = 6
会得到相同的结果,除了立方体的边长不同:
$ ./bin/cube-sphere-intersect 5.5 6 1
Out of 64 cubes, the following intersect sphere of radius 5.50
(-6, -6, -6)
(-6, -6, 0)
(-6, 0, -6)
(-6, 0, 0)
( 0, -6, -6)
( 0, -6, 0)
( 0, 0, -6)
( 0, 0, 0)
intersecting cubes: 8
如果您输入的
n = 1
长度实际上是
r
,那么您将在此处选择是否将
1
视为等于最小或最大长度。有论点说“接触”一个多维数据集并不一定意味着它相交,因为该点在技术上将位于相距一定距离的切线上,但是同样有很好的论据表明该相交(选择是否要使用
r
或比较中的
<=
留给您)
<
(
1.0 < sqrt(2)
)之间输入任何内容,则会发现32个立方体相交,例如
$ ./bin/cube-sphere-intersect 1.1
Out of 216 cubes, the following intersect sphere of radius 1.10
(-2, -1, -1)
(-2, -1, 0)
(-2, 0, -1)
(-2, 0, 0)
(-1, -2, -1)
(-1, -2, 0)
(-1, -1, -2)
(-1, -1, -1)
(-1, -1, 0)
(-1, -1, 1)
(-1, 0, -2)
(-1, 0, -1)
(-1, 0, 0)
(-1, 0, 1)
(-1, 1, -1)
(-1, 1, 0)
( 0, -2, -1)
( 0, -2, 0)
( 0, -1, -2)
( 0, -1, -1)
( 0, -1, 0)
( 0, -1, 1)
( 0, 0, -2)
( 0, 0, -1)
( 0, 0, 0)
( 0, 0, 1)
( 0, 1, -1)
( 0, 1, 0)
( 1, -1, -1)
( 1, -1, 0)
( 1, 0, -1)
( 1, 0, 0)
intersecting cubes: 32
然后对于
1.414...
之间的半径,您会发现56个立方体相交,依此类推。
sqrt(2) <= sqrt(3)
进行操作,但是该结构有助于使逻辑保持清晰。仔细检查一下,如果您还有其他问题,请告诉我。
关于c++ - 如果我有一个3d的立方体网格,如何有效地找到所有与半径r和位置p的球面相交的立方体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63892291/
我正在从 Stata 迁移到 R(plm 包),以便进行面板模型计量经济学。在 Stata 中,面板模型(例如随机效应)通常报告组内、组间和整体 R 平方。 I have found plm 随机效应
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
我想要求用户输入整数值列表。用户可以输入单个值或一组多个值,如 1 2 3(spcae 或逗号分隔)然后使用输入的数据进行进一步计算。 我正在使用下面的代码 EXP <- as.integer(rea
当 R 使用分类变量执行回归时,它实际上是虚拟编码。也就是说,省略了一个级别作为基础或引用,并且回归公式包括所有其他级别的虚拟变量。但是,R 选择了哪一个作为引用,以及我如何影响这个选择? 具有四个级
这个问题基本上是我之前问过的问题的延伸:How to only print (adjusted) R-squared of regression model? 我想建立一个线性回归模型来预测具有 15
我在一台安装了多个软件包的 Linux 计算机上安装了 R。现在我正在另一台 Linux 计算机上设置 R。从他们的存储库安装 R 很容易,但我将不得不使用 安装许多包 install.package
我正在阅读 Hadley 的高级 R 编程,当它讨论字符的内存大小时,它说: R has a global string pool. This means that each unique strin
我们可以将 Shiny 代码写在两个单独的文件中,"ui.R"和 "server.R" , 或者我们可以将两个模块写入一个文件 "app.R"并调用函数shinyApp() 这两种方法中的任何一种在性
我正在使用 R 通过 RGP 包进行遗传编程。环境创造了解决问题的功能。我想将这些函数保存在它们自己的 .R 源文件中。我这辈子都想不通怎么办。我尝试过的一种方法是: bf_str = print(b
假设我创建了一个函数“function.r”,在编辑该函数后我必须通过 source('function.r') 重新加载到我的全局环境中。无论如何,每次我进行编辑时,我是否可以避免将其重新加载到我的
例如,test.R 是一个单行文件: $ cat test.R # print('Hello, world!') 我们可以通过Rscript test.R 或R CMD BATCH test.R 来
我知道我可以使用 Rmd 来构建包插图,但想知道是否可以更具体地使用 R Notebooks 来制作包插图。如果是这样,我需要将 R Notebooks 编写为包小插图有什么不同吗?我正在使用最新版本
我正在考虑使用 R 包的共享库进行 R 的站点安装。 多台计算机将访问该库,以便每个人共享相同的设置。 问题是我注意到有时您无法更新包,因为另一个 R 实例正在锁定库。我不能要求每个人都关闭它的 R
我知道如何从命令行启动 R 并执行表达式(例如, R -e 'print("hello")' )或从文件中获取输入(例如, R -f filename.r )。但是,在这两种情况下,R 都会运行文件中
我正在尝试使我当前的项目可重现,因此我正在创建一个主文档(最终是一个 .rmd 文件),用于调用和执行其他几个文档。这样我自己和其他调查员只需要打开和运行一个文件。 当前设置分为三层:主文件、2 个读
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 5年前关闭。 Improve this qu
我的 R 包中有以下描述文件 Package: blah Title: What the Package Does (one line, title case) Version: 0.0.0.9000
有没有办法更有效地编写以下语句?accel 是一个数据框。 accel[[2]]<- accel[[2]]-weighted.mean(accel[[2]]) accel[[3]]<- accel[[
例如,在尝试安装 R 包时 curl作为 usethis 的依赖项: * installing *source* package ‘curl’ ... ** package ‘curl’ succes
我想将一些软件作为一个包共享,但我的一些脚本似乎并不能很自然地作为函数运行。例如,考虑以下代码块,其中“raw.df”是一个包含离散和连续类型变量的数据框。函数“count.unique”和“squa
我是一名优秀的程序员,十分优秀!