Files
XCharts/Runtime/XUGL/UGLHelper.cs

394 lines
13 KiB
C#
Raw Normal View History

2021-01-11 08:54:28 +08:00
using System.Collections.Generic;
using UnityEngine;
namespace XUGL
{
public static class UGLHelper
{
public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
{
2022-05-22 22:17:38 +08:00
return color1.a == color2.a &&
color1.b == color2.b &&
color1.g == color2.g &&
color1.r == color2.r;
2021-01-11 08:54:28 +08:00
}
public static bool IsValueEqualsColor(Color color1, Color color2)
{
2022-05-22 22:17:38 +08:00
return color1.a == color2.a &&
color1.b == color2.b &&
color1.g == color2.g &&
color1.r == color2.r;
2021-01-11 08:54:28 +08:00
}
public static bool IsValueEqualsString(string str1, string str2)
{
2021-11-28 20:31:41 +08:00
if (str1 == null && str2 == null)
return true;
else if (str1 != null && str2 != null)
return str1.Equals(str2);
2021-01-11 08:54:28 +08:00
else return false;
}
public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2)
{
2022-05-22 22:17:38 +08:00
return v1.x == v2.x &&
v1.y == v2.y;
2021-01-11 08:54:28 +08:00
}
public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2)
{
2022-05-22 22:17:38 +08:00
return v1.x == v2.x &&
v1.y == v2.y &&
v1.z == v2.z;
2021-01-11 08:54:28 +08:00
}
2022-03-09 07:26:15 +08:00
public static bool IsValueEqualsVector3(Vector3 v1, Vector2 v2)
{
2022-05-22 22:17:38 +08:00
return v1.x == v2.x &&
v1.y == v2.y;
2022-03-09 07:26:15 +08:00
}
2021-01-11 08:54:28 +08:00
public static bool IsValueEqualsList<T>(List<T> list1, List<T> list2)
{
2021-11-28 20:31:41 +08:00
if (list1 == null || list2 == null)
return false;
if (list1.Count != list2.Count)
return false;
2021-01-11 08:54:28 +08:00
for (int i = 0; i < list1.Count; i++)
{
2022-06-26 08:35:59 +08:00
if (list1[i] == null && list2[i] == null) { }
2021-01-11 08:54:28 +08:00
else
{
if (list1[i] != null)
{
2021-11-28 20:31:41 +08:00
if (!list1[i].Equals(list2[i]))
return false;
2021-01-11 08:54:28 +08:00
}
else
{
2021-11-28 20:31:41 +08:00
if (!list2[i].Equals(list1[i]))
return false;
2021-01-11 08:54:28 +08:00
}
}
}
return true;
}
public static bool IsClearColor(Color32 color)
{
2022-05-22 22:17:38 +08:00
return color.a == 0 &&
color.b == 0 &&
color.g == 0 &&
color.r == 0;
2021-01-11 08:54:28 +08:00
}
public static bool IsClearColor(Color color)
{
2022-05-22 22:17:38 +08:00
return color.a == 0 &&
color.b == 0 &&
color.g == 0 &&
color.r == 0;
2021-01-11 08:54:28 +08:00
}
public static bool IsZeroVector(Vector3 pos)
{
2022-05-22 22:17:38 +08:00
return pos.x == 0 &&
pos.y == 0 &&
pos.z == 0;
2021-01-11 08:54:28 +08:00
}
public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
{
Vector3 point = Quaternion.AngleAxis(angle, axis) * (position - center);
Vector3 resultVec3 = center + point;
return resultVec3;
}
public static void GetBezierList(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
2022-08-15 07:30:56 +08:00
Vector3 lsp, Vector3 nep, float smoothness = 2f, float k = 2.0f, bool limit = false, bool randomDire = false)
2021-01-11 08:54:28 +08:00
{
Vector3 cp1, cp2;
2022-08-15 07:30:56 +08:00
var dist = Vector3.Distance(sp, ep);
2021-01-11 08:54:28 +08:00
var dir = (ep - sp).normalized;
2022-08-15 07:30:56 +08:00
var diff = (randomDire ? dist : Mathf.Abs(sp.x - ep.x)) / k;
2021-01-11 08:54:28 +08:00
if (lsp == sp)
{
2022-07-17 20:57:38 +08:00
cp1 = sp + (nep - ep).normalized * diff;
2022-08-15 07:30:56 +08:00
if (limit) cp1.y = sp.y;
2021-01-11 08:54:28 +08:00
}
else
{
cp1 = sp + (ep - lsp).normalized * diff;
2022-08-15 07:30:56 +08:00
if (limit) cp1.y = sp.y;
2022-06-26 08:35:59 +08:00
}
if (nep == ep)
{
cp2 = ep;
}
else
{
cp2 = ep - (nep - sp).normalized * diff;
2022-08-15 07:30:56 +08:00
if (limit) cp2.y = ep.y;
2021-01-11 08:54:28 +08:00
}
2022-05-22 22:17:38 +08:00
int segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness));
if (segment < 1) segment = (int) (dist / 0.5f);
2021-01-11 08:54:28 +08:00
if (segment < 4) segment = 4;
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
2021-11-28 20:31:41 +08:00
if (posList.Count < 2)
{
posList.Clear();
posList.Add(sp);
posList.Add(ep);
}
2021-01-11 08:54:28 +08:00
}
public static void GetBezierListVertical(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
float smoothness = 2f, float k = 2.0f)
{
Vector3 dir = (ep - sp).normalized;
float dist = Vector3.Distance(sp, ep);
Vector3 cp1 = sp + dist / k * dir * 1;
Vector3 cp2 = sp + dist / k * dir * (k - 1);
cp1.x = sp.x;
cp2.x = ep.x;
2022-05-22 22:17:38 +08:00
int segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness));
2021-01-11 08:54:28 +08:00
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
2021-11-28 20:31:41 +08:00
if (posList.Count < 2)
{
posList.Clear();
posList.Add(sp);
posList.Add(ep);
}
2021-01-11 08:54:28 +08:00
}
public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp)
{
List<Vector3> list = new List<Vector3>();
for (int i = 0; i < segment; i++)
{
2022-05-22 22:17:38 +08:00
list.Add(GetBezier(i / (float) segment, sp, cp, ep));
2021-01-11 08:54:28 +08:00
}
list.Add(ep);
return list;
}
2021-11-28 20:31:41 +08:00
public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
int segment, Vector3 cp, Vector3 cp2)
2021-01-11 08:54:28 +08:00
{
posList.Clear();
if (posList.Capacity < segment + 1)
{
posList.Capacity = segment + 1;
}
for (int i = 0; i < segment; i++)
{
2022-05-22 22:17:38 +08:00
posList.Add((GetBezier2(i / (float) segment, sp, cp, cp2, ep)));
2021-01-11 08:54:28 +08:00
}
posList.Add(ep);
}
public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep)
{
Vector3 aa = sp + (cp - sp) * t;
Vector3 bb = cp + (ep - cp) * t;
return aa + (bb - aa) * t;
}
public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep)
{
t = Mathf.Clamp01(t);
var oneMinusT = 1f - t;
return oneMinusT * oneMinusT * oneMinusT * sp +
3f * oneMinusT * oneMinusT * t * p1 +
3f * oneMinusT * t * t * p2 +
t * t * t * ep;
}
public static Vector3 GetDire(float angle, bool isDegree = false)
{
angle = isDegree ? angle * Mathf.Deg2Rad : angle;
return new Vector3(Mathf.Sin(angle), Mathf.Cos(angle));
}
public static Vector3 GetVertialDire(Vector3 dire)
{
if (dire.x == 0)
return new Vector3(-1, 0, 0);
2021-11-28 20:31:41 +08:00
2021-01-11 08:54:28 +08:00
if (dire.y == 0)
return new Vector3(0, -1, 0);
else
return new Vector3(-dire.y / dire.x, 1, 0).normalized;
}
/// <summary>
/// 获得0-360的角度12点钟方向为0度
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
public static float GetAngle360(Vector2 from, Vector2 to)
{
float angle;
Vector3 cross = Vector3.Cross(from, to);
angle = Vector2.Angle(from, to);
angle = cross.z > 0 ? -angle : angle;
angle = (angle + 360) % 360;
return angle;
}
public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
{
angle = isDegree ? angle * Mathf.Deg2Rad : angle;
2021-11-28 20:31:41 +08:00
return new Vector3(center.x + radius * Mathf.Sin(angle),
center.y + radius * Mathf.Cos(angle));
}
/// <summary>
/// 获得两直线的交点
/// </summary>
/// <param name="p1">线段1起点</param>
/// <param name="p2">线段1终点</param>
/// <param name="p3">线段2起点</param>
/// <param name="p4">线段2终点</param>
/// <param name="intersection">相交点。当不想交时默认为 Vector3.zero </param>
/// <returns>相交则返回 true, 否则返回 false</returns>
public static bool GetIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, ref Vector3 intersection)
{
intersection = Vector3.zero;
var d = (p2.x - p1.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p4.x - p3.x);
if (d == 0)
return false;
var u = ((p3.x - p1.x) * (p4.y - p3.y) - (p3.y - p1.y) * (p4.x - p3.x)) / d;
var v = ((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / d;
if (u < 0 || u > 1 || v < 0 || v > 1)
return false;
intersection.x = p1.x + u * (p2.x - p1.x);
intersection.y = p1.y + u * (p2.y - p1.y);
return true;
}
/// <summary>
/// 三个点画线段所需要的六个关键点
/// </summary>
/// <param name="lp">上一个点</param>
/// <param name="cp">当前点</param>
/// <param name="np">下一个点</param>
/// <param name="width">线段宽度</param>
/// <param name="ltp">上一个点的上角点</param>
/// <param name="lbp">上一个点的下角点</param>
/// <param name="ntp">下一个点的上角点</param>
/// <param name="nbp">下一个点的下角点</param>
/// <param name="itp">交汇点的上角点</param>
/// <param name="ibp">交汇点的下角点</param>
internal static void GetLinePoints(Vector3 lp, Vector3 cp, Vector3 np, float width,
ref Vector3 ltp, ref Vector3 lbp,
ref Vector3 ntp, ref Vector3 nbp,
2021-12-08 08:31:32 +08:00
ref Vector3 itp, ref Vector3 ibp,
ref Vector3 clp, ref Vector3 crp,
ref bool bitp, ref bool bibp, int debugIndex = 0)
2021-11-28 20:31:41 +08:00
{
var dir1 = (cp - lp).normalized;
2022-03-20 18:52:50 +08:00
var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * width;
ltp = lp - dir1v;
lbp = lp + dir1v;
if (debugIndex == 1 && cp == np)
{
ntp = np - dir1v;
nbp = np + dir1v;
clp = cp - dir1v;
crp = cp + dir1v;
return;
}
2021-11-28 20:31:41 +08:00
var dir2 = (cp - np).normalized;
var dir2v = Vector3.Cross(dir2, Vector3.back).normalized * width;
2022-03-20 18:52:50 +08:00
ntp = np - dir2v;
nbp = np + dir2v;
clp = cp - dir2v;
crp = cp + dir2v;
2021-11-28 20:31:41 +08:00
2022-04-09 21:30:28 +08:00
if (Vector3.Cross(dir1, dir2) == Vector3.zero && np != cp)
{
itp = ntp;
ibp = nbp;
return;
}
2021-12-08 08:31:32 +08:00
var ldist = (Vector3.Distance(cp, lp) + 1) * dir1;
var rdist = (Vector3.Distance(cp, np) + 1) * dir2;
bitp = true;
2021-11-28 20:31:41 +08:00
if (!UGLHelper.GetIntersection(ltp, ltp + ldist, ntp, ntp + rdist, ref itp))
{
2022-03-20 18:52:50 +08:00
itp = cp - dir1v;
clp = cp - dir1v;
crp = cp - dir2v;
2021-12-08 08:31:32 +08:00
bitp = false;
2021-11-28 20:31:41 +08:00
}
2021-12-08 08:31:32 +08:00
bibp = true;
2021-11-28 20:31:41 +08:00
if (!UGLHelper.GetIntersection(lbp, lbp + ldist, nbp, nbp + rdist, ref ibp))
{
2022-03-20 18:52:50 +08:00
ibp = cp + dir1v;
clp = cp + dir1v;
crp = cp + dir2v;
2021-12-08 08:31:32 +08:00
bibp = false;
2021-11-28 20:31:41 +08:00
}
2022-01-05 07:46:30 +08:00
if (bitp == false && bibp == false && cp == np)
{
2022-03-20 18:52:50 +08:00
ltp = cp - dir1v;
clp = cp + dir1v;
crp = cp + dir1v;
2022-01-05 07:46:30 +08:00
}
2021-01-11 08:54:28 +08:00
}
2022-04-12 08:09:18 +08:00
public static bool IsPointInTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 check)
{
var dire1 = check - p1;
var dire2 = check - p2;
var dire3 = check - p3;
var c1 = dire1.x * dire2.y - dire1.y * dire2.x;
var c2 = dire2.x * dire3.y - dire2.y * dire3.x;
var c3 = dire3.x * dire1.y - dire3.y * dire1.x;
return c1 * c2 >= 0 && c1 * c3 >= 0;
}
2022-05-04 08:45:19 +08:00
public static bool IsPointInPolygon(Vector3 p, List<Vector3> polyons)
{
if (polyons.Count == 0) return false;
var inside = false;
var j = polyons.Count - 1;
for (int i = 0; i < polyons.Count; j = i++)
{
var pi = polyons[i];
var pj = polyons[j];
if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) &&
(p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x))
inside = !inside;
}
return inside;
}
public static bool IsPointInPolygon(Vector3 p, List<Vector2> polyons)
{
if (polyons.Count == 0) return false;
var inside = false;
var j = polyons.Count - 1;
for (int i = 0; i < polyons.Count; j = i++)
{
var pi = polyons[i];
var pj = polyons[j];
if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) &&
(p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x))
inside = !inside;
}
return inside;
}
2021-01-11 08:54:28 +08:00
}
}