具有如下另一个路径 [英] Having a path that follows another one

查看:121
本文介绍了具有如下另一个路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有坐标的数组(地理坐标,但是这不应该的问题),我需要有一个跟随我们已经拥有了路径的路径。

I have an array of coordinates (geographic coordinates, but that shouldn't matter) and I need to have a path that "follows" the path that we already have.

我们需要的东西像下面的图片上。你可以看到,该路径是不完全一样的(不是简单的偏移量),我们不希望它无论是规模。

We need something like on the following image. You can see that the path is not exactly the same (not a simple offset) and we don't want it to scale either.

有一些库,我们可以用这样做或如何实现这一一些指点?

Is there some library that we could use to do that or some pointers on how to implement this?

推荐答案

花费了太多时间试图找到我结束了编码工作解决方案后,我自己的:

After spending way too much time trying to find a working solution I ended up coding my own:

CGContextBeginPath(context);
CGMutablePathRef path = CGPathCreateMutable();

MKMapPoint *mapPoints = itineraryPath.points;
CGPoint previousEdgeNormal = CGPointZero;
CGPoint previousDrawnPoint = CGPointZero;
float offsetDistance = self.pathWidth*2.5;

for(int i = 0; i < itineraryPath.pointCount; i++) {
    if(i < itineraryPath.pointCount-1) {
        MKMapPoint mapPoint = mapPoints[i];
        CGPoint point = [self pointForMapPoint:mapPoint];
        MKMapPoint secondMapPoint = mapPoints[i+1];
        CGPoint secondPoint = [self pointForMapPoint:secondMapPoint];

        float xDelta = point.x-secondPoint.x;
        float yDelta = point.y-secondPoint.y;
        float factor = xDelta > 0 ? -1 : 1;

        float segmentLength = sqrt(pow(xDelta, 2.0)+pow(yDelta, 2.0));

        float yDeltaAngle = asin(sin(M_PI/2*factor)*yDelta/segmentLength);
        float opposedAngle = M_PI/2-yDeltaAngle;
        float remainingAngle = M_PI/2-opposedAngle;
        float yOffset = sin(opposedAngle)*offsetDistance/sin(M_PI/2)*factor;
        float xOffset = sin(remainingAngle)*offsetDistance/sin(M_PI/2)*factor;

        CGPoint offsetFirstPoint = CGPointMake(point.x+xOffset, point.y+yOffset);
        CGPoint offsetSecondPoint = CGPointMake(secondPoint.x+xOffset, secondPoint.y+yOffset);

        if(i == mapPointIndex) {
            CGPathMoveToPoint(path, NULL, offsetFirstPoint.x, offsetFirstPoint.y);
            previousDrawnPoint = offsetFirstPoint;
        }
        else {
            float xNormalDifference = previousEdgeNormal.x-offsetFirstPoint.x;
            float yNormalDifference = previousEdgeNormal.y-offsetFirstPoint.y;

            float xAverage = (xNormalDifference)/2;
            float yAverage = (yNormalDifference)/2;
            CGPoint normalAveragePoint = CGPointMake(offsetFirstPoint.x+xAverage, offsetFirstPoint.y+yAverage);

            CGPathAddLineToPoint(path, NULL, normalAveragePoint.x, normalAveragePoint.y);
            previousDrawnPoint = normalAveragePoint;
        }

        previousEdgeNormal = offsetSecondPoint;
    }
    else
        CGPathAddLineToPoint(path, NULL, previousEdgeNormal.x, previousEdgeNormal.y);
}

唯一需要注意的是,它不处理锐角很好呢。

Only caveat is that it doesn't handle acute angles very well yet.

但除此之外,一些提供了pretty整齐(右边是原来的路径,左偏移)

But otherwise gives something pretty neat (right is original path, left is offset)

这篇关于具有如下另一个路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆