1

Maya でスクリプトを試して、重力とそのロットが球体オブジェクトで動作するかどうかを確認していますが、現在は正常に動作しています (月と地球をスケーリングして重力効果を調整してみました)。さらに一歩進んで衝突を追加して、オブジェクトが互いに跳ね返るのを試みるのが好きですが、昨日長い間見回した後、3D を気にせずに 2D オブジェクトで十分に難しいことがわかりました。

両方のオブジェクト間の距離を取得し、それを両方のオブジェクトの半径と比較する衝突を検出できるビットを書くことができました。次にすること。正直なところ、それが正しいかどうかさえわかりません」

それがどのように機能するかを理解するために、メイン パーツの現在の段階を次に示します。objSel[j] は現在選択されているオブジェクトであり、allObjects は現在選択されているオブジェクト以外のすべてです。

def moveObjects(originalTime,objSel,objMultiplySize):
    moveAmounts = []
    crashed = False
    for j in range(len(objSel)):

        #get initial values
        originalVelocity = getVelocity(objSel[j],originalTime,objMultiplySize)
        objVolume = getVolume(objSel[j],objMultiplySize)
        allObjects = selectAllOtherObjects(objSel[j], objSel)

        #calculate gravity effect on object
        xDist = 0
        yDist = 0
        zDist = 0
        for i in range (0, len(allObjects) ):
            attraction = calcuateForce(objSel[j],allObjects[i],objMultiplySize)
            distanceFromObj = getDistance(allObjects[i],objSel[j],objMultiplySize)[1]
            xDist += distanceFromObj[0] * attraction / (objVolume*2.15*math.pi)
            yDist += distanceFromObj[1] * attraction / (objVolume*2.15*math.pi)
            zDist += distanceFromObj[2] * attraction / (objVolume*2.15*math.pi)
        gravityEffect = [xDist,yDist,zDist]
        newX = (originalVelocity[0]+gravityEffect[0])/objMultiplySize
        newY = (originalVelocity[1]+gravityEffect[1])/objMultiplySize
        newZ = (originalVelocity[2]+gravityEffect[2])/objMultiplySize
        newVelocity = [newX,newY,newZ]
        moveAmounts.append( newVelocity )



    #-----------this whole bit needs rewriting--------

    py.currentTime( originalTime + 1, edit = True, update = True)
    for j in range(len(moveAmounts)):

        #collision detection
        allObjects = selectAllOtherObjects(objSel[j], objSel)
        originalRadius = getRadius(objSel[j],objMultiplySize)

        for i in range (0, len(allObjects) ):
            objRadius = getRadius(allObjects[i],objMultiplySize)
            objDistance = getDistance(allObjects[i],objSel[j],objMultiplySize)
            if objDistance[0] < objRadius + originalRadius:
                force1 = moveAmounts[j][0]*objMultiplySize * objRadius
                print "Crashed"
                crashed = True

        if crashed != True:

            #move object
            py.move( objSel[j], float(moveAmounts[j][0]), float(moveAmounts[j][1]), float(moveAmounts[j][2]), relative = True )
            py.setKeyframe( objSel[j], attribute='translateX')
            py.setKeyframe( objSel[j], attribute='translateY')
            py.setKeyframe( objSel[j], attribute='translateZ')

        else:

            #dunno what to do here
            for i in range (0, len(allObjects) ):
                mass1 = getVolume(allObjects[i],objMultiplySize)
                velocity1 = getVelocity(allObjects[i],originalTime,objMultiplySize)
                mass2 = getVolume(objSel[j],objMultiplySize)
                velocity2 = getVelocity(objSel[j],originalTime,objMultiplySize)
                m1v1m2v2X = mass1*velocity1[0] + mass2*velocity2[0]
                m1v1m2v2Y = mass1*velocity1[1] + mass2*velocity2[1]
                m1v1m2v2Z = mass1*velocity1[2] + mass2*velocity2[2]
                totalMass = mass1+mass2
4

3 に答える 3

2

http://en.wikipedia.org/wiki/Elastic_collision を参照:

for i in range (0, len(allObjects) ):
                mass1 = getVolume(allObjects[i],objMultiplySize)
                velocity1 = getVelocity(allObjects[i],originalTime,objMultiplySize)
                mass2 = getVolume(objSel[j],objMultiplySize)
                velocity2 = getVelocity(objSel[j],originalTime,objMultiplySize)

                v1new = velocity1; //just initialization
                v2new = velocity2; //just initialization
                v1new[0] = (velocity1[0] *( mass1-mass2) + 2*mass2*velocity2[0])/(mass1 + mass2);
                v2new[0] = (velocity2[0] *( mass2-mass1) + 2*mass1*velocity1[0])/(mass1 + mass2);
                v1new[1] = (velocity1[1] *( mass1-mass2) + 2*mass2*velocity2[1])/(mass1 + mass2);
                v2new[1] = (velocity2[1] *( mass2-mass1) + 2*mass1*velocity1[1])/(mass1 + mass2);
                v1new[2] = (velocity1[2] *( mass1-mass2) + 2*mass2*velocity2[2])/(mass1 + mass2);
                v2new[2] = (velocity2[2] *( mass2-mass1) + 2*mass1*velocity1[2])/(mass1 + mass2);

弾性衝突を想定すると、各次元の衝突計算を個別に行うことができます。

于 2013-07-11T12:53:54.630 に答える
1

トーマスの衝突は優れた単純な弾性衝突方程式ですが、惑星体のスケールでは、弾性衝突のようなものはありません。というか、惑星自体が弾性的に衝突するわけではありません。惑星を大きな弾むボールであるかのように考える代わりに、より正確な類推は、惑星を大きな水滴であるかのように考えることです。完全に同一というわけではありませんが、水滴と惑星が衝突する際の相互作用には多くの類似点があります。

この種の結果を生成する数学の優れた簡単な図は、ここで見ることができます. そのシミュレーションは天体に固有のものではありませんが、「スクイーズ」衝突の背後にある基本原則は引き続き適用されます。

また、さまざまなシミュレーション パラメーターを使用して自分用にバージョンを作成し、構造活動と火山を完備しましたが、普遍的な重力はありませんでした (ラグが大きすぎました - 私が持っているのは中心にある重力井戸だけです)。大きな月。必要に応じて、ここからダウンロードして調べたり遊んだりできます(マウスを使用して惑星のチャンクをつかんで投げることができます。g重力のオン/オフを切り替えることができます)。中心に形成される惑星を周回する「彗星」は巨大であることに注意してください。惑星が地球の大きさだったら、それらの彗星は少なくともテキサス程度の大きさになるでしょう。

私がリンクしたシミュレーションはどちらも Java で書かれていますが、同じ数学と物理学をどの言語でも適用できます。

于 2013-07-11T15:09:22.700 に答える
0

まず第一に、これは Python の問題というよりも数学の問題のように思えます。なぜなら、同じ理論的根拠がどの言語にも当てはまるからです。

第 2 に、すべてのオブジェクトが球状の場合、TRUE COLLISION を実際に検出する必要はありませんが、オブジェクトの中心間の距離がそれらの半径の合計よりも小さいかどうかを確認するだけです。この関数 (コードで定義されているのを見たことがありません) を使用して、この距離 (スペースがユークリッドの場合) をすばやく取得できます。

def get_distance(obj1, obj2):
    # euclidean distance in three dimensions:
    return ( (obj2.x-obj2.x)**2 + (obj2.y-obj2.y)**2 + (obj2.z-obj2.z)**2 ) ** 0.5

さて、私が理解したことから、あなたはオブジェクトをバウンスしたいと考えています。これには、定義により、オブジェクトが常に VELOCITY プロパティを持っている必要があります。これは、方向と大きさを持つベクトルです。オブジェクトの位置を更新するときは、その速度も更新する必要があります (ほとんどの場合、以前の位置から)。

最後に、跳ねるときは、オブジェクトの位置、その速度ベクトル、および衝突している他のオブジェクトの中心を指す正規化されたベクトルを考慮する必要があります。次に、いくつかのベクトル演算を実行して、新しい速度ベクトルを取得します。

(更新):オブジェクトの質量が異なり、現実的な跳ね返りが必要な場合は、トーマスの回答で弾性衝突の概念を使用してください!

したがって、さらなる調査の「方向性」として、次のことをお勧めします。

  • いくつかの基本的なベクトル演算、特に内積と外積を学びます (「理解」した後は、それができてよかったと思うでしょう)。
  • ベクトルとベクトル操作を非常に便利な方法で実装する Numpy を強く使用することを検討してください。これにより、多くのことを実装する必要がなくなり、手動で行うよりも非常に高速になります。すべてを学ぶ必要はありません。問題を解決するのに十分なだけ学びましょう。

お役に立てれば!

于 2013-07-11T12:59:44.537 に答える