查看: 1911|回复: 2
打印 上一主题 下一主题

[经验分享] unity3d 图形吧 之 场景中画圆

[复制链接]

100

主题

3

听众

7683

积分

高级设计师

Rank: 6Rank: 6

纳金币
2378
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2015-2-7 22:52:17 |只看该作者 |倒序浏览

先看一下效果:

   

区别就是一个2d一个3d.

2d就不介绍了,相对简单一些,对于3d的内容,我们先来看一看数学中的一个题和答案,这样就很容易理解程序了。

这样就好办了!    直接看下面几个脚本吧。


using UnityEngine;  
using System.Collections;  
using SunGuangDong.Math;  
  
[ExecuteInEditMode]  
public class DrawCircleMono : MonoBehaviour {  
    private Vector3 m_Normal ;  
  
    // Use this for initialization  
    void Start () {  
        m_Normal = new Vector3 (0, 1, 0);  
    }  
      
    void OnDrawGizmos()  
    {  
        Circle2d circle2 = new Circle2d(transform.position, 5);  
        DrawCircle(ref circle2, Color.red);  
  
        Vector3 center = new Vector3 (transform.position.x, transform.position.y + 0.2f, transform.position.z);  
        Circle3d circle3 = new Circle3d(ref center,ref m_Normal, 5);  
        DrawCircle (circle3, Color.red, 40);  
    }  
  
  
    protected void DrawCircle(ref Circle2d circle, Color color)  
    {  
        int count = 40;  
        float delta = 2f * Mathf.PI / count;  
        Vector3 prev = circle.Eval(0);  
  
        Color tempColor = Gizmos.color;  
        Gizmos.color = color;  
  
        for (int i = 1; i <= count; ++i)  
        {  
            Vector3 curr = circle.Eval(i * delta);  
            Gizmos.DrawLine(prev, curr);  
            prev = curr;  
        }  
  
        Gizmos.color = tempColor;  
    }  
      
    protected void DrawCircle(Vector2 center, float radius, Color color)  
    {  
        Circle2d circle = new Circle2d(ref center, radius);  
        int count = 40;  
        float delta = 2f * Mathf.PI / count;  
        Vector3 prev = circle.Eval(0);  
  
        Color tempColor = Gizmos.color;  
        Gizmos.color = color;  
  
        for (int i = 1; i <= count; ++i)  
        {  
            Vector3 curr = circle.Eval(i * delta);  
            Gizmos.DrawLine(prev, curr);  
            prev = curr;  
        }  
  
        Gizmos.color = tempColor;  
    }  
      
    protected void DrawCircle(Circle3d circle, Color color, int count = 20)  
    {  
        float delta = 2f * Mathf.PI / count;  
        Vector3 prev = circle.Eval(0);  
  
        Color tempColor = Gizmos.color;  
        Gizmos.color = color;  
  
        for (int i = 1; i <= count; ++i)  
        {  
            Vector3 curr = circle.Eval(i * delta);  
            Gizmos.DrawLine(prev, curr);  
            prev = curr;  
        }  
  
        Gizmos.color = tempColor;  
    }  
}  

上面这个脚本在 挂到场景中的任意对象上,如Cube

namespace SunGuangDong.Math  
{  
    using System;  
    using System.Collections.Generic;  
    using System.Runtime.Interopservices;  
    using UnityEngine;  

    [StructLayout(LayoutKind.Sequential)]  
    public struct Circle2d  
    {  
        public Vector2 Center;  
        public float Radius;  
        public Circle2d(ref Vector2 center, float radius)  
        {  
            this.Center = center;  
            this.Radius = radius;  
        }  

        public Circle2d(Vector2 center, float radius)  
        {  
            this.Center = center;  
            this.Radius = radius;  
        }  

        public float CalcPerimeter()  
        {  
            return (6.283185f * this.Radius);  
        }  

        public float CalcArea()  
        {  
            return ((3.141593f * this.Radius) * this.Radius);  
        }  

        public Vector2 Eval(float t)  
        {  
            return new Vector2(this.Center.x + (this.Radius * Mathf.Cos(t)), this.Center.y + (this.Radius * Mathf.Sin(t)));  
        }  

        public Vector2 Eval(float t, float radius)  
        {  
            return new Vector2(this.Center.x + (radius * Mathf.Cos(t)), this.Center.y + (radius * Mathf.Sin(t)));  
        }  
        public bool Contains(ref Vector2 point)  
        {  
            Vector2 vector = point - this.Center;  
            return (vector.magnitude <= (this.Radius * this.Radius));  
        }  

        public bool Contains(Vector2 point)  
        {  
            Vector2 vector = point - this.Center;  
            return (vector.magnitude <= (this.Radius * this.Radius));  
        }  

        public void Include(ref Circle2d circle)  
        {  
            Vector2 vector = circle.Center - this.Center;  
            float num = vector.magnitude;  
            float num2 = circle.Radius - this.Radius;  
            float num3 = num2 * num2;  
            if (num3 >= num)  
            {  
                if (num2 >= 0f)  
                {  
                    this = circle;  
                }  
            }  
            else  
            {  
                float num4 = Mathf.Sqrt(num);  
                if (num4 > 1E-05f)  
                {  
                    float num5 = (num4 + num2) / (2f * num4);  
                    this.Center += (Vector2) (num5 * vector);  
                }  
                this.Radius = 0.5f * ((num4 + this.Radius) + circle.Radius);  
            }  
        }  

        public void Include(Circle2d circle)  
        {  
            this.Include(ref circle);  
        }  
    }  
}  


namespace SunGuangDong.Math  
{  
    using System;  
    using System.Runtime.InteropServices;  
    using UnityEngine;  

    [StructLayout(LayoutKind.Sequential)]  
    public struct Circle3d  
    {  
        public Vector3 Center;  
        public Vector3 Axis0;  
        public Vector3 Axis1;  
        public Vector3 Normal;  
        public float Radius;  

        public Circle3d(ref Vector3 center, ref Vector3 normal, float radius)  
        {  
            this.Center = center;  
            this.Normal = normal;  
            Vector3ex.CreateOrthonormalBasis(out this.Axis0, out this.Axis1, ref this.Normal);  
            this.Radius = radius;  
        }  

        public Circle3d(Vector3 center, Vector3 normal, float radius)  
        {  
            this.Center = center;  
            this.Normal = normal;  
            Vector3ex.CreateOrthonormalBasis(out this.Axis0, out this.Axis1, ref this.Normal);  
            this.Radius = radius;  
        }  

        public float CalcPerimeter()  
        {  
            return (6.283185f * this.Radius);  
        }  

        public float CalcArea()  
        {  
            return ((3.141593f * this.Radius) * this.Radius);  
        }  

        public Vector3 Eval(float t)  
        {  
            return (this.Center + ((Vector3) (this.Radius * ((Mathf.Cos(t) * this.Axis0) + (Mathf.Sin(t) * this.Axis1)))));  
        }  

        public Vector3 Eval(float t, float radius)  
        {  
            return (this.Center + ((Vector3) (radius * ((Mathf.Cos(t) * this.Axis0) + (Mathf.Sin(t) * this.Axis1)))));  
        }  
    }  
}  



namespace SunGuangDong.Math  
{  
    using System;  
    using System.Collections.Generic;  
    using System.Runtime.CompilerServices;  
    using System.Runtime.InteropServices;  
    using UnityEngine;  

    public static class Vector3ex  
    {  
        public static readonly Vector3 Zero = new Vector3(0f, 0f, 0f);  

        public static void CreateOrthonormalBasis(out Vector3 u, out Vector3 v, ref Vector3 w)  
        {  
            if (Mathf.Abs(w.x) >= Mathf.Abs(w.y))  
            {  
                float num = Mathfex.InvSqrt((w.x * w.x) + (w.z * w.z));  
                u.x = -w.z * num;  
                u.y = 0f;  
                u.z = w.x * num;  
                v.x = w.y * u.z;  
                v.y = (w.z * u.x) - (w.x * u.z);  
                v.z = -w.y * u.x;  
            }  
            else  
            {  
                float num2 = Mathfex.InvSqrt((w.y * w.y) + (w.z * w.z));  
                u.x = 0f;  
                u.y = w.z * num2;  
                u.z = -w.y * num2;  
                v.x = (w.y * u.z) - (w.z * u.y);  
                v.y = -w.x * u.z;  
                v.z = w.x * u.y;  
            }  
        }  
    }  
}  



namespace SunGuangDong.Math  
{  
    using System;  
    using System.Runtime.InteropServices;  
    using UnityEngine;  

    public static class Mathfex  
    {  
        public const float Pi = 3.141593f;  

        public static float InvSqrt(float value)  
        {  
            if (value != 0f)  
            {  
                return (1f / Mathf.Sqrt(value));  
            }  
            return 0f;  
        }  
    }  
}  


最后附上一些其他图片吧。






1.png (136.41 KB, 下载次数: 273)

1

1

2.png (186.11 KB, 下载次数: 259)

2

2

3.png (386.62 KB, 下载次数: 269)

3

3

4.png (98.09 KB, 下载次数: 277)

4

4

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

115

主题

3

听众

5676

积分

高级设计师

Rank: 6Rank: 6

纳金币
7268
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2015-2-7 23:29:55 |只看该作者
Thanks for sharing this one !
回复

使用道具 举报

10

主题

0

听众

551

积分

初级设计师

Rank: 3Rank: 3

纳金币
586
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2015-2-8 11:19:58 |只看该作者
感谢分享,谢谢提供下载
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-4-29 12:19 , Processed in 0.097122 second(s), 30 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部