簡體   English   中英

有一條遵循另一條道路的道路

[英]Having a path that follows another one

我有一個坐標數組(地理坐標,但這沒關系),我需要有一個“遵循”我們已經擁有的路徑的路徑。

我們需要類似下圖的內容。 您會看到路徑並不完全相同(不是簡單的偏移量),我們也不希望其縮放。

是否有一些我們可以用來完成此操作的庫或一些有關如何實現此操作的指針?

路徑

在花了太多時間試圖找到可行的解決方案之后,我最終編寫了自己的代碼:

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);
}

唯一需要注意的是,它不能很好地處理銳角。

但是否則會給人一些整潔的感覺(右邊是原始路徑,左邊是偏移量)

地圖

您想要的就是一條平行曲線: http : //en.wikipedia.org/wiki/Parallel_curve

一種生成方法是計算每個點上原始曲線的法線,然后使用該法線偏移這些點。 如果只有直線段,這非常簡單。 對於圓弧和貝塞爾曲線,還需要弄清楚如何修改控制點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM