86593


２点間の与えられた始点と終点の間に連続した点を置く為に、ブレゼンハムのアルゴリズムを使用したいのですが、座標(x,y)がCGFloat値で小数点以下の数値があります。  
そこも含めて一旦、整数値Intにし計算する必要があると思うのですが、欲しいのは最終的に小数点を含むCGFloat値である為、どの様にSwiftで小数点→整数→小数点にするのが効率よく記述できますでしょうか。ブレゼンハムのコード自体は以下の様にしたいと考えています。宜しくお願い致します。

[code]

    func getPoints(p0: CGPoint, p1: CGPoint) -> [CGPoint] {
            var points = [CGPoint]()
            var x0: Int = Int(p0.x)
            var y0: Int = Int(p0.y)
            let x1: Int = Int(p1.x)
            let y1: Int = Int(p1.y)
            let dx: Int = Int(abs(p1.x - p0.x)) // DeltaX
            let dy: Int = Int(abs(p1.y - p0.y)) // DeltaY
            let sx: Int = (p1.x>p0.x) ? 1 : -1 // StepX
            let sy: Int = (p1.y>p0.y) ? 1 : -1 // StepT
            var err = dx - dy
            while true {
                if x0 >= 0, y0 >= 0 { points.append(CGPoint(x: x0, y: y0)) }
                if x0 == x1, y0 == y1 { break }
                let e2 = 2*err
                if e2 > -dy {
                    err -= dy
                    x0 += sx
                }
                if e2 < dx {
                    err += dx
                    y0 += sy
                }
            }
            return points
        }
    
[/code]


CC BY-SA 4.0
2022-02-24T05:53:20.250
86549
2022-02-27T03:15:54.780
14780
question
swift ios
CGFloat値の小数点以下を含む数値を整数にし、また小数点を含む数値に戻したい。


浮動小数点数（`CGFloat`）と整数（`Int`）の変換ではなく、丸め処理（`rounded()`）で小数点以下を切り捨てたほうが、処理時間を短縮できるという結果になりました。

[code]

    import Foundation
    
    // 質問で提示された、CGFloatとInt間の変換を伴う処理
    func getPointsA(p0: CGPoint, p1: CGPoint) -> [CGPoint] {
        var points = [CGPoint]()
        var x0: Int = Int(p0.x)
        var y0: Int = Int(p0.y)
        let x1: Int = Int(p1.x)
        let y1: Int = Int(p1.y)
        let dx: Int = Int(abs(p1.x - p0.x))
        let dy: Int = Int(abs(p1.y - p0.y))
        let sx: Int = (p1.x > p0.x) ? 1 : -1
        let sy: Int = (p1.y > p0.y) ? 1 : -1
        var err = dx - dy
        
        while true {
            if x0 >= 0, y0 >= 0 {
                points.append(CGPoint(x: x0, y: y0))
            }
            if x0 == x1, y0 == y1 {
                break
            }
            let e2 = err * 2
            if e2 > -dy {
                err -= dy
                x0 += sx
            }
            if e2 < dx {
                err += dx
                y0 += sy
            }
        }
        
        return points
    }
    
    // 丸め処理で、小数点以下を切り捨てる処理
    func getPointsB(p0: CGPoint, p1: CGPoint) -> [CGPoint] {
        var points = [CGPoint]()
        var x0 = p0.x.rounded(.down)
        var y0 = p0.y.rounded(.down)
        let x1 = p1.x.rounded(.down)
        let y1 = p1.y.rounded(.down)
        let dx = abs(p1.x - p0.x)
        let dy = abs(p1.y - p0.y)
        let sx = (p1.x > p0.x) ? 1.0 : -1.0
        let sy = (p1.y > p0.y) ? 1.0 : -1.0
        var err = dx - dy
        
        while true {
            if x0 >= 0, y0 >= 0 {
                points.append(CGPoint(x: x0, y: y0))
            }
            if x0 == x1, y0 == y1 {
                break
            }
            let e2 = err * 2
            if e2 > -dy {
                err -= dy
                x0 += sx
            }
            if e2 < dx {
                err += dx
                y0 += sy
            }
        }
        
        return points
    }
    
    // 処理時間の比較
    let startTime = Date()
    let points = getPointsA(p0: CGPoint(x: 0.0, y: 0.0), p1: CGPoint(x: 5000.3, y: 10000.7))
    let interval = -startTime.timeIntervalSinceNow
    print(interval)
    
    let startTime2 = Date()
    let points2 = getPointsB(p0: CGPoint(x: 0.0, y: 0.0), p1: CGPoint(x: 5000.3, y: 10000.7))
    let interval2 = -startTime2.timeIntervalSinceNow
    print(interval2)
    
    // 結果
    // 0.00038504600524902344
    // 0.00018894672393798828
    
[/code]

型変換のコストがかからない分、時間が短いということだと思われます。


CC BY-SA 4.0
2022-02-27T03:15:54.780
86593
2022-02-27T03:15:54.780
18540
86549
answer