web-dev-qa-db-ja.com

3Dアニメーションで表示される円の数を一定に保つ

2Dコンピュータ画面に投影された偽の3D空間でランダムに動く白い円の透視投影を使用した3Dアニメーションを作成しました(GIF 1)。

enter image description here

同じ数の可視円を保持する必要があるため、円がフレームから消えるたびに、フレーム内に新しい可視円を作成する必要があります。そのために、次のコードを書きました。

  • 最初に、初期座標と2つの移動角度(球座標)を作成しました。

    for circle in circles:
    
        circle.position.xy = np.random.uniform(-25, 25, size=2)
        z = np.random.uniform(near_z, far_z)
    
        circle.position.z = z
        circle.position.x *= z/-50
        circle.position.y *= z/-50
    
        circle.theta_deg = np.random.Rand(1) * 360
        circle.phi_deg = np.random.Rand(1) * 360
    
        theta_rad = circle.theta_deg * np.pi / 180
        phi_rad = circle.phi_deg* np.pi / 180
    
    
        circle.dx = speed * np.sin(-phi_rad - theta_rad) / frameRate
        circle.dy = -speed * np.cos(phi_rad + theta_rad) / frameRate
        circle.dz = -speed * np.cos(theta_rad) / frameRate
    
    • 次に、アニメーションを再生し、各円の位置を更新するループで、同じ種類の問題に対して提供された同じ回答 here に従ってこの条件を設定しました。

      max_dist = max(abs(circle.position.x),abs(circle.position.y))
      limit_dist = 25 * abs((circle.position.z-near_z) / far_z)
      
      z_rel = np.random.uniform(near_z,far_z)
      
      if max_dist > limit_dist: 
          circle.position.x = np.random.uniform(-25, 25) * z_rel/far_z
          circle.position.y = np.random.uniform(-25, 25) * z_rel/far_z
      

GIF 2に示すように奇妙な結果が出ました

enter image description here

私の状態の何が問題になっていますか?また、どのようにしてフレームから消える円を検出し、フレーム内にそれを再作成できますか?

@Fabian N.(以下の回答)の提案に従って、次のようにx座標とy座標とともにz座標をリセットしました。

    max_dist   = max(abs(circle.position.x), abs(circle.position.y))        # Find maximum distance of a circle to the center of the view:
    limit_dist = 25 * abs((circle.position.z-near_z) / far_z)


    if circle.position.z <= near_z or max_dist > limit_dist:

        z_rel = np.random.uniform(near_z,far_z) 
        circle.position.z = z_rel + near_z

        circle.position.x = np.random.uniform(-25, 25) * z_rel/far_z
        circle.position.y = np.random.uniform(-25, 25) * z_rel/far_z

そして私はこの結果を得ました: enter image description here

9
Kathia

あなたが投稿したコードに基づいて、私は実際にそれを実行せずに2つの興味のあるポイントしか見ることができません
(投稿したコードの周りにいくつかのグルーコードを追加して、スタンドアロンの例として実行可能にすることができますか?)

  1. If条件でx位置とy位置をリセットするだけで、zもリセットする必要があります。そうしないと、カメラの後ろに飛ぶか、距離が離れます。
  2. リンクした質問のif条件には別の部分があります:sphere.position.z >= camera_zは、コードをcircle.position.z <= near_zに変換して、カメラの後ろを飛んでいる球を実際に検出します

どちらも、2番目のgifで何が起こっているのかを実際に説明することはできません...


考え直してください:gif 2のジャンプする円は、Z座標が同じままなので適切にリセットされないため、各フレームを即座にリセットする円である可能性があります。

1
Fabian N.

追加したコードでは、初期化した方法とは異なる方法でzパラメーターをリセットしています。

コードの最初の部分では、

z = np.random.uniform(near_z, far_z)
circle.position.z = z
circle.position.x *= z/-50
circle.position.y *= z/-50

forループで使用している間

z_rel = np.random.uniform(near_z,far_z)
circle.position.z = z_rel + near_z
circle.position.x = np.random.uniform(-25, 25) * z_rel/far_z
circle.position.y = np.random.uniform(-25, 25) * z_rel/far_z

これらは同等ではないようです。おそらく両方に同じパラメータを使用する必要があります。

また、x位置とy位置を更新する方法、特にパラメータdxとdyが大きくなりすぎて、円が画面からすぐに飛び出す可能性があるため、これらの位置を更新する方法も確認する必要があります。

0
Achille Huet