- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我确定一定有一种方法可以执行以下操作,但我不知道它叫什么,所以我无法用谷歌搜索它。
我需要一个从 A 到 B 的算法。有人知道它叫什么或有链接吗?
编辑:对不起,我不够清楚。图 A 由正方形组成,我基本上需要一个算法来移除正方形并将其变成多边形(图 B)。输入是轴对齐正方形的普通列表,输出应该是构成多边形的顶点列表。方 block 将始终像网格一样对齐,它们不会重叠。
为了更清楚,我想写一个这样的函数(伪代码):
struct Square {
x, y, size: float
}
struct Polygon {
vertices_x, vertices_y: float[]
}
function convert_to_polygon(IN squares: Square[]) -> OUT Polygon {
//The algorithm I need goes here
}
最佳答案
如果我没看错你想获得图像的圆周轮廓。
对于矢量和栅格输入,您可以调整/使用 finding holes in 2D point set .无论如何,您想寻找某种 (convex) Hull 算法的 2D 改编 ...
如果您的输入是光栅:
将所有红色像素重新着色为黑色
如果您需要在项目符号 #2 处停止的矢量输出并创建红点列表。然后应用连接像素分析来检测线条在多边形中的顺序......对于正方形这应该很容易但是对于任意图像你需要line regression或霍夫变换 ...
如果您的输入是矢量:
然后删除所有内线。因此,被其他线围成 H 形状的线。您还可以检测所有小方 block ,然后删除重复的线条。
[Edit1] 你的输入/输出是向量所以
删除所有出现超过一次的行
如果您的正方形是任意大小的,那么您需要通过切割重叠部分来更精确地做到这一点......
将第一条线添加到多边形(将其从线列表中删除)
在 C++ 中,我破坏了这样的东西:
// temp structures
struct _pnt { float x,y; _pnt(){}; _pnt(_pnt& a){ *this=a; }; ~_pnt(){}; _pnt* operator = (const _pnt *a) { *this=*a; return this; }; /*_pnt* operator = (const _pnt &a) { ...copy... return this; };*/ };
struct _lin { int p0,p1,n; _lin(){}; _lin(_lin& a){ *this=a; }; ~_lin(){}; _lin* operator = (const _lin *a) { *this=*a; return this; }; /*_lin* operator = (const _lin &a) { ...copy... return this; };*/ };
// your in/out structures
struct _sqr { float x,y,s; _sqr(){}; _sqr(_sqr& a){ *this=a; }; ~_sqr(){}; _sqr* operator = (const _sqr *a) { *this=*a; return this; }; /*_sqr* operator = (const _sqr &a) { ...copy... return this; };*/ };
struct _pol { List<float> x,y; _pol(){}; _pol(_pol& a){ *this=a; }; ~_pol(){}; _pol* operator = (const _pol *a) { *this=*a; return this; }; /*_pol* operator = (const _pol &a) { ...copy... return this; };*/ };
List<_sqr> sqr; // squares
_pol pol; // polygon
void sqr2pol_init()
{
_sqr s;
int i,j,p0,p1,p2,p3;
float x,y,x0,x1,y0,y1,a=32,d,_zero=1e-3;
// [init square list to your scenario]
sqr.num=0; pol.x.num=0; pol.y.num=0;
s.s=a; s.x=a; s.y=a;
sqr.add(s); s.x+=a;
sqr.add(s); s.x+=a;
sqr.add(s); s.x+=a;
sqr.add(s); s.x =a; s.y+=a;
sqr.add(s); s.x =a; s.y+=a;
sqr.add(s); s.x+=a;
// [compute point and line lists]
List<_pnt> pnt; _pnt p;
List<_lin> lin; _lin l;
for (pnt.num=0,lin.num=0,i=0;i<sqr.num;i++)
{
x=sqr[i].x;
y=sqr[i].y;
a=sqr[i].s*0.5;
x0=x-a; x1=x+a;
y0=y-a; y1=y+a;
// add non duplicate points only
p.x=x0; p.y=y0; for (j=0;j<pnt.num;j++) { x=pnt[j].x-p.x; y=pnt[j].y-p.y; if ((x*x)+(y*y)<=_zero) break; } if (j>=pnt.num) pnt.add(p); p0=j;
p.x=x0; p.y=y1; for (j=0;j<pnt.num;j++) { x=pnt[j].x-p.x; y=pnt[j].y-p.y; if ((x*x)+(y*y)<=_zero) break; } if (j>=pnt.num) pnt.add(p); p1=j;
p.x=x1; p.y=y1; for (j=0;j<pnt.num;j++) { x=pnt[j].x-p.x; y=pnt[j].y-p.y; if ((x*x)+(y*y)<=_zero) break; } if (j>=pnt.num) pnt.add(p); p2=j;
p.x=x1; p.y=y0; for (j=0;j<pnt.num;j++) { x=pnt[j].x-p.x; y=pnt[j].y-p.y; if ((x*x)+(y*y)<=_zero) break; } if (j>=pnt.num) pnt.add(p); p3=j;
// add non duplicate lines (and update counter n for duplicates)
l.p0=p0; l.p1=p1; l.n=0; for (j=0;j<lin.num;j++) if (((lin[j].p0==l.p0)&&(lin[j].p1==l.p1))||((lin[j].p0==l.p1)&&(lin[j].p1==l.p0))) { lin[j].n++; break; } if (j>=lin.num) lin.add(l);
l.p0=p1; l.p1=p2; l.n=0; for (j=0;j<lin.num;j++) if (((lin[j].p0==l.p0)&&(lin[j].p1==l.p1))||((lin[j].p0==l.p1)&&(lin[j].p1==l.p0))) { lin[j].n++; break; } if (j>=lin.num) lin.add(l);
l.p0=p2; l.p1=p3; l.n=0; for (j=0;j<lin.num;j++) if (((lin[j].p0==l.p0)&&(lin[j].p1==l.p1))||((lin[j].p0==l.p1)&&(lin[j].p1==l.p0))) { lin[j].n++; break; } if (j>=lin.num) lin.add(l);
l.p0=p3; l.p1=p0; l.n=0; for (j=0;j<lin.num;j++) if (((lin[j].p0==l.p0)&&(lin[j].p1==l.p1))||((lin[j].p0==l.p1)&&(lin[j].p1==l.p0))) { lin[j].n++; break; } if (j>=lin.num) lin.add(l);
}
// [copy singular lines only to polygon + connected lines analysis/reorder]
// add first usable (n==0) line to polygon
p0=-1;
for (i=0;i<lin.num;i++)
if (lin[i].n==0)
{
pol.x.add(pnt[lin[i].p0].x);
pol.y.add(pnt[lin[i].p0].y);
pol.x.add(pnt[lin[i].p1].x);
pol.y.add(pnt[lin[i].p1].y);
p0=lin[i].p0; // p0 = start of polygon
p1=lin[i].p1; // p1 = current end of polygon
lin[i].n++; // mark as unusable
break;
}
// add next line to p1 until you can
for (j=1;j;)
{
for (i=0,j=0;i<lin.num;i++)
if (lin[i].n==0)
{
p2=-1;
if (lin[i].p0==p1) p2=lin[i].p1;
if (lin[i].p1==p1) p2=lin[i].p0;
if (p2<0) continue;
pol.x.add(pnt[p2].x);
pol.y.add(pnt[p2].y);
lin[i].n++; // mark as unusable
p1=p2; // update last point
j=1; // continue search
break;
}
}
}
List<T> l;
只是动态线性阵列模板(类似于 std::vector
)T[l.num] l;
l.num
是数组的当前大小l.add(x);
添加新项目 x
到数组的末尾...这是结果:
sqr
pol
输出关于algorithm - 从等正方形构造的几何图形中提取轮廓(圆周)多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33472951/
谁能解释一下原因: (define a (lambda() (cons a #f))) (car (a)) ==> procedure ((car (a))) ==> (procedure . #f)
这是 PyBrain 网站的摘录。我了解大部分正在发生的事情,但是一行让我完全难住了。我以前从未在 python 代码中看到过这样的东西。这是整个循环,对于上下文: for c in [0,
我是gradle / groovy的新手。我想创建将做一些事情的自定义任务。我的第一个问题是任务完成时该如何做?我可以覆盖doFirst / doLast闭包吗?也许我可以重写某些在开始和结束时都会执
我刚刚开始评估 MS 企业库。他们使用以下指令来获取实例: var customerDb = EnterpriseLibraryContainer.Current.GetInstance("C
这是我的 if else Ansible 逻辑.. - name: Check certs exist stat: path=/etc/letsencrypt/live/{{ rootDomain
我正在使用construct 2.8 对一些失传已久的 Pascal 程序创建的一些文件的 header 进行逆向工程。 header 由许多不同的记录组成,其中一些是可选的,我不确定顺序是否固定。
我在将 getchar() 的输入放入 char *arr[] 数组时遇到问题。我这样做的原因是因为输入数据(将是一个带有命令行参数的文件)将存储在一个 char 指针数组中以传递给 execvp 函
通常我们不能约束类型参数 T派生自密封类型(例如 struct 类型)。这将毫无意义,因为只有一种类型适合,因此不需要泛型。所以约束如下: where T : string 或: where T :
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
#include using namespace std; class A { private: int m_i; friend int main(int argc, char cons
这个问题在这里已经有了答案: Are there legitimate uses for JavaScript's "with" statement? (33 个答案) 关闭 9 年前。 我有这个代
在this answer我看到了下一个 Bash 结构。 yes "$(< file.txt)" 什么意思 "$(< file.txt)" ? 我明白了 命令替换 - $(command)用命令的结
if (a == 1) //do something else if (a == 2) //do something else if (a == 3) //do somethi
关于构造的快速简单的问题。 我有以下用于将项目添加到 ListView 的代码。 ListViewItem item = new ListViewItem(); item.Text = file; i
我想使用 std::vector 来控制给定的内存。首先,我很确定这不是好的做法,但好奇心占了上风,无论如何我都想知道如何做到这一点。 我遇到的问题是这样的方法: vector getRow(unsi
下面显示了一段简单的javascript: var mystring = ("random","ignored","text","h") + ("ello world") 这个字符串会生成 hello
在 Java 中,创建对象的标准方法是使用 MyClass name = new MyClass(); 我也经常看到构造 new MyClass() { /*stuff goes in here*/
我正在编写 C++ ndarray 类。我需要动态大小和编译时大小已知的数组(分别分配自由存储和分配堆栈)。我想支持从嵌套的 std::initializer_list 进行初始化。 动态大小的没问题
我正在将一个项目从 Visual Studio 2005 转换为 Visual Studio 2008,并提出了上述结构。 using Castle.Core.Resource; using Cast
我想知道我在这里的想法是否正确,我主要针对接口(interface)进行编程,所以我想知道下面的类是否应该通过 DI 注入(inject),或者我应该自己实例化一个类... 注意:这些服务保存在我的核
我是一名优秀的程序员,十分优秀!