2016-09-01 18 views
0

私のオブジェクトが従う滑らかな*とランダムなパスを描きたいので、私は2次ベジェ曲線を使うことにしました。2次ベジェ曲線によるランダムパスの描画

私のコードでは、オブジェクトはランダムで滑らかな方法で移動しています。

プレビュー:https://youtu.be/Eg9PEKuH4zA

私の質問は:どのように私は、方向の変化が滑らかにすることができますか?私はベジエのソリューションを完全に捨てるべきでしょうか、私が欲しいものを達成するためにコードを磨く方法がありますか?

*スムーズ==急激な方向は

私のコード変化しない:あなたは、いくつかの中間点でAからBに行くのカーブを持っている場合は、それに応じてCを選択する必要があります

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 

public class Lights : MonoBehaviour { 
    public float paintHeight = -90.0f; 
    public static int NUMBER_OF_LIGHTS = 3; 
    private static int BEZIER_PATH_POINTS = 100; 
    private float GOLDEN_COLOR_RATIO = 0.618033988749895f; 
    private Light[] lights = new Light[NUMBER_OF_LIGHTS]; 

    Vector3 RandomPoint() { 
     float obj_width = gameObject.GetComponent<RectTransform>().rect.width; 
     float screenX = Random.Range(-obj_width/2, obj_width/2); 

     float obj_height = gameObject.GetComponent<RectTransform>().rect.height; 
     float screenY = Random.Range(-obj_height/2, obj_height/2); 

     return new Vector3(screenX, screenY, -paintHeight); 
    } 


    Vector3 QuadraticBezierPoint(Vector3 startPoint, Vector3 endPoint, Vector3 vertexPoint, float t) { 
     /* 
     *   vertex 
     *  /╲ 
     *  / ╲ 
     * /p ╲ 
     * /. . ╲ 
     * /.  · ╲ 
     * /·   · ╲ 
     * start   · end 
     * 
     * 0 < t < 1 
     * 
     * B(t) = (1 - t)^2 * P0 + 2 * (1-t) * t * P1 + t^2 * P2 
     * 
     */ 
     return Mathf.Pow((1 - t), 2) * startPoint + 2 * (1 - t) * t * vertexPoint + Mathf.Pow(t, 2) * endPoint; 
    } 

    Color RandomColor() { 
     float h = Random.Range(0.0f, 1.0f) + GOLDEN_COLOR_RATIO; 
     h %= 1; 
     return Color.HSVToRGB(h, 0.99f, 0.99f); 
    } 

    void Start() { 
     for (int i = 0; i < NUMBER_OF_LIGHTS; i++) { 
      GameObject light_obj = new GameObject(); 
      Light light = light_obj.AddComponent<Light>(); 
      light.type = LightType.Point; 
      light.range = 10.0f; 
      light.intensity = 3.5f; 
      light.renderMode = LightRenderMode.ForcePixel; 
      light.name = "Light" + i; 
      light.transform.parent = gameObject.transform; 
      lights[i] = light; 
     } 

     StartCoroutine("Move"); 
    } 

    IEnumerator Move() { 
     Dictionary<string, Vector3>[] light_points = new Dictionary<string, Vector3>[NUMBER_OF_LIGHTS]; 
     Dictionary<string, Color>[] light_colors = new Dictionary<string, Color>[NUMBER_OF_LIGHTS]; 
     for (int i = 0; i < NUMBER_OF_LIGHTS; i++) { 
      light_points[i] = new Dictionary<string, Vector3>(); 
      light_colors[i] = new Dictionary<string, Color>(); 
      //light_points[i]["startPoint"] = RandomPoint(); 
      //light_points[i]["vertexPoint"] = RandomPoint(); 
      light_points[i]["endPoint"] = RandomPoint(); 
      light_colors[i]["nextColor"] = RandomColor(); 
     } 

     while(true) { 
      for (int i = 0; i < NUMBER_OF_LIGHTS; i++) { 
       light_points[i]["startPoint"] = light_points[i]["endPoint"]; 
       light_points[i]["vertexPoint"] = RandomPoint(); 
       light_points[i]["endPoint"] = RandomPoint(); 

       light_colors[i]["currentColor"] = light_colors[i]["nextColor"]; 
       light_colors[i]["nextColor"] = RandomColor(); 
      } 

      for (int i = 0; i < BEZIER_PATH_POINTS; i++) { 
       float percent = (float)i/BEZIER_PATH_POINTS; 
       for (int j = 0; j < NUMBER_OF_LIGHTS; j++) { 
        lights[j].transform.localPosition = QuadraticBezierPoint(
         light_points[j]["startPoint"], 
         light_points[j]["endPoint"], 
         light_points[j]["vertexPoint"], 
         percent 
        ); 
        lights[j].color = Color.Lerp(light_colors[j]["currentColor"], light_colors[j]["nextColor"], percent); 
       } 
       yield return new WaitForSeconds(0.02f); 
      } 
     } 
    } 
} 
+0

あなたのビデオは本当に助けにならない、散漫な光が混乱する背景に動いて、どのパスがトレースされているのかわからない。実際の問題を記述することから始めます。単一の曲線は滑らかです。したがって、ある曲線から次の曲線へ行くことは滑らかではないという問題がありますか?そうであれば、ソリューションはG1またはG2の連続性を保証します。これは、より高次のカーブがより良いカーブのようになります。そして、その時点でCatmul-Romカーブを使用することは、あなたが定義したポイントを通過するので(カーブ上の各セクションがベジエのフォームに変わる) –

答えて

1

をBにおける角度(A、B、C)が小さすぎたり大きすぎたりしないようにする。

また、適切な方法で中間点を選択する必要があります。 https://www.particleincell.com/2012/bezier-splines/であり、方向の変化がそれほど大きくないようにする。

0

あなたはNURBSや他のスプラインを使用することができますが、投稿したものに応じて滑らかなカーブを得るのは、もっと簡単で同等の方法でしょう。

作成している各曲線には、コード開始点、頂点、および終了点に3点があります。 S、V、Eと呼ぶことができます。さらに、時間をかけてそれらを見ることができるので、{S0,V0,E0}は最初のカーブを作成し、{S1,V1,E1}は2番目のカーブを作成します。

今のところ、S1=E0S2=E1などが表示されます。つまり、ライトがランダムにジャンプすることはありませんが、ベジェ曲線を切り替えるとモーションが急になる可能性があります。

動きがスムーズになるように、S1 = E0 = 0.5 * (V0+V1)を確認してください。つまり実際には、S0とV0をランダムに生成するということです。次に、新しい曲線ごとに新しいVを生成し、古いVと新しいVの中間点を曲線ブレークポイントにします。

これは等級2のBスプラインを持つことに相当します。

ここにいくつかのコード例を示します。

// initialize with randomness 
// we need a previous v and a current v for the first iteration 
// So, the first start point will be halfway between these two points 
prev_v = random_point() 
v = random_point() 

while(true) 
{ 
    next_v = random_point() 
    s = 0.5 * (prev_v + v) // s is halfway between prev_v and v 
    e = 0.5 * (v + next_v) // e is halfway between v and next_v 
    yield_movement_bezier(s, v, e) 

    // prep for next iteration 
    prev_v = v 
    v = next_v 
} 
+0

私はそれがうまくいくとは思わない。 https://ibin.co/31dRdvQTxJDw.jpg – alexandernst

+0

したがって、ダイアグラムでは、E0はV0とV1の中点にある必要があります。このアプローチでは、E値をランダムに生成せず、V値だけをランダムに生成します。私は明確にしようとするいくつかの擬似コードを追加します。 – tfinniga

関連する問題