Я хочу нарисовать гладкие * и случайные пути, по которым мои объекты будут следовать, и я решил пойти с квадратичными кривыми Безье (но я открыт для других идей).Рисунок случайных путей с квадратичными кривыми Безье
Мой код перемещает мои объекты в случайном, но негладком * пути.
Preview: https://youtu.be/Eg9PEKuH4zA
Мой вопрос: как я могу сделать изменения направления гладко? Должен ли я полностью отказаться от решения Безье или есть способ, которым я мог бы отполировать свой код, чтобы добиться того, чего хочу?
* гладкие == не крутая направление не меняется
Мой код:
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);
}
}
}
}
Ваше видео действительно не помогает, это рассеянное освещение, движущееся на отвлекающем фоне, что делает невозможным рассказать, какой путь отслеживается. Начните с описания фактической проблемы: одиночные кривые являются гладкими, и проблема, которая идет от одной кривой к следующей, не является гладкой? Если это так, то решение гарантирует G1 или даже непрерывность G2, для которых луч более высокого порядка лучше, как кубическая кривая. И в этот момент кривые Catmul-Rom имеют еще больший смысл, поскольку они проходят через определяемые вами точки (каждый раздел на кривой тривиально преобразуется в форму Безье) –