0

Swift で Verlet ロープを実装しようとしています。制約から点質量の位置を修正しようとすると、それらが非常に急速に離れてしまい、座標が NaN になるという問題が発生しています。私のコードで何が間違っている可能性がありますか?

import Foundation

private let DEF_POINT_COUNT = 10
private let CONST_ITERATIONS = 5

@objc class PointMass: DebugPrintable {
    var point: NSPoint
    private var oldPoint: NSPoint

    var x: Double {
        get { return Double(point.x) }
    }

    var y: Double {
        get { return Double(point.y) }
    }

    var debugDescription: String {
        get { return "\(point)" }
    }

    init(_ point: NSPoint) {
        self.point = point
        self.oldPoint = point
    }

    func updatePosition() {
        let dx = point.x - oldPoint.x
        let dy = (point.y - oldPoint.y)

        oldPoint = point

        point = NSPoint(x: point.x + dx, y: point.y + dy)
    }

    func updatePosition(point: NSPoint) {
        let dx = point.x - self.point.x
        let dy = point.y - self.point.y
        self.oldPoint = NSPoint(x: oldPoint.x + dx, y: oldPoint.y + dy)
        self.point = point
    }
}

struct Constraint {
    var p1: PointMass
    var p2: PointMass
    var len: Double

    func fixPoints() {
        let dx = p2.x - p1.x
        let dy = p2.y - p1.y

        let dist = sqrt(dx*dx + dy*dy)

        let diff = (dist - len)/len

        p2.updatePosition(NSPoint(x: p2.x - diff*dx*0.5, y: p2.y - diff*dy*0.5))
        p1.updatePosition(NSPoint(x: p1.x + diff*dx*0.5, y: p1.y + diff*dy*0.5))
    }
}

@objc class Rope: NSObject {
    let points: [PointMass]
    let constraints: [Constraint]

    init(anchor: NSPoint, end: NSPoint, length: Double, count: Int = DEF_POINT_COUNT) {
        let anchorPoint = PointMass(anchor)
        let endPoint = PointMass(end)

        let dx = (anchorPoint.x - endPoint.x)/Double(count)
        let dy = (anchorPoint.y - endPoint.y)/Double(count)

        let constraintLength = length/Double(count)

        var points = [endPoint]
        var constraints: [Constraint] = []

        for i in 1...count {
            let prevPoint = points[i-1]
            let newPoint = PointMass(NSPoint(x: prevPoint.x + dx, y: prevPoint.y + dy))

            let constraint = Constraint(p1: prevPoint, p2: newPoint, len: constraintLength)

            points.append(newPoint)
            constraints.append(constraint)
        }

        self.points = points
        self.constraints = constraints
    }

    func update(anchor: NSPoint, endPoint: NSPoint) {
        points.first?.updatePosition(endPoint)
        points.last?.updatePosition(anchor)

        for point in points {
            point.updatePosition()
        }

        for i in 0...CONST_ITERATIONS {
            for constraint in constraints {
                constraint.fixPoints()
            }
        }
    }
}
4

1 に答える 1

0

それを見つけた。fixPoints()私が疑ったように、問題は方法にありました。

この線

let diff = (dist - len)/len

代わりにする必要があります

let diff = (len - dist)/dist
于 2014-12-15T12:26:57.923 に答える