如何生成凹面多边形的回声路径

维伦

我需要一种算法来绘制任意多边形的回声路径。如果多边形是凸的,则很容易解决。要了解我的意思,请查看波纹管,其中黑色是原始多边形,红色是从原始多边形生成的回声多边形。凸多边形回波演示

d 是给定的回声路径之间的距离

β 角度很容易计算已知顶点的坐标

如您所见,我们可以为每个顶点进行计算L,从而为下一个回声路径提供新的顶点。

问题是,当我们在某个点具有凹面多边形时,会得到一张自相交多边形的丑陋图片。请看这张照片。在此处输入图片说明

我想做的是生成没有自相交部分的回波多边形,即没有带有虚线的部分。算法或java代码将非常有帮助。谢谢。

编辑

只需添加一段代码即可生成注释中要求的凸多边形的回波路径。

public List<MyPath> createEchoCoCentral( List<Point> pointsOriginal, float encoderEchoDistance, int appliqueEchoCount){

    List<Point> contourPoints = pointsOriginal;
    List<MyPath> echoPaths = new ArrayList<>();
    for (int round = 0; round < appliqueEchoCount; round++) {

        List<Point> echoedPoints = new ArrayList<>();
        int size = contourPoints.size()+1;//+1 because we connect end to start

        Point previousPoint = contourPoints.get(contourPoints.size() - 1);
        for (int i = 0; i < size; i++) {
            Point currentPoint;
            if (i == contourPoints.size()) {
                currentPoint = new Point(contourPoints.get(0));
            } else {
                currentPoint = contourPoints.get(i);
            }
            final Point nextPoint;
            if (i + 1 == contourPoints.size()) {
                nextPoint = contourPoints.get(0);
            } else if (i == contourPoints.size()) {
                nextPoint = contourPoints.get(1);
            } else {
                nextPoint = contourPoints.get(i + 1);
            }
            if (currentPoint.x == previousPoint.x && currentPoint.y == previousPoint.y) continue;
            if (currentPoint.x == nextPoint.x && currentPoint.y == nextPoint.y) continue;

            // signs needed o determine to which side of polygon new point will go
            float currentSlope = (float) (Math.atan((previousPoint.y - currentPoint.y) / (previousPoint.x - currentPoint.x)));
            float signX = Math.signum((previousPoint.x - currentPoint.x));
            float signY = Math.signum((previousPoint.y - currentPoint.y));
            signX = signX == 0 ? 1 : signX;
            signY = signY == 0 ? 1 : signY;

            float nextSignX = Math.signum((currentPoint.x - nextPoint.x));
            float nextSignY = Math.signum((currentPoint.y - nextPoint.y));
            nextSignX = nextSignX == 0 ? 1 : nextSignX;
            nextSignY = nextSignY == 0 ? 1 : nextSignY;

            float nextSlope = (float) (Math.atan((currentPoint.y - nextPoint.y) / (currentPoint.x - nextPoint.x)));
            float nextSlopeD = (float) Math.toDegrees(nextSlope);

            //calculateMidAngle - is a bit tricky function that calculates angle between two adjacent edges
            double S = calculateMidAngle(currentSlope, nextSlope, signX, signY, nextSignX, nextSignY);
            Point p2 = new Point();

            double ew = encoderEchoDistance / Math.cos(S - (Math.PI / 2));
            p2.x = (int) (currentPoint.x + (Math.cos(currentSlope - S)) * ew * signX);
            p2.y = (int) (currentPoint.y + (Math.sin(currentSlope - S)) * ew * signX);

            echoedPoints.add(p2);
            previousPoint = currentPoint;


        }

        //createPathFromPoints just creates MyPath objects from given Poins set
        echoPaths.add(createPathFromPoints(echoedPoints));
        //remove last point since it was just to connect end to first point
        echoedPoints.remove(echoedPoints.size() - 1);
        contourPoints = echoedPoints;
    }
    return echoPaths;
}
维伦

好的,找到了一个可以满足我需要的库。它叫做快船队

如果有人感兴趣这里也有Java实现

使用Java库,几行代码可以解决问题

    Path originalPath = new Path();
    for (PointF areaPoint:pointsOriginal){
        originalPath.add(new LongPoint((long)areaPoint.x, (long)areaPoint.y));
    }
    final ClipperOffset clo = new ClipperOffset();
    Paths clips = new Paths();
    Paths solution = new Paths();
    clips.add(originalPath);
    clo.addPaths( clips, Clipper.JoinType.SQUARE, Clipper.EndType.CLOSED_LINE );
    float encoderEchoDistance = (float) UnitUtils.convertInchOrMmUnitsToEncoderUnits(this, inchOrMm, appliqueEchoDistance);
    clo.execute( solution, encoderEchoDistance );
    // Now solution.get(0) will contain path that has offset from original path
    // and what is most important it will not have self intersections.

它是开源的,因此我将深入了解实施细节。感谢所有尝试提供帮助的人。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何生成多边形图

来自分类Dev

是否可以在PhysicsJS中创建凹面多边形?

来自分类Dev

Sketchup API在视图类中绘制凹面多边形

来自分类Dev

折线生成多边形?

来自分类Dev

Google Maps:如何从SVG路径创建多边形

来自分类Dev

如何动态生成在Canvas中向上移动的多边形?

来自分类Dev

如何连接多边形?

来自分类Dev

如何拖动多边形?

来自分类Dev

如何旋转多边形?

来自分类Dev

ITextShape可点击的多边形或路径

来自分类Dev

读入SVG路径/多边形的坐标

来自分类Dev

从多边形的路径获取latLng失败

来自分类Dev

将多边形转换为路径

来自分类Dev

从3D对象获取2D凹面多边形

来自分类Dev

程序生成低多边形树

来自分类Dev

从图像(填充形状)生成多边形

来自分类Dev

在多边形中生成随机点

来自分类Dev

生成外凸多边形

来自分类Dev

如何在FF和IOS中使用剪切路径多边形

来自分类Dev

如何在Vue中保存Google地图编辑的多边形路径

来自分类Dev

如何比.each通过svg路径和多边形循环更快?

来自分类Dev

如何为 SVG 设置动画(使用多边形,而不是路径)?

来自分类Dev

如何在 <svg>-Tag 中居中多边形和路径?

来自分类Dev

如何计算边界多边形?

来自分类Dev

如何沿着多边形移动对象

来自分类Dev

如何标记SVG多边形

来自分类Dev

如何创建多边形div

来自分类Dev

我将如何迭代多边形?

来自分类Dev

如何使用EaselJS绘制多边形?