HGRippleRadarView icon indicating copy to clipboard operation
HGRippleRadarView copied to clipboard

Add item to specific circle

Open diegogarciar opened this issue 5 years ago • 1 comments

Is there a possibility or a future update to specifically add an item into a certain circle? I want to use this radar and place the items depending on the distance from the center.

diegogarciar avatar Jan 22 '19 21:01 diegogarciar

It found out it was not that difficult, I simply kept track of the positions of each circle


var allCirclePositions = [Int:[CGPoint]]()
    /// browse circles and find possible position to draw layer
    private func findPossiblePositions() {
        for (index, layer) in circlesLayer.enumerated() {
            let origin = layer.position
            let radius = radiusOfCircle(at: index)
            let circle = Circle(origin: origin, radius:radius)
            
            // we calculate the capacity using: (2π * r1 / 2 * r2) ; r2 = (itemRadius + padding/2)
            let capicity = (radius * CGFloat.pi) / (itemRadius + paddingBetweenItems/2)
            
            /*
             Random Angle is used  to don't have the gap in the same place, we should find a better solution
             for example, dispatch the gap as padding between items
             let randomAngle = CGFloat(arc4random_uniform(UInt32(Float.pi * 2)))
             */
            var circlePositions = [CGPoint]()
            for index in 0 ..< Int(capicity) {
                let angle = ((CGFloat(index) * 2 * CGFloat.pi) / CGFloat(capicity))/* + randomAngle */
                let itemOrigin = Geometry.point(in: angle, of: circle)
                circlePositions.append(itemOrigin)
            }
            allPossiblePositions.append(contentsOf: circlePositions)
            allCirclePositions[index] = circlePositions
        }
    }

Then created a new addItem public function

public func add(item: Item,at circle: Int, using animation: CAAnimation = Animation.transform()) {
        
        guard circle < circlesLayer.count else{return}
        
        if allPossiblePositions.isEmpty {
            findPossiblePositions()
        }
        
        var count = allCirclePositions[circle]!.count
        var offset = 0
        while count == 0 { //if no available positions, try to place in next outer circle
             offset += 1
            let outerCircle = circle + offset
            if outerCircle >= circlesLayer.count{
              return // no more circles outside
           }
            count = allCirclePositions[outerCircle]!.count
        }
        var randomIndex = Int(arc4random_uniform(UInt32(count)))
        allCirclePositions[circle + offset]?.remove(at: randomIndex)
        add(item: item, at: &randomIndex, using: animation)
    }

diegogarciar avatar Jan 22 '19 22:01 diegogarciar