using System.Collections; using System.Collections.Generic; using UnityEngine; namespace YKMoon.Math { public partial class YKMath { public static Vector2 GetVector2IgnoreYAxis(Vector2 v) { v.y = 0; return v; } public static Vector2 GetDeltaIgnoreZAxis(Vector3 from, Vector3 to) { return new Vector2((to - from).x, (to - from).y); } public static Vector2 GetDisIgnoreZAxis(Vector3 posA, Vector3 posB) { return new Vector2(Mathf.Abs((posA - posB).x), Mathf.Abs((posA - posB).y)); } /// /// 三点确认抛物线, 获得抛物线内的percent%的点 /// /// 起点 /// 终点 /// 轨迹内任意点 /// 最高点 /// 百分比 /// public static Vector2 GetParabolaPos(Vector2 P1, Vector2 P2, Vector2 P3, out Vector2 maxHeightPos, float percent) { float a, b, c; CalculateABC(P1, P2, P3, out a, out b, out c); float x = Mathf.Lerp(P1.x, P2.x, percent); float y = a * x * x + b * x + c; Vector2 position = new Vector2(x, y); maxHeightPos.x = -b / (2 * a); maxHeightPos.y = c - b * b / (4 * a); return position; } /// /// 三点确认抛物线, 获得抛物线内的percent%的点,只计算XY平面投影 /// /// /// /// /// /// /// public static Vector3 GetParabolaPos3DXY(Vector3 P1, Vector3 P2, Vector3 P3, out Vector3 maxHeightPos, float percent) { //先计算2D投影 float a, b, c; CalculateABC(P1, P2, P3, out a, out b, out c); float x = Mathf.Lerp(P1.x, P2.x, percent); float y = a * x * x + b * x + c; float z = Mathf.Lerp(P1.z, P2.z, percent); Vector3 position = new Vector3(x, y, z); maxHeightPos.x = -b / (2 * a); maxHeightPos.y = c - b * b / (4 * a); maxHeightPos.z = Mathf.Lerp(P1.z, P2.z, (maxHeightPos.x - P1.x) / (P2.x - P1.x)); return position; } /// /// 三点确认抛物线,获得抛物线的二次方程abc参数, ax^2+bx+c=0 /// private static void CalculateABC(Vector2 P1, Vector2 P2, Vector2 P3, out float a, out float b, out float c) { float x1 = P1.x; float y1 = P1.y; float x2 = P3.x; float y2 = P3.y; float x3 = P2.x; float y3 = P2.y; a = (y1 * x2) + (x1 * y3) + (y2 * x3) - (y3 * x2) - (x3 * y1) - (y2 * x1); a /= x1 * x1 * x2 + x3 * x3 * x1 + x3 * x2 * x2 - x3 * x3 * x2 - x3 * x1 * x1 - x2 * x2 * x1; b = x1 * x1 * y2 + y1 * x3 * x3 + x2 * x2 * y3 - x3 * x3 * y2 - x1 * x1 * y3 - x2 * x2 * y1; b /= x1 * x1 * x2 + x3 * x3 * x1 + x3 * x2 * x2 - x3 * x3 * x2 - x3 * x1 * x1 - x2 * x2 * x1; c = (x1 * x1 * x2 * y3) + (x1 * y2 * x3 * x3) + (y1 * x3 * x2 * x2) - (x3 * x3 * x2 * y1) - (x3 * y2 * x1 * x1) - (y3 * x1 * x2 * x2); c /= x1 * x1 * x2 + x3 * x3 * x1 + x3 * x2 * x2 - x3 * x3 * x2 - x3 * x1 * x1 - x2 * x2 * x1; } /// /// 在圆内均匀分布点。 /// /// 圆的半径,要生成点在该半径的圆内 /// 要生成点的数量 /// public static List RandomPointInCircle(float radius, int count, float minDisBetweenPos) { List result = new List(); /*float r;//公式的r系数 float theta;//公式的角度系数 float x; float y; float randomValue;//0-1的随机值 System.Random random = new System.Random(); for(int i = 0; i < count; i++) { // Tip 此处要注意! r和theta的生成要分别生成随机数,公式概念中明确说明,r和theta要互不相干 randomValue = (float)random.NextDouble(); r = math.sqrt(randomValue) * radius; randomValue = (float)random.NextDouble(); theta = 2 * math.PI * randomValue; //生成x,y坐标, x = (float)r * math.cos(theta); y = (float)r * math.sin(theta); result.Add(new Vector2(x, y));//* 0.5; 若要变成椭圆,将X和Y结果值乘上你想要的比例系数即可 }*/ while(result.Count < count) { var pos = UnityEngine.Random.insideUnitCircle * radius; bool isMatch = true; for(int i = 0; i < result.Count; i++) { if(Vector3.Distance(result[i], pos) < minDisBetweenPos) { isMatch = false; break; } } if(isMatch) { result.Add(pos); } else { break; } } while(result.Count < count) { var pos = UnityEngine.Random.insideUnitCircle * radius; result.Add(pos); } return result; } /// /// 生成随机点均匀分布在圆内 /// /// 半径 /// 点个数 /// public static List RandomPointsInCircleUniformly(float radius, int count) { List result = new List(); System.Random random = new System.Random(); for(int i=0; i /// 简谐运动cos版 /// /// 时间点 /// 振幅 /// 频率 = 1/一个周期时长 /// 初相位,单位为弧度 /// if true use cos else sin. /// 位移 public static float SimpleHarmonicMotion(float time, float frequency, float Amplitude = 0.5f, float phi = 0, bool isCos = true) { //位移时间方程 x = Acos(ωt + φ) //圆频率ω = 2πf //频率f //相位φ //振幅A float omega = 2 * Mathf.PI * frequency; if(isCos) { return Amplitude * Mathf.Cos(omega * time + phi); } else { return Amplitude * Mathf.Sin(omega * time + phi); } } } }