C# 计算游戏技能攻击区域

来源:互联网 发布:淘宝海报设计价格 编辑:程序博客网 时间:2024/05/22 00:26


孙广东  2017.10.22

http://blog.csdn.NET/u010019717

1、判断  一个点是否在  与坐标平行的矩形内


public struct AAB2 {    public Vector2 Min;    public Vector2 Max;    public static AAB2 CreateAAB2(Transform point0, Transform point1)    {        // Creates aab from two unsorted points, if you know min and max use constructor        return CreateFromTwoPoints(point0.position, point1.position);    }    public static AAB2 CreateFromTwoPoints(Vector2 point0, Vector2 point1)    {        AAB2 aab;        if (point0.x < point1.x)        {            aab.Min.x = point0.x;            aab.Max.x = point1.x;        }        else        {            aab.Min.x = point1.x;            aab.Max.x = point0.x;        }        if (point0.y < point1.y)        {            aab.Min.y = point0.y;            aab.Max.y = point1.y;            return aab;        }        aab.Min.y = point1.y;        aab.Max.y = point0.y;        return aab;    }    public bool Contains(ref Vector2 point)    {        if (point.x < this.Min.x)        {            return false;        }        if (point.x > this.Max.x)        {            return false;        }        if (point.y < this.Min.y)        {            return false;        }        if (point.y > this.Max.y)        {            return false;        }        return true;    }    public void CalcVertices(out Vector2 vertex0, out Vector2 vertex1, out Vector2 vertex2, out Vector2 vertex3)    {        vertex0 = this.Min;        vertex1 = new Vector2(this.Max.x, this.Min.y);        vertex2 = this.Max;        vertex3 = new Vector2(this.Min.x, this.Max.y);    }}

[ExecuteInEditMode]public class Test_ContPoint2AAB2 : MonoBehaviour{    public Transform Point;    public Transform Box_Point0, Box_Point1;    private const float _pointRadius = .11f;    private void OnDrawGizmos()    {        Vector2 point = Point.position;        AAB2 box = AAB2.CreateAAB2(Box_Point0, Box_Point1);        bool cont = box.Contains(ref point);        FiguresColor();        DrawAAB(ref box);        if (cont) ResultsColor();            DrawPoint(point);        LogInfo(cont);    }    protected void DrawPoint(Vector2 position)    {        Gizmos.DrawSphere(position, _pointRadius);    }    protected void ResultsColor()    {        Gizmos.color = Color.blue;    }    protected void FiguresColor()    {        Gizmos.color = Color.gray;    }    protected void LogInfo(object value)    {        Debug.Log(value);    }    protected void DrawAAB(ref AAB2 box)    {        Vector2 v0, v1, v2, v3;        box.CalcVertices(out v0, out v1, out v2, out v3);        Gizmos.DrawLine(v0, v1);        Gizmos.DrawLine(v1, v2);        Gizmos.DrawLine(v2, v3);        Gizmos.DrawLine(v3, v0);    }}


2 判断是否在矩形内


矩形就是 Box 对象决定, 自己是原点, 旋转决定了两个轴  Scale决定了 宽高!

[ExecuteInEditMode]public class Test_ContPoint2Box2 : MonoBehaviour{    public Transform Point;    public Transform Box;    private const float _pointRadius = .11f;    private void OnDrawGizmos()    {        Vector2 point = Point.position;        Box2 box = Box2.CreateBox2(Box);        bool cont = box.Contains(ref point);        FiguresColor();        DrawBox(ref box);        if (cont) ResultsColor();        DrawPoint(point);        LogInfo(cont);    }    protected void DrawPoint(Vector2 position)    {        Gizmos.DrawSphere(position, _pointRadius);    }    protected void ResultsColor()    {        Gizmos.color = Color.blue;    }    protected void FiguresColor()    {        Gizmos.color = Color.gray;    }    protected void LogInfo(object value)    {        Debug.Log(value);    }    protected void DrawBox(ref Box2 box)    {        Vector2 v0, v1, v2, v3;        box.CalcVertices(out v0, out v1, out v2, out v3);        Gizmos.DrawLine(v0, v1);        Gizmos.DrawLine(v1, v2);        Gizmos.DrawLine(v2, v3);        Gizmos.DrawLine(v3, v0);    }}

public struct Box2 {    public Vector2 Center;    public Vector2 Axis0;    public Vector2 Axis1;    public Vector2 Extents;    public Box2(Vector2 center, Vector2 axis0, Vector2 axis1, Vector2 extents)    {        this.Center = center;        this.Axis0 = axis0;        this.Axis1 = axis1;        this.Extents = extents;    }    public static Box2 CreateBox2(Transform box)    {        return new Box2(box.position, box.right, box.up, box.localScale);    }    public bool Contains(ref Vector2 point)    {        Vector2 vector;        vector.x = point.x - this.Center.x;        vector.y = point.y - this.Center.y;        float num = vector.Dot(ref this.Axis0);        if (num < -this.Extents.x)        {            return false;        }        if (num > this.Extents.x)        {            return false;        }        num = vector.Dot(ref this.Axis1);        if (num < -this.Extents.y)        {            return false;        }        if (num > this.Extents.y)        {            return false;        }        return true;    }    public void CalcVertices(out Vector2 vertex0, out Vector2 vertex1, out Vector2 vertex2, out Vector2 vertex3)    {        Vector2 vector = (Vector2)(this.Axis0 * this.Extents.x);        Vector2 vector2 = (Vector2)(this.Axis1 * this.Extents.y);        vertex0 = (this.Center - vector) - vector2;        vertex1 = (this.Center + vector) - vector2;        vertex2 = (this.Center + vector) + vector2;        vertex3 = (this.Center - vector) + vector2;    }}public static class Vector2ex{    public static float Dot(this Vector2 vector, ref Vector2 value)    {        return ((vector.x * value.x) + (vector.y * value.y));    }}

3  判断一个点是否在园内部



[ExecuteInEditMode]public class Test_ContPoint2Circle2 : MonoBehaviour{    public Transform Point;    public Transform Circle;    private const float _pointRadius = .11f;    private void OnDrawGizmos()    {        Vector2 point = Point.position;        Circle2 circle = Circle2.CreateCircle2(Circle);        bool cont = circle.Contains(ref point);        FiguresColor();        DrawCircle(ref circle);        if (cont) ResultsColor();        DrawPoint(point);        LogInfo(cont);    }    protected void DrawPoint(Vector2 position)    {        Gizmos.DrawSphere(position, _pointRadius);    }    protected void ResultsColor()    {        Gizmos.color = Color.blue;    }    protected void FiguresColor()    {        Gizmos.color = Color.gray;    }    protected void LogInfo(object value)    {        Debug.Log(value);    }    protected void DrawCircle(ref Circle2 circle)    {        int count = 40;        float delta = 2f * Mathf.PI / count;        Vector3 prev = circle.Eval(0);        for (int i = 1; i <= count; ++i)        {            Vector3 curr = circle.Eval(i * delta);            Gizmos.DrawLine(prev, curr);            prev = curr;        }    }}
public struct Circle2{    public Vector2 Center;    public float Radius;    public Circle2(Vector2 center, float radius)    {        this.Center = center;        this.Radius = radius;    }    public bool Contains(ref Vector2 point)    {        Vector2 vector = point - this.Center;        return (vector.SqrMagnitude() <= (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 static Circle2 CreateCircle2(Transform circle)    {        return new Circle2(circle.position, circle.localScale.x);    }}


4  三角形内



[ExecuteInEditMode]public class Test_ContPoint2Triangle2 : MonoBehaviour{    public Transform Point;    public Transform V0, V1, V2;    private const float _pointRadius = .11f;    private void OnDrawGizmos()    {        Vector2 point = Point.position;        Triangle2 triangle = Triangle2.CreateTriangle2(V0, V1, V2);        Orientations orientation = triangle.CalcOrientation();        if (orientation == Orientations.CCW)        {            bool cont = triangle.Contains(ref point);            bool cont1 = triangle.ContainsCCW(ref point); // 如果你知道三角形方向(顶点顺序方向),就用这个            FiguresColor();            DrawTriangle(ref triangle);            if (cont) ResultsColor();            DrawPoint(point);            LogInfo("Orientation: " + orientation + "    Contained: " + cont);            if (cont != cont1)                Debug.LogError("cont != cont1");        }        else if (orientation == Orientations.CW)        {            bool cont = triangle.Contains(ref point);            bool cont1 = triangle.ContainsCW(ref point); // 如果你知道三角形方向(顶点顺序方向),就用这个            FiguresColor();            DrawTriangle(ref triangle);            if (cont) ResultsColor();            DrawPoint(point);            LogInfo("Orientation: " + orientation + "    Contained: " + cont);            if (cont != cont1)                Debug.LogError("cont != cont1");        }        else // Degenerate        {            Debug.LogError("Triangle is degenerate");        }    }    void DrawTriangle(ref Triangle2 triangle)    {        Gizmos.DrawLine(triangle.V0, triangle.V1);        Gizmos.DrawLine(triangle.V1, triangle.V2);        Gizmos.DrawLine(triangle.V2, triangle.V0);    }    protected void DrawPoint(Vector2 position)    {        Gizmos.DrawSphere(position, _pointRadius);    }    protected void ResultsColor()    {        Gizmos.color = Color.blue;    }    protected void FiguresColor()    {        Gizmos.color = Color.gray;    }    protected void LogInfo(object value)    {        Debug.Log(value);    }}

public enum Orientations{    CW,    CCW,    None}public struct Triangle2 {    public Vector2 V0;    public Vector2 V1;    public Vector2 V2;    public static Triangle2 CreateTriangle2(Transform v0, Transform v1, Transform v2)    {        return new Triangle2(v0.position, v1.position, v2.position);    }    public Triangle2(Vector2 v0, Vector2 v1, Vector2 v2)    {        this.V0 = v0;        this.V1 = v1;        this.V2 = v2;    }    public Orientations CalcOrientation(float threshold = 1E-05f)    {        float num = this.CalcDeterminant();        if (num > threshold)        {            return Orientations.CCW;        }        if (num < -threshold)        {            return Orientations.CW;        }        return Orientations.None;    }    public float CalcDeterminant()    {        return ((((((this.V1.x * this.V2.y) + (this.V0.x * this.V1.y)) + (this.V2.x * this.V0.y)) - (this.V1.x * this.V0.y)) - (this.V2.x * this.V1.y)) - (this.V0.x * this.V2.y));    }    public bool Contains(ref Vector2 point)    {        bool flag = (((point.x - this.V1.x) * (this.V0.y - this.V1.y)) - ((point.y - this.V1.y) * (this.V0.x - this.V1.x))) < 0f;        bool flag2 = (((point.x - this.V2.x) * (this.V1.y - this.V2.y)) - ((point.y - this.V2.y) * (this.V1.x - this.V2.x))) < 0f;        if (flag != flag2)        {            return false;        }        bool flag3 = (((point.x - this.V0.x) * (this.V2.y - this.V0.y)) - ((point.y - this.V0.y) * (this.V2.x - this.V0.x))) < 0f;        return (flag2 == flag3);    }    /// <summary>    /// 当已经知道 三个顶点的顺序是逆时针方向的时候使用    /// </summary>    /// <param name="point"></param>    /// <returns></returns>    public bool ContainsCCW(ref Vector2 point)    {        if ((((point.x - this.V0.x) * (this.V1.y - this.V0.y)) - ((point.y - this.V0.y) * (this.V1.x - this.V0.x))) > 0f)        {            return false;        }        if ((((point.x - this.V1.x) * (this.V2.y - this.V1.y)) - ((point.y - this.V1.y) * (this.V2.x - this.V1.x))) > 0f)        {            return false;        }        if ((((point.x - this.V2.x) * (this.V0.y - this.V2.y)) - ((point.y - this.V2.y) * (this.V0.x - this.V2.x))) > 0f)        {            return false;        }        return true;    }    /// <summary>    /// 当已经知道 三个顶点的顺序是顺时针方向的时候使用    /// </summary>    /// <param name="point"></param>    /// <returns></returns>    public bool ContainsCW(ref Vector2 point)    {        if ((((point.x - this.V0.x) * (this.V1.y - this.V0.y)) - ((point.y - this.V0.y) * (this.V1.x - this.V0.x))) < 0f)        {            return false;        }        if ((((point.x - this.V1.x) * (this.V2.y - this.V1.y)) - ((point.y - this.V1.y) * (this.V2.x - this.V1.x))) < 0f)        {            return false;        }        if ((((point.x - this.V2.x) * (this.V0.y - this.V2.y)) - ((point.y - this.V2.y) * (this.V0.x - this.V2.x))) < 0f)        {            return false;        }        return true;    }}


5   凸多边形内


public class Test_ContPoint2ConvexPolygon2 : MonoBehaviour {    public Transform Point;    public Transform[] ConvexPolygon;    private const float _pointRadius = .11f;    private void OnDrawGizmos()    {        Vector2 point = Point.position;        Polygon2 convexPolygon = Polygon2.CreatePolygon2(ConvexPolygon);        Orientations orientation;        // 判断是凸状的不?        bool convex = convexPolygon.IsConvex(out orientation);        if (convex)        {            bool cont;            if (orientation == Orientations.CCW)            {                cont = convexPolygon.ContainsConvexCCW(ref point);                //cont = convexPolygon.ContainsConvexQuadCCW(point); // 如果你知道 方向(顶点顺序方向),就用这个            }            else // CW            {                cont = convexPolygon.ContainsConvexCW(ref point);                //cont = convexPolygon.ContainsConvexQuadCW(point);            }            FiguresColor();            DrawPolygon(convexPolygon);            if (cont) ResultsColor();            DrawPoint(point);            LogInfo("Orientation: " + orientation + "     Contained: " + cont);        }        else        {            FiguresColor();            DrawPolygon(convexPolygon);            DrawPoint(point);            Debug.LogError("polygon is non-convex");        }    }    protected void DrawPolygon(Polygon2 polygon)    {        for (int i0 = 0, i1 = polygon.VertexCount - 1; i0 < polygon.VertexCount; i1 = i0, ++i0)        {            Gizmos.DrawLine(polygon[i0], polygon[i1]);        }    }    protected void DrawPoint(Vector2 position)    {        Gizmos.DrawSphere(position, _pointRadius);    }    protected void ResultsColor()    {        Gizmos.color = Color.blue;    }    protected void FiguresColor()    {        Gizmos.color = Color.gray;    }    protected void LogInfo(object value)    {        Debug.Log(value);    }}

public struct Edge2{    public Vector2 Point0;    public Vector2 Point1;    public Vector2 Direction;    public Vector2 Normal;    public float Length;}public static class Vector3ex{    public static Vector2 ToVector2XY(this Vector3 vector)    {        return new Vector2(vector.x, vector.y);    }}public struct Polygon2 {    private Edge2[] _edges;    private Vector2[] _vertices;    public Polygon2(int vertexCount)    {        this._vertices = new Vector2[vertexCount];        this._edges = new Edge2[vertexCount];    }    public Vector2 this[int vertexIndex]    {        get        {            return this._vertices[vertexIndex];        }        set        {            this._vertices[vertexIndex] = value;        }    }    public int VertexCount    {        get        {            return this._vertices.Length;        }    }    public static Polygon2 CreatePolygon2(Transform[] polygon)    {        Polygon2 result = new Polygon2(polygon.Length);        for (int i = 0; i < polygon.Length; ++i)        {            result[i] = polygon[i].position.ToVector2XY();        }        result.UpdateEdges();        return result;    }    public void UpdateEdges()    {        int length = this._vertices.Length;        int index = length - 1;        for (int i = 0; i < length; i++)        {            Vector2 vector = (this._edges[index].Point1 = this._vertices[i]) - (this._edges[index].Point0 = this._vertices[index]);            this._edges[index].Length = Vector2ex.Normalize(ref vector, 1E-05f);            this._edges[index].Direction = vector;            this._edges[index].Normal = vector.Perp();            index = i;        }    }    /// <summary>    /// 判断当前是不是 凸 状的    /// </summary>    /// <param name="orientation"></param>    /// <param name="threshold"></param>    /// <returns></returns>    public bool IsConvex(out Orientations orientation, float threshold = 1E-05f)    {        orientation = Orientations.None;        int length = this._edges.Length;        int num2 = 0;        int index = length - 1;        for (int i = 0; i < length; i++)        {            Vector2 vector = -this._edges[index].Direction;            Vector2 direction = this._edges[i].Direction;            float num5 = vector.DotPerp(ref direction);            int num6 = ((num5 < -threshold) || (num5 > threshold)) ? ((num5 > 0f) ? 1 : -1) : 0;            if (num6 != 0)            {                if (num2 != 0)                {                    if (((num2 > 0) && (num6 < 0)) || ((num2 < 0) && (num6 > 0)))                    {                        return false;                    }                }                else                {                    num2 += num6;                }            }            index = i;        }        orientation = (num2 == 0) ? Orientations.None : ((num2 > 0) ? Orientations.CW : Orientations.CCW);        return (orientation != Orientations.None);    }    public bool ContainsConvexCCW(ref Vector2 point)    {        return this.SubContainsPointCCW(ref point, 0, 0);    }    public bool ContainsConvexCW(ref Vector2 point)    {        return this.SubContainsPointCW(ref point, 0, 0);    }    private bool SubContainsPointCCW(ref Vector2 p, int i0, int i1)    {        float num2;        float num3;        float num4;        float num5;        int num7;        int length = this._vertices.Length;        int num6 = i1 - i0;        if ((num6 == 1) || ((num6 < 0) && ((num6 + length) == 1)))        {            num2 = this._vertices[i1].y - this._vertices[i0].y;            num3 = this._vertices[i0].x - this._vertices[i1].x;            num4 = p.x - this._vertices[i0].x;            num5 = p.y - this._vertices[i0].y;            return (((num2 * num4) + (num3 * num5)) <= 0f);        }        if (i0 < i1)        {            num7 = (i0 + i1) >> 1;        }        else        {            num7 = ((i0 + i1) + length) >> 1;            if (num7 >= length)            {                num7 -= length;            }        }        num2 = this._vertices[num7].y - this._vertices[i0].y;        num3 = this._vertices[i0].x - this._vertices[num7].x;        num4 = p.x - this._vertices[i0].x;        num5 = p.y - this._vertices[i0].y;        if (((num2 * num4) + (num3 * num5)) > 0f)        {            return this.SubContainsPointCCW(ref p, i0, num7);        }        return this.SubContainsPointCCW(ref p, num7, i1);    }    private bool SubContainsPointCW(ref Vector2 p, int i0, int i1)    {        float num2;        float num3;        float num4;        float num5;        int num7;        int length = this._vertices.Length;        int num6 = i1 - i0;        if ((num6 == 1) || ((num6 < 0) && ((num6 + length) == 1)))        {            num2 = this._vertices[i1].y - this._vertices[i0].y;            num3 = this._vertices[i0].x - this._vertices[i1].x;            num4 = p.x - this._vertices[i0].x;            num5 = p.y - this._vertices[i0].y;            return (((num2 * num4) + (num3 * num5)) >= 0f);        }        if (i0 < i1)        {            num7 = (i0 + i1) >> 1;        }        else        {            num7 = ((i0 + i1) + length) >> 1;            if (num7 >= length)            {                num7 -= length;            }        }        num2 = this._vertices[num7].y - this._vertices[i0].y;        num3 = this._vertices[i0].x - this._vertices[num7].x;        num4 = p.x - this._vertices[i0].x;        num5 = p.y - this._vertices[i0].y;        if (((num2 * num4) + (num3 * num5)) < 0f)        {            return this.SubContainsPointCW(ref p, i0, num7);        }        return this.SubContainsPointCW(ref p, num7, i1);    }}

public static class Vector2ex{    public static float Dot(this Vector2 vector, ref Vector2 value)    {        return ((vector.x * value.x) + (vector.y * value.y));    }    public static float Normalize(ref Vector2 vector, float epsilon = 1E-05f)    {        float num = Mathf.Sqrt((vector.x * vector.x) + (vector.y * vector.y));        if (num >= epsilon)        {            float num2 = 1f / num;            vector.x *= num2;            vector.y *= num2;            return num;        }        vector.x = 0f;        vector.y = 0f;        return 0f;    }    public static float DotPerp(this Vector2 vector, ref Vector2 value)    {        return ((vector.x * value.y) - (vector.y * value.x));    }    public static Vector2 Perp(this Vector2 vector)    {        return new Vector2(vector.y, -vector.x);    }}


6  直接判断是否在多边形内。   凹多边形内 (其实不管是凹还是凸了)



public struct Edge2{    public Vector2 Point0;    public Vector2 Point1;    public Vector2 Direction;    public Vector2 Normal;    public float Length;}public static class Vector3ex{    public static Vector2 ToVector2XY(this Vector3 vector)    {        return new Vector2(vector.x, vector.y);    }}public struct Polygon2 {    private Edge2[] _edges;    private Vector2[] _vertices;    public Polygon2(int vertexCount)    {        this._vertices = new Vector2[vertexCount];        this._edges = new Edge2[vertexCount];    }    public Vector2 this[int vertexIndex]    {        get        {            return this._vertices[vertexIndex];        }        set        {            this._vertices[vertexIndex] = value;        }    }    public int VertexCount    {        get        {            return this._vertices.Length;        }    }    public static Polygon2 CreatePolygon2(Transform[] polygon)    {        Polygon2 result = new Polygon2(polygon.Length);        for (int i = 0; i < polygon.Length; ++i)        {            result[i] = polygon[i].position.ToVector2XY();        }        result.UpdateEdges();        return result;    }    public void UpdateEdges()    {        int length = this._vertices.Length;        int index = length - 1;        for (int i = 0; i < length; i++)        {            Vector2 vector = (this._edges[index].Point1 = this._vertices[i]) - (this._edges[index].Point0 = this._vertices[index]);            this._edges[index].Length = Vector2ex.Normalize(ref vector, 1E-05f);            this._edges[index].Direction = vector;            this._edges[index].Normal = vector.Perp();            index = i;        }    }    public bool ContainsSimple(ref Vector2 point)    {        bool flag = false;        int length = this._vertices.Length;        int index = 0;        int num3 = length - 1;        while (index < length)        {            float num4;            float num5;            Vector2 vector = this._vertices[index];            Vector2 vector2 = this._vertices[num3];            if (point.y < vector2.y)            {                if (vector.y <= point.y)                {                    num5 = (point.y - vector.y) * (vector2.x - vector.x);                    num4 = (point.x - vector.x) * (vector2.y - vector.y);                    if (num5 > num4)                    {                        flag = !flag;                    }                }            }            else if (point.y < vector.y)            {                num5 = (point.y - vector.y) * (vector2.x - vector.x);                num4 = (point.x - vector.x) * (vector2.y - vector.y);                if (num5 < num4)                {                    flag = !flag;                }            }            num3 = index;            index++;        }        return flag;    }}

[ExecuteInEditMode]public class Test_ContPoint2Polygon2 : MonoBehaviour{    public Transform Point;    public Transform[] Polygon;    private const float _pointRadius = .11f;    private void OnDrawGizmos()    {        Vector2 point = Point.position;        Polygon2 polygon = Polygon2.CreatePolygon2(Polygon);        bool cont = polygon.ContainsSimple(ref point);        FiguresColor();        DrawPolygon(polygon);        if (cont) ResultsColor();        DrawPoint(point);        LogInfo(cont);    }    protected void DrawPolygon(Polygon2 polygon)    {        for (int i0 = 0, i1 = polygon.VertexCount - 1; i0 < polygon.VertexCount; i1 = i0, ++i0)        {            Gizmos.DrawLine(polygon[i0], polygon[i1]);        }    }    protected void DrawPoint(Vector2 position)    {        Gizmos.DrawSphere(position, _pointRadius);    }    protected void ResultsColor()    {        Gizmos.color = Color.blue;    }    protected void FiguresColor()    {        Gizmos.color = Color.gray;    }    protected void LogInfo(object value)    {        Debug.Log(value);    }}

public static class Vector2ex{    public static float Normalize(ref Vector2 vector, float epsilon = 1E-05f)    {        float num = Mathf.Sqrt((vector.x * vector.x) + (vector.y * vector.y));        if (num >= epsilon)        {            float num2 = 1f / num;            vector.x *= num2;            vector.y *= num2;            return num;        }        vector.x = 0f;        vector.y = 0f;        return 0f;    }    public static Vector2 Perp(this Vector2 vector)    {        return new Vector2(vector.y, -vector.x);    }}



原创粉丝点击