- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
给定多条曲线,包括线段和圆弧,如何计算所有曲线的总OBB?
似乎各个曲线的每个 OBB 的并集都不对,这不是最小覆盖。
查看这张图,红框是怎么计算的?
最佳答案
您还应该以矢量形式添加输入,以便我们可以测试您的数据......我会这样处理:
O(n)
计算每个角度的最大距离 O(n)
只需为足够的 m
创建表角度(例如 5 度步长,所以 m = 360/5
),其中对于每个角度部分,您只记得最大远点距离。
计算每次旋转的最大垂直距离 O(m^2)
因此对于每个角度部分计算值是:
value[actual_section] = max(distance[i]*cos(section_angle[i]-section_angle[actual_section]))
哪里i
封面 +/- 90 deg
围绕实际截面角度,所以现在您获得了每个角度的最大垂直距离...
选择最佳解决方案 O(m)
因此请查看从 0 度到 90 度的所有旋转,并记住具有最小 OBB 区域的旋转。只是为了确保 OBB 与截面角度对齐,轴的大小是 value
那个角度和所有 90 度增量......围绕中心
这不会产生最佳解决方案,但非常接近它。为了提高精度,您可以使用更多的角度部分,甚至可以使用越来越小的角度步长递归搜索已找到的解决方案(首次运行后无需计算其他角度区域。
[编辑1]
我尝试用 C++ 对此进行编码作为概念证明,并使用您的图像(作为点集处理)作为输入,所以这里是结果,以便您可以进行比较(用于调试目的)
灰色 是从您的图像中检测到的点,绿色 矩形是轴对齐的 BBox 红色 矩形被发现OBBox。 aqua 点是每个角度间隔的最大距离,green 点是 +/-90deg
的最大垂直距离。邻角间隔。我用了400
角度,如您所见,结果非常接近... 360/400 deg
准确性,所以这种方法很有效......
这里是C++源码:
//---------------------------------------------------------------------------
struct _pnt2D
{
double x,y;
// inline
_pnt2D() {}
_pnt2D(_pnt2D& a) { *this=a; }
~_pnt2D() {}
_pnt2D* operator = (const _pnt2D *a) { *this=*a; return this; }
//_pnt2D* operator = (const _pnt2D &a) { ...copy... return this; }
};
struct _ang
{
double ang; // center angle of section
double dis; // max distance of ang section
double pdis; // max perpendicular distance of +/-90deg section
// inline
_ang() {}
_ang(_ang& a) { *this=a; }
~_ang() {}
_ang* operator = (const _ang *a) { *this=*a; return this; }
//_ang* operator = (const _ang &a) { ...copy... return this; }
};
const int angs=400; // must be divisible by 4
const int angs4=angs>>2;
const double dang=2.0*M_PI/double(angs);
const double dang2=0.5*dang;
_ang ang[angs];
List<_pnt2D> pnt;
_pnt2D bbox[2],obb[4],center;
//---------------------------------------------------------------------------
void compute_OBB()
{
_pnt2D ppp[4];
int i,j; double a,b,dx,dy;
_ang *aa,*bb;
_pnt2D p,*pp; DWORD *q;
// convert bmp -> pnt[]
pnt.num=0;
Graphics::TBitmap *bmp=new Graphics::TBitmap;
bmp->LoadFromFile("in.bmp");
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
for (p.y=0;p.y<bmp->Height;p.y++)
for (q=(DWORD*)bmp->ScanLine[int(p.y)],p.x=0;p.x<bmp->Width;p.x++)
if ((q[int(p.x)]&255)<20)
pnt.add(p);
delete bmp;
// axis aligned bbox
bbox[0]=pnt[0];
bbox[1]=pnt[0];
for (pp=pnt.dat,i=0;i<pnt.num;i++,pp++)
{
if (bbox[0].x>pp->x) bbox[0].x=pp->x;
if (bbox[0].y>pp->y) bbox[0].y=pp->y;
if (bbox[1].x<pp->x) bbox[1].x=pp->x;
if (bbox[1].y<pp->y) bbox[1].y=pp->y;
}
center.x=(bbox[0].x+bbox[1].x)*0.5;
center.y=(bbox[0].y+bbox[1].y)*0.5;
// ang[] table init
for (aa=ang,a=0.0,i=0;i<angs;i++,aa++,a+=dang)
{
aa->ang=a;
aa-> dis=0.0;
aa->pdis=0.0;
}
// ang[].dis
for (pp=pnt.dat,i=0;i<pnt.num;i++,pp++)
{
dx=pp->x-center.x;
dy=pp->y-center.y;
a=atan2(dy,dx);
j=floor((a/dang)+0.5); if (j<0) j+=angs; j%=angs;
a=(dx*dx)+(dy*dy);
if (ang[j].dis<a) ang[j].dis=a;
}
for (aa=ang,i=0;i<angs;i++,aa++) aa->dis=sqrt(aa->dis);
// ang[].adis
for (aa=ang,i=0;i<angs;i++,aa++)
for (bb=ang,j=0;j<angs;j++,bb++)
{
a=fabs(aa->ang-bb->ang);
if (a>M_PI) a=(2.0*M_PI)-a;
if (a<=0.5*M_PI)
{
a=bb->dis*cos(a);
if (aa->pdis<a) aa->pdis=a;
}
}
// find best oriented bbox (the best angle is ang[j].ang)
for (b=0,j=0,i=0;i<angs;i++)
{
dx =ang[i].pdis; i+=angs4; i%=angs;
dy =ang[i].pdis; i+=angs4; i%=angs;
dx+=ang[i].pdis; i+=angs4; i%=angs;
dy+=ang[i].pdis; i+=angs4; i%=angs;
a=dx*dy; if ((b>a)||(i==0)) { b=a; j=i; }
}
// compute endpoints for OBB
i=j;
ppp[0].x=ang[i].pdis*cos(ang[i].ang);
ppp[0].y=ang[i].pdis*sin(ang[i].ang); i+=angs4; i%=angs;
ppp[1].x=ang[i].pdis*cos(ang[i].ang);
ppp[1].y=ang[i].pdis*sin(ang[i].ang); i+=angs4; i%=angs;
ppp[2].x=ang[i].pdis*cos(ang[i].ang);
ppp[2].y=ang[i].pdis*sin(ang[i].ang); i+=angs4; i%=angs;
ppp[3].x=ang[i].pdis*cos(ang[i].ang);
ppp[3].y=ang[i].pdis*sin(ang[i].ang); i+=angs4; i%=angs;
obb[0].x=center.x+ppp[0].x+ppp[3].x;
obb[0].y=center.y+ppp[0].y+ppp[3].y;
obb[1].x=center.x+ppp[1].x+ppp[0].x;
obb[1].y=center.y+ppp[1].y+ppp[0].y;
obb[2].x=center.x+ppp[2].x+ppp[1].x;
obb[2].y=center.y+ppp[2].y+ppp[1].y;
obb[3].x=center.x+ppp[3].x+ppp[2].x;
obb[3].y=center.y+ppp[3].y+ppp[2].y;
}
//---------------------------------------------------------------------------
我使用我的动态列表模板是这样的:
List<double> xxx;
与double xxx[];
相同
xxx.add(5);
添加 5
到列表的末尾
xxx[7]
访问数组元素(安全)
xxx.dat[7]
访问数组元素(不安全但快速的直接访问)
xxx.num
是数组实际使用的大小
xxx.reset()
清除数组并设置 xxx.num=0
xxx.allocate(100)
为 100
预分配空间元素
你可以忽略// convert bmp -> pnt[]
VCL 部分,因为您已经获得了数据。
我建议也看看我的:
关于algorithm - 如何计算多条曲线的 OBB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42989829/
我看过几个关于找到两个 OBB 之间的交点的线程。我仍然不明白如何找到最小穿透轴。我需要找到最小穿透轴,我相信它在 David Eberly 的论文中也被称为最后一个分离轴,以确定我应该使用表格的哪一
所以我遇到的问题非常简单,我似乎无法弄清楚。当我将扩展文件或 .obb 文件 main.2.com.example.project.obb 放入 obb 目录时,如下所示: /storage/emul
我正在尝试按照此处的指南在 Android 中测试扩展包文件 (OBB): http://developer.android.com/google/play/expansion-files.html
我正在为“扩展文件”开发 obb 集成。我通过复制设备 (4.1) 的 sdcard 上的 .obb 文件使其在本地工作,但在我的 4.2 设备上它不再工作了。 1) 在 4.1 平板电脑上:运行良好
我需要一些关于 obb 旋转的帮助: 首先,我检查 3d 模型的每个顶点并获取最小值和最大值以找到 obb 最小/最大点。 void obb::checkVertex(vector3f& vertex
嗨,我正在尝试使用 lwjgl 将 OBB 构建到我的 3d java 游戏中。目前我只是尝试使用matrix4f 旋转OBB 并通过渲染点来测试它。因此,当我渲染它时,它的 xyx=0,0,0 且
给定多条曲线,包括线段和圆弧,如何计算所有曲线的总OBB? 似乎各个曲线的每个 OBB 的并集都不对,这不是最小覆盖。 查看这张图,红框是怎么计算的? 最佳答案 您还应该以矢量形式添加输入,以便我们可
我正在创建一个 2D 游戏并想测试 OBB(定向边界框)和圆之间的碰撞。我不确定执行此操作的数学和代码。我正在用 C++ 和 OpenGL 创建游戏。 最佳答案 因为你的两个形状都是凸的,你可以使用
我在项目中使用文件扩展来访问 obb 文件夹中的音频、视频和图像文件。我的Obb文件的形式是:main.1.com.example.sample--->包含三个名为Images、Video和Audio
美好的一天! 假设我有一个名为 test 的目录。它包含几个目录和文件。(dir_1:file_1,file_2;dir_2:file_1,file_2;...;dir_5:file_1,file_2
我手动放置了 OBB 文件,这样我就可以检查是否一切正常。当我将文件放在 Android/obb 文件夹中时,在第一次构建时无法识别它。我注意到,如果我将 OBB 文件放入 obb 文件夹后重新启动手
给定形成 OBB 的中心点、宽度、高度和角度,如何确定给定点 P 是否在 OBB 内? 谢谢 最佳答案 我认为你的问题中的皱纹是边界框可以旋转?如果是这样,对我来说最简单的解决方案似乎是在以边界框中心
我正在关注所有官方扩展文件指南,但我找不到它。我无法访问我需要的包含的 obb 文件。 我需要 6 个音频文件 (80Mb),我将它们“存储”(未压缩)在一个 zip 文件中并重命名为“main.20
在我的应用程序中,我在 Android->obb->packagename->main.1.packagename.obb 下载了扩展文件。有人可以向我解释,即使有示例代码如何从中提取我的文件吗? 我
通过将 .obb 文件扩展到另一个目录以读取各个部分,我们已经在我们的应用程序中成功使用 APK 扩展文件技术一段时间了。我们最终决定尝试通过使用 StorageManager 挂载 bob 来直接读
我能够上传和下载可扩展文件在我的谷歌播放应用程序上。按照o[官方教程][1] 将obb文件保存到/Android/Obb/main.2.myappname.obb 我假设这个 obb 文件将被提取到
我正在尝试挂载一个 obb 文件,但是 std::fstream test("/storage/emulated/0/Android/obb/com.bixense.jngl_test/main.1.
我已经在我的游戏应用程序上开发了 obb 函数。简单解释一下obb函数的逻辑, 制作一个包含 Assets 的 zip 文件并重命名为 .obb。 使用 apk 将其上传到 Play 商店。然后它会自
我正在尝试编写一个刚体模拟器,在模拟过程中,我不仅对发现两个物体是否发生碰撞感兴趣,而且还对碰撞的点和法线感兴趣。我找到了很多资源,这些资源实际上说明了两个 OBB 是否正在使用分离轴定理发生碰撞。我
我在处理 APK 扩展时遇到问题。在 Java 端,我可以设置我应该设置的所有内容,但似乎我无法在 C++ 端正确修改代码。 CCFileUtilsAndroid::getFileData 函数内部:
我是一名优秀的程序员,十分优秀!