a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

UGUI繪制多點連續的平滑曲線

2019-10-29 19:41:04
字體:
來源:轉載
供稿:網友

本文實例為大家分享了UGUI繪制平滑曲線的具體代碼,供大家參考,具體內容如下

繪制

實現自定義的MaskableGraphic掛載在UGUI的UI節點上

public class UGUIObjectRender : MaskableGraphic{  /**  * points 為需要穿過的點  * segments 為曲線細分度  * linewidth 為曲線粗細  */  protected override void OnPopulateMesh(VertexHelper vh)  {    vh.DrawBeziers(points,segments,linewidth);  }}

需要時用的工具類在后面

二次貝塞爾工具類

using UnityEngine;namespace ViVi.UIExtensions{/** * Created by vivi on 16/5/11. */  public class BezierUtils {    public float P0x;    public float P1x;    public float P2x;    public float P3x;    public float P0y;    public float P1y;    public float P2y;    public float P3y;    public BezierUtils(float p0x,float p0y,float p1x,float p1y,float p2x,float p2y,float p3x,float p3y) {      P0x = p0x;      P0y = p0y;      P1x = p1x;      P1y = p1y;      P2x = p2x;      P2y = p2y;      P3x = p3x;      P3y = p3y;    }    public BezierUtils(Vector2 p0,Vector2 p1,Vector2 p2,Vector2 p3) {      P0x = p0.x;      P0y = p0.y;      P1x = p1.x;      P1y = p1.y;      P2x = p2.x;      P2y = p2.y;      P3x = p3.x;      P3y = p3.y;    }    public float beze_x(float t){      float it = 1-t;      return it*it*it*P0x + 3*it*it*t*P1x + 3*it*t*t*P2x + t*t*t*P3x;    }    public float beze_y(float t){      float it = 1-t;      return it*it*it*P0y + 3*it*it*t*P1y + 3*it*t*t*P2y + t*t*t*P3y;    }    //-------------------------------------------------------------------------------------    public float beze_speed_x(float t)    {      float it = 1-t;      return -3*P0x*it*it + 3*P1x*it*it - 6*P1x*it*t + 6*P2x*it*t - 3*P2x*t*t + 3*P3x*t*t;    }    public float beze_speed_y(float t)    {      float it = 1-t;      return -3*P0y*it*it + 3*P1y*it*it - 6*P1y*it*t + 6*P2y*it*t - 3*P2y*t*t + 3*P3y*t*t;    }    private float beze_speed(float t)    {      float sx = beze_speed_x(t);      float sy = beze_speed_y(t);      return (float) Mathf.Sqrt(Mathf.Pow(sx,2)+Mathf.Pow(sy,2));    }    //-------------------------------------------------------------------------------------    private float beze_length(float t)    {      float LATESTCOUNT = 10000;      int steps = (int) Mathf.Ceil(LATESTCOUNT * t);      if (steps == 0)        return 0;      if (steps % 2 != 0)        steps++;      float halfSteps = steps * .5f;      float nSum = 0;      float n1Sum = 0;      float disStep = t / steps;      for (int i = 0; i < halfSteps; i++ ) {        n1Sum += beze_speed((2 * i + 1) * disStep);        nSum += beze_speed(2 * i * disStep);      }      return (beze_speed(0) + beze_speed(1) + 2 * n1Sum + 4 * nSum) * disStep / 3;    }    //-------------------------------------------------------------------------------------    private float beze_even(float t)    {      float len = t * beze_length(1);      float uc = 0;      do {        float ulen = beze_length(t);        float uspeed = beze_speed(t);        uc = t - (ulen - len) / uspeed;        if (Mathf.Abs(uc - t) < 0.0001)          break;        t = uc;      }while(true);      return uc;    }    private float totallength = -1;    public float getTotalLength(){      if(totallength<0)        totallength = beze_length(1);      return totallength;    }    public Vector2 getPosition(float t){      return new Vector2(beze_x(t),beze_y(t));    }  }}

UGUI 繪圖工具類

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);    }  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: xxxx午夜 | 欧美国产日韩另类 | 99精品欧美一区二区三区综合在线 | 精品视频一区二区三区 | 久久亚洲欧美日韩精品专区 | 国产欧美在线观看 | 99国产精品久久久 | 久久国产精品视频 | 男女午夜 | 中文字幕在线免费 | 最新高清无码专区 | 欧美一级在线免费观看 | 日韩欧美国产一区二区 | h亚洲视频 | 日本高清视频网站www | 奇米av| 精品国产一区二区三区久久影院 | 免费观看一级毛片 | 一区二区av | 亚洲国产精品99 | 日本视频一区二区 | 日韩在线播放一区 | 国产精品久久久久久网站 | 观看av| 一区不卡在线 | 天堂色网 | h视频免费| 九九av| 日韩欧美国产成人一区二区 | 久久久国产视频 | 成年人精品视频在线观看 | 日本视频黄 | 国产日韩视频在线播放 | 国产性色av | 中文字幕第80页 | 日韩免费高清视频 | 国产精品一区三区 | 欲色av| 密室大逃脱第六季大神版在线观看 | 天天干天天操 | 91精品久久久久久久久 |