using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;namespace ViVi.UIExtensions{ public static class PolygonHelper { public static void AddUIVertexTriangles(this VertexHelper vh,UIVertex[] verts) { for (int i = 0; i < verts.Length; i += 3) { int currentVertCount = vh.currentVertCount; for (int index = i; index < i+3; index++) { vh.AddVert(verts[index].position, verts[index].color, verts[index].uv0, verts[index].uv1, verts[index].normal, verts[index].tangent); } vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); } } public static void AddUIVertexTriangle(this VertexHelper vh,UIVertex[] verts) { int currentVertCount = vh.currentVertCount; for (int index = 0; index < 3; ++index) vh.AddVert(verts[index].position, verts[index].color, verts[index].uv0, verts[index].uv1, verts[index].normal, verts[index].tangent); vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); } private static void vertex(this List<UIVertex> vertices,float x, float y , Color color) { UIVertex v = UIVertex.simpleVert; v.color = color; v.position = new Vector2(x,y); v.uv0 = Vector2.zero; } //画圆形 public static void circle (this VertexHelper vh, Vector2 pos, float radius,Color color,bool filled = false) { circle(vh,pos.x, pos.y, radius, Mathf.Max(1, (int)(6 * Mathf.Pow(radius,1/3f))),color,filled); } public static void circle (this VertexHelper vh, float x, float y, float radius,Color color,bool filled = false) { circle(vh,x, y, radius, Mathf.Max(1, (int)(6 * Mathf.Pow(radius,1/3f))),color,filled); } public static void circle (this VertexHelper vh, float x, float y, float radius, int segments ,Color color,bool filled = false) { if (segments > 0){ float angle = 2 * Mathf.PI / segments; float cos = Mathf.Cos(angle); float sin = Mathf.Sin(angle); float cx = radius, cy = 0; List<UIVertex> vs = new List<UIVertex>(); segments--; for (int i = 0; i < segments; i++) { vs.vertex(x, y, color); vs.vertex(x + cx, y + cy, color); float temp = cx; cx = cos * cx - sin * cy; cy = sin * temp + cos * cy; vs.vertex(x + cx, y + cy, color); } vs.vertex(x, y, color); vs.vertex(x + cx, y + cy, color); cx = radius; cy = 0; vs.vertex(x + cx, y + cy, color); vh.AddUIVertexTriangles(vs.ToArray()); } } public static void DrawBeziers(this VertexHelper vh,List<Vector2> points,float segment,float width) { List<BezierUtils> beziers = CreateBeziers(points); if (beziers != null) { for (int i = 0; i < beziers.Count; i++) { BezierUtils bezier = beziers[i]; DrawBezier(vh ,bezier,segment,width); } } } public static Vector2 nor (this Vector2 vec) { float len = vec.magnitude; if (len != 0) { vec.x /= len; vec.y /= len; } return vec; } public static Vector2 rotate90 (this Vector2 vec, int dir) { float x = vec.x; if (dir >= 0) { vec.x = -vec.y; vec.y = x; } else { vec.x = vec.y; vec.y = -x; } return vec; } public static Vector2 cpy (this Vector2 vec) { return new Vector2(vec.x,vec.y); } private static void DrawBezier(VertexHelper vh,BezierUtils bezier,float segment,float width) { List<Vector2> lpos = new List<Vector2>(); List<Vector2> rpos = new List<Vector2>(); for (int i = 0; i <= segment; i++) { Vector2 bezierPos = new Vector2(bezier.beze_x((float)i/(float)segment),bezier.beze_y((float)i/(float)segment)); Vector2 bezierSpeed = new Vector2(bezier.beze_speed_x((float)i/(float)segment),bezier.beze_speed_y((float)i/(float)segment)); Vector2 offseta = bezierSpeed.normalized.rotate90(1) * (0.5f * width); Vector2 offsetb = bezierSpeed.normalized.rotate90(-1) * (0.5f * width); lpos.Add(bezierPos.cpy() + offseta); rpos.Add(bezierPos.cpy() + offsetb); } for (int j = 0; j < segment; j++) { vh.AddUIVertexQuad(GetQuad(lpos[j], lpos[j+1], rpos[j+1], rpos[j])); } } private static UIVertex[] GetQuad (params Vector2[] vertPos) { UIVertex[] vs = new UIVertex[4]; Vector2[] uv = new Vector2[4]; uv[0] = new Vector2(0, 0); uv[1] = new Vector2(0, 1); uv[2] = new Vector2(1, 0); uv[3] = new Vector2(1, 1); for (int i = 0; i < 4; i++) { UIVertex v = UIVertex.simpleVert; v.color = Color.blue; v.position = vertPos[i]; v.uv0 = uv[i]; vs[i] = v; } return vs; } private static List<BezierUtils> CreateBeziers(List<Vector2> points) { float scale = 0.6f; List<BezierUtils> beziers = new List<BezierUtils>(); int originCount = points.Count - 1; List<Vector2> midpoints = new List<Vector2>(); for (int i = 0; i < originCount; i++) { midpoints.Add(new Vector2( Mathf.Lerp(points[i].x,points[i+1].x,0.5f), Mathf.Lerp(points[i].y,points[i+1].y,0.5f)) ); } List<Vector2> ctrlPoints = new List<Vector2>(); float offsetx; float offsety; ctrlPoints.Add(new Vector2( points[0].x, points[0].y )); for (int i = 0; i < originCount - 1; i++) { Vector2 orginPoint = points[i + 1]; offsetx = orginPoint.x - Mathf.Lerp(midpoints[i].x, midpoints[i + 1].x, 0.5f); offsety = orginPoint.y - Mathf.Lerp(midpoints[i].y, midpoints[i + 1].y, 0.5f); ctrlPoints.Add(new Vector2( midpoints[i].x + offsetx, midpoints[i].y + offsety )); ctrlPoints.Add(new Vector2( midpoints[i+1].x + offsetx, midpoints[i+1].y + offsety )); ctrlPoints[i * 2 + 1] = Vector2.Lerp(orginPoint, ctrlPoints[i * 2 + 1], scale); ctrlPoints[i * 2 + 2] = Vector2.Lerp(orginPoint, ctrlPoints[i * 2 + 2], scale); } ctrlPoints.Add(new Vector2( points[points.Count - 1].x, points[points.Count - 1].y )); for (int i = 0; i < originCount; i++) { BezierUtils bezier = getBezier(points[i], ctrlPoints[i * 2], ctrlPoints[i * 2 + 1],points[i + 1]); beziers.Add(bezier); } return beziers; } public static BezierUtils getBezier(Vector2 p0,Vector2 p1 ,Vector2 p2,Vector2 p3){ return new BezierUtils( p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); } }}