using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
///
/// 贝塞尔算法
///
public class UnitAlgorithmBezier : UnitAlgorithm {
/// 贝塞尔算法
public UnitAlgorithmBezier() { }
public void Compute(DataPlate data) {
List points = new List();
for (int i = 0; i < data.plateSides.Count; i++) {
Compute(data.plateSides[i]);
//points.AddRange(data.plateSides[i].positions);
}
//去除重复边缘点
points = points.Distinct().ToList();
//data.edgePoints = points;
}
public void Compute(DataPlateSide data) {
DataBezier dataBezier = new DataBezier();
dataBezier.bezier = data.bezier;
//dataBezier.smooth = data.plate.smooth;
dataBezier.aPoint = data.aPoint.position;
dataBezier.bPoint = data.bPoint.position;
dataBezier.aBezier = data.aBezier;
dataBezier.bBezier = data.bBezier;
dataBezier.Compute();
//data.length = dataBezier.length;
//data.positions = dataBezier.positions.ToArray();
//data.lines = dataBezier.lines.ToArray();
}
public class DataBezier {
//输入
public float smooth;
public Bezier bezier;
public Vector3 aPoint;
public Vector3 bPoint;
public Vector3 aBezier;
public Vector3 bBezier;
//输出
public float length;
public List positions = new List();
public List lines = new List();
/// 计算曲线细分点
public void Compute() {
//细分点
if (bezier == Bezier.一阶) { positions = new List { aPoint, bPoint }; }
if (bezier == Bezier.二阶) { positions = Compute(aPoint, aBezier, bPoint); }
if (bezier == Bezier.三阶) { positions = Compute(aPoint, aBezier, bBezier, bPoint); }
//线段
lines = new List();
for (int i = 0; i < positions.Count - 1; i++) {
DataPlateLine line = new DataPlateLine();
line.a = positions.LoopIndex(i + 0);
line.b = positions.LoopIndex(i + 1);
line.origin = length;
lines.Add(line);
length += line.Distance;
}
}
/// 二阶贝塞尔线段
private List Compute(Vector3 a, Vector3 b, Vector3 c) {
List points = new List();
//方向,距离
float distance = Vector2.Distance(c, a);
//求余,得商数
int quotient = Quotient(distance, smooth);
//贝塞尔曲线点
for (int i = 0; i < quotient; i++) {
float t = i * (distance / quotient) / distance;
Vector2 position = ComputeBezier(a, b, c, t);
points.Add(position);
}
points.Add(c);
return points;
}
/// 三阶贝塞尔线段
private List Compute(Vector3 a, Vector3 b, Vector3 c, Vector3 d) {
List points = new List();
//方向,距离
Vector2 direction = (d - a).normalized;
float distance = Vector2.Distance(d, a);
//求余,得商数
int quotient = Quotient(distance, smooth);
//贝塞尔曲线点
for (int i = 0; i < quotient; i++) {
float t = i * (distance / quotient) / distance;
Vector2 position = ComputeBezier(a, b, c, d, t);
points.Add(position);
}
points.Add(d);
return points;
}
}
/// 商数
public static int Quotient(float distance, float smooth) {
int a = (int)(distance * 1000);
int b = (int)(smooth * 1000);
return Math.DivRem(a, b, out int remainder);
}
///
/// 一阶贝塞尔算法
///
/// 起点
/// 终点
/// 进度
///
public static Vector3 ComputeBezier(Vector3 a, Vector3 b, float t) {
return a + (b - a) * t;
}
///
/// 二阶贝塞尔算法
///
/// 起点
/// 贝塞尔点
/// 终点
/// 进度
/// 当前进度的曲线点
public static Vector3 ComputeBezier(Vector3 a, Vector3 b, Vector3 c, float t) {
Vector3 aa = a + (b - a) * t;
Vector3 bb = b + (c - b) * t;
return aa + (bb - aa) * t;
}
///
/// 三阶贝塞尔算法
///
/// 起点
/// 起点的贝塞尔点
/// 终点的贝塞尔点
/// 终点
/// 进度
/// 当前进度的曲线点
public static Vector3 ComputeBezier(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float t) {
Vector3 aa = a + (b - a) * t;
Vector3 bb = b + (c - b) * t;
Vector3 cc = c + (d - c) * t;
Vector3 aaa = aa + (bb - aa) * t;
Vector3 bbb = bb + (cc - bb) * t;
return aaa + (bbb - aaa) * t;
}
}