iOS 道格拉斯普克(Douglas-Peuker)算法

介紹

Douglas-Peukcer算法由D.Douglas和T.Peueker于1973年提出,是線狀要素抽稀的經(jīng)典算法。用它處理大量冗余的幾何數(shù)據(jù)點(diǎn),既可以達(dá)到數(shù)據(jù)量精簡(jiǎn)的目的,有可以在很大程度上保留幾何形狀的骨架。

算法思路

將待處理曲線的首末點(diǎn)虛連一條直線,求所有中間點(diǎn)與直線的距離,并找出最大距離值dmax ,用dmax與抽稀閾值tolerance相比較:

若dmax < tolerance,這條曲線上的中間點(diǎn)全部舍去;

若dmax ≥ tolerance,則以該點(diǎn)為界,把曲線分為兩部分,對(duì)這兩部分曲線重復(fù)上述過(guò)程,直至所有的點(diǎn)都被處理完成。

用途

可用于圖表的繪制和地圖繪制線減少軌跡點(diǎn)

Demo效果

遞歸核心代碼

- (NSArray *)reduceWithDouglasPeuker:(NSArray *)points tolerance:(CGFloat)tolerance
{
    if (tolerance <= 0 || points.count < 3) {
        return points;
    }
    
    NSInteger index = 0;
    CGFloat dmax = 0.f;
    
    // 遍歷除首尾點(diǎn)以外的點(diǎn)
    for (NSInteger i = 1; i < points.count - 1; i ++) {
        CGFloat distance = [self getDistanceWithStartPoint:[points.firstObject CGPointValue] endPoint:[points.lastObject CGPointValue] betweenPoint:[points[i] CGPointValue]];
        if (distance > dmax)
        {
            dmax = distance;
            index = i;
        }
    }
    
    // 遞歸
    if (dmax >= tolerance) {
        NSArray *resultList = [self reduceWithDouglasPeuker:[points subarrayWithRange:NSMakeRange(0, index)] tolerance:tolerance];
        return [resultList arrayByAddingObjectsFromArray:[self reduceWithDouglasPeuker:[points subarrayWithRange:NSMakeRange(index, points.count - index)] tolerance:tolerance]];
    } else {
        return @[points.firstObject, points.lastObject];
    }
    
}

// 鞋帶公式求三角形的高, 也可以用海倫公式
- (CGFloat)getDistanceWithStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint betweenPoint:(CGPoint)point
{
    CGFloat dx = startPoint.x - endPoint.x;
    CGFloat dy = startPoint.y - endPoint.y;
    
    CGFloat sxey = startPoint.x * endPoint.y;
    CGFloat exsy = endPoint.x * startPoint.y;
    
    // 起止點(diǎn)的長(zhǎng)度
    CGFloat length = sqrt(dx * dx + dy * dy);
    
    return fabs(dy * point.x - dx * point.y + sxey - exsy) / length;
}

Demo

Demo

參考

計(jì)算幾何-道格拉斯普克(Douglas-Peuker)算法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容