예제 #1
0
파일: Raycast.cs 프로젝트: Slaktus/Tetra
        private static bool Raycast(float2 from, float2 to, CircleCollider circle)
        {
            float2 delta = to - from;

            float a = delta.x * delta.x + delta.y * delta.y;
            float b = 2 * (delta.x * (from.x - circle.position.x) + delta.y * (from.y - circle.position.y));
            float c = (from.x - circle.position.x) * (from.x - circle.position.x) + (from.y - circle.position.y) * (from.y - circle.position.y) - (circle.radius * circle.radius);

            float discriminant = b * b - 4 * a * c;

            if (0 > discriminant)
            {
                return(false);
            }

            float positive = (-b + math.sqrt(discriminant)) / (2 * a);

            if (positive >= 0 && 1 >= positive)
            {
                return(true);
            }

            float negative = (-b - math.sqrt(discriminant)) / (2 * a);

            return(negative >= 0 && 1 >= negative);
        }
예제 #2
0
        private static bool Intersects(CircleCollider circle, ShapeCollider shape)
        {
            float2 nearest     = shape.position + shape.points[0];
            float  minDistance = math.distancesq(circle.position, nearest);

            for (int i = 1; shape.points.Count > i; i++)
            {
                float distance = math.distancesq(circle.position, shape.position + shape.points[i]);

                if (minDistance > distance)
                {
                    minDistance = distance;
                    nearest     = shape.position + shape.points[i];
                }
            }

            float2 axis = math.normalizesafe(nearest - circle.position);

            if (LineOverlap(Project(shape, axis), Project(circle, axis)) == 0)
            {
                return(false);
            }

            for (int i = 0; shape.points.Count > i; i++)
            {
                axis = math.normalizesafe(shape.edges[i].perpendicular());

                if (LineOverlap(Project(shape, axis), Project(circle, axis)) == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        private static float2 Depenetrate(CircleCollider circleA, CircleCollider circleB)
        {
            float2 direction   = circleA.position - circleB.position;
            float  summedRadii = circleA.radius + circleB.radius;
            float  distance    = math.length(direction);

            return(summedRadii > distance?math.normalizesafe(direction) * (summedRadii - distance) : float2.zero);
        }
예제 #4
0
        private static bool ContainedBy(ShapeCollider shapeCollider, CircleCollider circleCollider)
        {
            for (int i = 0; shapeCollider.points.Count > i; i++)
            {
                if (!ContainedBy(shapeCollider.position + shapeCollider.points[i], circleCollider))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #5
0
        private static float2 Depenetrate(CircleCollider circle, ShapeCollider shape)
        {
            float2 nearest = shape.position + shape.points[0];
            float  lowest  = math.distancesq(circle.position, nearest);

            for (int i = 1; shape.points.Count > i; i++)
            {
                float distance = math.distancesq(circle.position, shape.position + shape.points[i]);

                if (lowest > distance)
                {
                    lowest  = distance;
                    nearest = shape.position + shape.points[i];
                }
            }

            float2 depenetration = float2.zero;
            float  depth         = float.PositiveInfinity;
            float2 axis          = math.normalizesafe(nearest - circle.position);
            float  overlap       = LineOverlap(Project(shape, axis), Project(circle, axis));

            if (overlap == 0)
            {
                return(float2.zero);
            }

            if (depth > overlap)
            {
                depth         = overlap;
                depenetration = axis;
            }

            for (int i = 0; shape.points.Count > i; i++)
            {
                axis    = math.normalizesafe(shape.edges[i].perpendicular());
                overlap = LineOverlap(Project(shape, axis), Project(circle, axis));

                if (overlap == 0)
                {
                    return(float2.zero);
                }

                if (depth > overlap)
                {
                    depth         = overlap;
                    depenetration = axis;
                }
            }

            return(depenetration * depth * (math.dot(depenetration, shape.position - circle.position) >= 0 ? -1 : 1));
        }
예제 #6
0
        private static float2 Depenetrate <T>(CircleCollider circleColliderA, T colliderB) where T : AbstractCollider
        {
            switch (colliderB)
            {
            case CircleCollider circleColliderB:
                return(Depenetrate(circleColliderA, circleColliderB));

            case ShapeCollider shapeColliderB:
                return(Depenetrate(circleColliderA, shapeColliderB));

            default:
                return(float2.zero);
            }
        }
예제 #7
0
        private static bool ContainedBy <T>(CircleCollider circleColliderA, T colliderB) where T : AbstractCollider
        {
            switch (colliderB)
            {
            case CircleCollider circleColliderB:
                return(ContainedBy(circleColliderA, circleColliderB));

            case ShapeCollider shapeColliderB:
                return(ContainedBy(shapeColliderB, circleColliderA));

            default:
                return(false);
            }
        }
예제 #8
0
        private static bool Intersects <T>(CircleCollider circleColliderA, T colliderB) where T : AbstractCollider
        {
            switch (colliderB)
            {
            case CircleCollider circleColliderB:
                return(Intersects(circleColliderA, circleColliderB));

            case ShapeCollider shapeColliderB:
                return(Intersects(circleColliderA, shapeColliderB));

            default:
                return(false);
            }
        }
예제 #9
0
 private static float2 Depenetrate(ShapeCollider shape, CircleCollider circle) => - Depenetrate(circle, shape);
예제 #10
0
파일: Common.cs 프로젝트: Slaktus/Tetra
        private static float2 Project(CircleCollider circle, float2 axis)
        {
            float dot = math.dot(circle.position, axis);

            return(new float2(dot - circle.radius, dot + circle.radius));
        }
예제 #11
0
 public CircleCollider(CircleCollider circleCollider) : this(circleCollider.radius)
 {
 }
예제 #12
0
파일: AABB.cs 프로젝트: Slaktus/Tetra
 public AABB(CircleCollider collider) : this(collider.position, collider.radius)
 {
 }
예제 #13
0
 private static bool ContainedBy(float2 point, CircleCollider circleCollider) => circleCollider.radius * circleCollider.radius > math.distancesq(point, circleCollider.position);
예제 #14
0
 private static bool ContainedBy(CircleCollider circleColliderA, CircleCollider circleColliderB) => (circleColliderB.radius - circleColliderA.radius) * (circleColliderB.radius - circleColliderA.radius) > math.distancesq(circleColliderA.position, circleColliderB.position);
예제 #15
0
 private static bool Intersects(ShapeCollider shape, CircleCollider circle) => Intersects(circle, shape);
예제 #16
0
 private static bool Intersects(CircleCollider circleA, CircleCollider circleB) => (circleA.radius + circleB.radius) * (circleA.radius + circleB.radius) > math.distancesq(circleA.position, circleB.position);