我有两个多边形,它们的顶点存储为双坐标.我想找到这些多边形的交叉区域,所以我正在看Clipper库(C++版本).问题是,Clipper仅适用于整数数学(它使用Long类型).
有没有办法可以安全地转换具有相同比例因子的多边形,将它们的坐标转换为Longs,使用Clipper执行交点算法,然后使用相同的因子缩小生成的交叉点多边形,并将其转换回Double没有太多的精度损失?
我无法理解如何做到这一点.
我正在尝试编写一段代码,给出一个多边形列表(定义为IntPoints列表列表)检查是否有任何触摸,如果是,则将它们合并为一个多边形.为了做到这一点,我已经尝试了以下两种方法:
List<List<IntPoint>> output=new List<List<IntPoint>>();
output = Clipper.SimplifyPolygons(input,PolyFillType.pftPositive);
Run Code Online (Sandbox Code Playgroud)
和
Clipper c = new Clipper();
c.AddPaths(input, PolyType.ptClip, true);
c.Execute(ClipType.ctUnion, output);
Run Code Online (Sandbox Code Playgroud)
现在这两个都很容易将多边形合并在一起,但它们有点过于粗糙,因为任何多边形开放空间都会被忽略,而开放区域只是组合成一个多边形,这意味着:
发生.现在这显然是错误的,因为这两个多边形不相互接触.两种方法都会出现相同的结果.结果与输入相同.知道如何解决这个问题吗?sollution不必使用限幅器库(我没有与它结合)但我确实需要使用由点列表定义的多边形的东西输入是List>其中Intpoint只是一个包含x的结构和y.
编辑我注意到当另一个多边形内没有多边形时也会出现这个问题,所以解决方案总是"填充"编辑编辑:这里也是一个输入可能是什么样的例子
input[0][0]
{ClipperLib.IntPoint}
X: -724
Y: -472
input[0][1]
{ClipperLib.IntPoint}
X: 428
Y: -472
input[0][2]
{ClipperLib.IntPoint}
X: 428
Y: -472
input[0][3]
{ClipperLib.IntPoint}
X: 428
Y: 632
input[0][4]
{ClipperLib.IntPoint}
X: 428
Y: 632
input[0][5]
{ClipperLib.IntPoint}
X: -724
Y: 632
input[0][6]
{ClipperLib.IntPoint}
X: -724
Y: 632
input[0][7]
{ClipperLib.IntPoint}
X: -724
Y: -472
input[0][8]
{ClipperLib.IntPoint}
X: -88
Y: -218
input[0][9]
{ClipperLib.IntPoint}
X: -107
Y: …
Run Code Online (Sandbox Code Playgroud) 该代码的最终目标是确保客户定义的形状实际上可以由我们的......呃机器加工.要做到这一点,我们将指定的形状向内偏移到钻头的半径,然后向外向外偏移相同的量,从而将任何太小的部分弄圆,以实际适合钻头.对于多边形偏移,我们使用的是Angus Johnson的Clipper库,版本5.1.6(c ++).
但是从图中可以看出,这导致了一些意想不到的形状.在图片中,我使用-radius偏移原始形状(绿色,大部分被后面的绘图覆盖),ClipperLib::OffsetPolygon
以获得黄色形状,然后偏移半径以获得红色形状.
理论上,对于链接中显示的情况,这应该导致红色形状完全匹配绿色形状.
如果出现上述结果可能会出现什么问题?
我正在使用CLIPPER库来偏移线并尝试制作平行线.
ClipperOffset co = new ClipperOffset();
co.AddPath (s, JoinType.jtRound, EndType.etOpenRound);
co.Execute (ref solution, 15);
Run Code Online (Sandbox Code Playgroud)
结果是附件中的右图.我需要平行线而不是"围绕"主线的偏移线.
有没有人知道它是否可能在Clipper或任何人有任何想知道如何过滤结果点以删除不必要的?
我需要测试一个点是否击中带有孔和岛的多边形。我想了解我应该如何做到这一点。这没有记录,我找不到任何解释或例子。
我所做的是+1
对每个外部多边形命中和-1
每个内部多边形命中进行计数。所得总和为:
该类根据绕数HitData
分隔路径orientation
,以避免不必要的重新计算。Clipper.PointInPolygon()
应用于每条路径后,总和很容易计算。
但有两个主要缺点:
Clipper.PointInPolygon()
于每一条 道路;PolyTree
。有 Clipper 实践经验的人(@angus-johnson?)可以消除这种困惑吗?
我的问题再次是:我应该如何实现这个?虽然 Clipper 库中已经有现成的实际解决方案,但我是否要重新发明轮子?
旁注:
PolyTree
仍然需要测试每条 路径来确定PolyNode
点在哪一条。没有Clipper.PointInPolyTree()
方法,因此,据我所知PolyTree
没有帮助。
分隔外多边形和内多边形的结构:
public class HitData
{
public List<List<IntPoint>> Outer, Inner;
public HitData(List<List<IntPoint>> paths)
{
Outer = new List<List<IntPoint>>();
Inner = new List<List<IntPoint>>(); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Clipper C++ 库来实现一个is_bordering
函数,如下所示。
bool is_bordering(Path p1, Path p2) {
Paths solutions;
Clipper c;
// execute intersection on paths
c.AddPath(p1, ptSubject, true);
c.AddPath(p2, ptClip, true);
c.Execute(ctIntersection, solutions, pftNonZero);
return (solutions.size() > 0); // the paths share edges
}
int main() {
Path p1, p2;
p1 << IntPoint(0,0) << IntPoint(1,0) << IntPoint(0,1) << IntPoint(0,0);
p2 << IntPoint(1,0) << IntPoint(1,1) << IntPoint(0,1) << IntPoint(1,0);
cout << is_bordering(p1, p2) << endl;
}
Run Code Online (Sandbox Code Playgroud)
我认为当测试两个边界多边形时ctIntersection
,结果将包含边界边缘,但对我来说这返回 false。我对上面的期望如下,绿色代表solutions
路径。
我如何让这个函数工作(使用 Clipper 库)?
我可以使用 Clipper 检查多边形轮廓是否与其自身相交(如果是复杂多边形还是简单多边形)?
我知道它不会使多边形无效,但就我而言,我想避免自相交的多边形。
我正在使用限幅器对多边形执行一系列操作,这些操作代表程序中对象的轮廓.问题是,我现在想要剪切一个线段网格来填充这些轮廓,但我正在努力用Clipper做到这一点.
目前我正在将线条转换为厚度为2个单位的矩形,然后我进行交叉操作,最后我需要将新多边形还原为线段.这虽然效率很低,但会产生很多错误.
这可以用Clipper完成,如果没有其他我可以使用或我需要实现我自己的线段裁剪器吗?
我使用限幅器库.在图中,红色和黑色是剪辑,绿色是多边形.代码如下所示.但是,我不明白为什么生成的联合多边形是(7 3 4 14 9 1 2 6).
我认为它应该是(1 4 14 9)
?数字是图中所示的顶点.
using System;
using ClipperLib;
using Polygon = System.Collections.Generic.List<ClipperLib.IntPoint>;
using Polygons = System.Collections.Generic.List<System.Collections.Generic.List<ClipperLib.IntPoint>>;
namespace ClipperLibrary_Test
{
class Program
{
static void Main(string[] args)
{
Polygons subj = new Polygons(1);
subj.Add(new Polygon(4));
subj[0].Add(new IntPoint(0, 0));
subj[0].Add(new IntPoint(0, 70));
subj[0].Add(new IntPoint(100, 70));
subj[0].Add(new IntPoint(100, 0));
Polygons clip = new Polygons();
clip.Add(new Polygon(4));
clip[0].Add(new IntPoint(40, 0));
clip[0].Add(new IntPoint(40, 100));
clip[0].Add(new IntPoint(150, 100));
clip[0].Add(new IntPoint(150, 0));
clip.Add(new Polygon(4)); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Clipper 库按线分割多边形。执行裁剪后,返回空路径。有人可以建议正确的方法来做同样的事情吗?
Paths clip(2),soln;
clip[0] << IntPoint(-264,-210) << IntPoint(650,-209);
Path sub = clip[0];
Path poly << IntPoint(531,49) << IntPoint(-21,49) << IntPoint(-970,-961) << IntPoint(-945,-1019) << IntPoint(1045,-1071) ;
Clipper c;
c.AddPath(poly,ptSubject,true);
c.AddPath(sub,ptClip,true);
c.Execute(ctIntersection,soln,pftNonZero, pftNonZero);
std::cout << soln.size() << "soln size";
Run Code Online (Sandbox Code Playgroud)
溶液尺寸为零。
Clipper 接受整数输入,但我想传递浮点值而不丢失精度。用于整数和双精度值的 Clipper 结构。
struct IntPoint {
cInt X;
cInt Y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
#else
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
#endif
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
{
return a.X == b.X && a.Y == b.Y;
}
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
{
return a.X != b.X || …
Run Code Online (Sandbox Code Playgroud)