欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

UGUI如何繪制多點連續(xù)的平滑曲線

小編給大家分享一下UGUI如何繪制多點連續(xù)的平滑曲線,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

成都創(chuàng)新互聯(lián)公司服務項目包括南縣網(wǎng)站建設(shè)、南縣網(wǎng)站制作、南縣網(wǎng)頁制作以及南縣網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,南縣網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到南縣省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!

具體內(nèi)容如下

繪制

實現(xiàn)自定義的MaskableGraphic掛載在UGUI的UI節(jié)點上

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

  }
}

看完了這篇文章,相信你對“UGUI如何繪制多點連續(xù)的平滑曲線”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)站欄目:UGUI如何繪制多點連續(xù)的平滑曲線
轉(zhuǎn)載注明:http://chinadenli.net/article18/gspogp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務器響應式網(wǎng)站動態(tài)網(wǎng)站定制開發(fā)面包屑導航微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司