iOS之兩圓之間標准圓的隨機生成
相信很多社交產品中,肯定會存在尋找附近人或者附近商家的需求,類似下圖,在大圓和小圓之間(橘色區域)生成一系列的隨機圓,並且所有隨機圓之間也不能有交集,我暫且稱這種圓為標准圓。思路一:
對於這個需求,我一開始也陷入了寫死數據的套路,但是在兼容大小圓半徑上做了一定的兼容,大致的將大圓切分成9塊,然後在除了中間區域外的8塊區域再生成一系列的偽標准圓。然後取值時現隨機選取8塊區域,再隨機從塊區拿取偽標准圓:
很明顯,在 1、3、6、8 塊中及中間塊 存在很大的誤差,明顯也不可取
Objective-c代碼如下:
// 1: 判斷隨機生成的 圓 包含在 self 這個大圓內部 if ( sqrt(pow(self.center.x - randomCPX, 2) + pow(self.frame.size.height / 2 - randomCPY, 2)) < (R - r) ) { }
// 2: 判斷隨機生成的 圓 不在 中間 這個圓 不能重合, 即得到兩個圓之間的小圓 if (sqrt(pow(self.center.x - randomCPX, 2) + pow(self.frame.size.height / 2 - randomCPY, 2)) > (Rr + r)) { }3、從第2步得到的隨機圓2中,篩選出和已存在的標准圓不相交隨機圓3,隨機圓3即我們所需要的標准圓(其中圓2是已經存在的標准圓,那麼只有圓1才是該步驟所需要的隨機圓3)對應的數學公式,當圓心距小於兩圓半徑之和時 兩圓相交或兩圓內含,隨機圓2應該廢棄:
// 3: 新生成的 圓 和已經存在的 圓 不能重合 BOOL success = YES; for (NSValue *value in randomCircleInfos) { CircleInfo circle; [value getValue:&circle]; // 只要新生成的 圓 和 任何一個存在的 圓 有交集,則失敗 if (sqrt(pow(circle.center.x - randomCPX, 2) + pow(circle.center.y - randomCPY, 2)) <= (circle.radius + r)) { success = NO; break ; } } if (success) { [randomCircleInfos addObject:[self standardCircle:randomCPX centerY:randomCPY radius:r]];}為了尋找 8 個標准圓一共生成了 53 個隨機圓 生成了 29 個在大圓內部的圓 生成了 9 個在大圓內部的圓且不與中圓有交集的圓 為了尋找 8 個標准圓一共生成了 38 個隨機圓 生成了 28 個在大圓內部的圓 生成了 10 個在大圓內部的圓且不與中圓有交集的圓
只要通過這三步成功後,即得到了我們所要的標准圓,從算法的時間復雜度看 ,得到標准圓的復雜度為O(n*n),對於小量了標准圓來說,速度是非常快的:(當然效率上還由隨機圓的半徑有關系)
但是在產生大量的標准圓上,隨機生成的總量會非常大:(可以考慮將隨機圓半徑減少,或者生成該頁面之前,提前生成好這些標准圓相關數據:即圓心坐標和半徑)