Files
Studio/Assets/Scripts/Studio/Machine/AGV/BezierCurve.cs

99 lines
3.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace Studio
{
public class BezierCurve : MonoBehaviour
{
public static Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t)
{
float u = 1 - t;
float tt = t * t;
float uu = u * u;
Vector3 p = uu * p0; // (1-t)^2 * p0
p += 2 * u * t * p1; // 2 * (1-t) * t * p1
p += tt * p2; // t^2 * p2
return p;
}
/* not Use
//세 점의 외심을 구하는 함수
public static Vector3 CalculateCircumcenter(Vector3 A, Vector3 B, Vector3 C)
{
// 각 점의 좌표
float x1 = A.x, y1 = A.z;
float x2 = B.x, y2 = B.z;
float x3 = C.x, y3 = C.z;
// 외심의 x좌표 계산
float D = 2 * (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2));
float Ux = ((x1 * x1 + y1 * y1) * (y2 - y3) + (x2 * x2 + y2 * y2) * (y3 - y1) + (x3 * x3 + y3 * y3) * (y1 - y2)) / D;
// 외심의 y좌표 계산
float Uy = ((x1 * x1 + y1 * y1) * (x3 - x2) + (x2 * x2 + y2 * y2) * (x1 - x3) + (x3 * x3 + y3 * y3) * (x2 - x1)) / D;
return new Vector3(Ux, 0f, Uy);
}
//외심점을 바탕으로 두 점 사이의 각도를 구하는 함수
public static float CalculateAngleBetweenPoints(Vector3 center, Vector3 pointA, Vector3 pointB)
{
Vector3 vectorA = pointA - center;
Vector3 vectorB = pointB - center;
float dotProduct = Vector3.Dot(vectorA.normalized, vectorB.normalized);
float angle = Mathf.Acos(dotProduct) * Mathf.Rad2Deg;
return angle;
}
*/
public static float GetTValueByDistance(float distance,List<float> arcLengths)
{
for (int i = 0; i < arcLengths.Count - 1; i++)
{
if (arcLengths[i] >= distance)
return (float)i / (arcLengths.Count - 1);
}
return 1.0f;
}
public static List<float> PrecomputeArcLengths(Vector3 p0, Vector3 p1, Vector3 p2, int segments=10000)
{
List<float> arcLengths = new List<float>();
float totalLength = 0.0f;
Vector3 previousPoint = p0;
arcLengths.Add(0.0f);
for (int i = 1; i <= segments; i++)
{
float t = i / (float)segments;
Vector3 currentPoint = GetPoint(p0,p1,p2,t);
totalLength += Vector3.Distance(previousPoint, currentPoint);
arcLengths.Add(totalLength);
previousPoint = currentPoint;
}
return arcLengths;
}
public static float ApproximateLength(Vector3 p0, Vector3 p1, Vector3 p2, int segments=10000)
{
float totalLength = 0.0f;
Vector3 previousPoint = p0;
Vector3 currentPoint;
for (int i = 1; i <= segments; i++)
{
float t = i / (float)segments;
currentPoint = GetPoint(p0, p1, p2, t);
totalLength += Vector3.Distance(previousPoint, currentPoint);
previousPoint = currentPoint;
}
return totalLength;
}
}
}