SGDE.Physics.Collision.CollisionUnit.GetCollisionPoint C# (CSharp) Method

GetCollisionPoint() public method

Get the point of collision with the other CollisionUnit. This does not do any real collision checks so the returned value might not be the actual collision point.
public GetCollisionPoint ( CollisionUnit other ) : Vector2
other CollisionUnit The CollisionUnit to get the collision point from.
return Vector2
        public Vector2 GetCollisionPoint(CollisionUnit other)
        {
            Vector2 otherCircleCenter;
            int otherCircleRadius;
            Vector2 boxUpperLeft;
            Vector2 boxLowerRight;
            float dX;
            float dY;
            float ratio;
            Vector2 collisionPoint = new Vector2(-1, -1);

            if (mCollisionType == CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionType.COLLISION_CIRCLE)
            {
                otherCircleCenter = other.GetCircleCenter();
                otherCircleRadius = other.GetCircleRadius();

                dX = otherCircleCenter.X - mCircleCenter.X;
                dY = otherCircleCenter.Y - mCircleCenter.Y;

                ratio = ((float)mCircleRadius) / (mCircleRadius + otherCircleRadius);

                dX *= ratio;
                dY *= ratio;

                collisionPoint = new Vector2(mCircleCenter.X + dX, mCircleCenter.Y + dY);
            }
            else if ((mCollisionType == CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionType.COLLISION_BOX)
                    || (mCollisionType == CollisionType.COLLISION_BOX && other.GetCollisionType() == CollisionType.COLLISION_CIRCLE))
            {
                if (mCollisionType == CollisionType.COLLISION_CIRCLE)
                {
                    otherCircleCenter = mCircleCenter;
                    otherCircleRadius = mCircleRadius;
                    boxUpperLeft = other.GetUpperLeft();
                    boxLowerRight = other.GetLowerRight();
                }
                else
                {
                    otherCircleCenter = other.GetCircleCenter();
                    otherCircleRadius = other.GetCircleRadius();
                    boxUpperLeft = mPoint1;
                    boxLowerRight = mPoint2;
                }

                if (otherCircleCenter.X > boxLowerRight.X)
                {
                    if (otherCircleCenter.Y > boxLowerRight.Y)
                    {
                        collisionPoint = boxLowerRight;
                    }
                    else if (otherCircleCenter.Y < boxUpperLeft.Y)
                    {
                        collisionPoint = new Vector2(boxLowerRight.X, boxUpperLeft.Y);
                    }
                    else
                    {
                        collisionPoint = new Vector2(otherCircleCenter.X - otherCircleRadius, otherCircleCenter.Y);
                    }
                }
                else if (otherCircleCenter.X < boxUpperLeft.X)
                {
                    if (otherCircleCenter.Y > boxLowerRight.Y)
                    {
                        collisionPoint = new Vector2(boxUpperLeft.X, boxLowerRight.Y);
                    }
                    else if (otherCircleCenter.Y < boxUpperLeft.Y)
                    {
                        collisionPoint = boxUpperLeft;
                    }
                    else
                    {
                        collisionPoint = new Vector2(otherCircleCenter.X + otherCircleRadius, otherCircleCenter.Y);
                    }
                }
                else if (otherCircleCenter.Y > boxLowerRight.Y)
                {
                    collisionPoint = new Vector2(otherCircleCenter.X, otherCircleCenter.Y - otherCircleRadius);
                }
                else if (otherCircleCenter.Y < boxUpperLeft.Y)
                {
                    collisionPoint = new Vector2(otherCircleCenter.X, otherCircleCenter.Y + otherCircleRadius);
                }
                else
                {
                    // inside
                    collisionPoint = otherCircleCenter;
                }
            }

            return collisionPoint;
        }

Usage Example

示例#1
0
        /// <summary>
        /// Add a bounce between two CollisionUnits based on the velocity.
        /// </summary>
        /// <param name="unit">The main collision unit involved in the "bounce".</param>
        /// <param name="other">The secondary collision unit involved in the "bounce".</param>
        public void AddBounce(CollisionUnit unit, CollisionUnit other)
        {
            Vector2 unitCircleCenter;
            Vector2 otherCircleCenter;
            int unitRadius;
            int otherRadius;
            Vector2 oldVelocity;

            Vector2 norm;
            Vector2 unitNorm;
            Vector2 unitTan = new Vector2();
            Vector2 oldVelocityOther = new Vector2(0, 0);
            float velocityNorm;
            float velocityTan;
            float velocityNormOther;
            float velocityTanOther;
            float newVelocityScalar;
            float newVelocityScalarOther;
            Vector2 newVelocityNorm;
            Vector2 newVelocityNormOther;
            Vector2 newVelocityTan;
            Vector2 newVelocityTanOther;
            Vector2 newVelocity;
            Vector2 newVelocityOther;
            float mass = 1;
            float massOther = 10000;
            Vector2 velocityDiff;

            if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE)
            {
                unitCircleCenter = unit.GetCircleCenter();
                unitRadius = unit.GetCircleRadius();

                otherCircleCenter = other.GetCircleCenter();
                otherRadius = other.GetCircleRadius();

                oldVelocity = mVelocity;

                ////////////////

                norm = otherCircleCenter - unitCircleCenter;
                unitNorm = norm / ((float)Math.Sqrt(norm.X * norm.X + norm.Y * norm.Y));
                unitTan.X = unitNorm.Y * -1;
                unitTan.Y = unitNorm.X;

                velocityNorm = Vector2.Dot(unitNorm, oldVelocity);
                velocityTan = Vector2.Dot(unitTan, oldVelocity);
                velocityNormOther = Vector2.Dot(unitNorm, oldVelocityOther);
                velocityTanOther = Vector2.Dot(unitTan, oldVelocityOther);

                newVelocityScalar = (velocityNorm * (mass - massOther) + 2 * massOther * velocityNormOther) / (mass + massOther);
                newVelocityScalarOther = (velocityNormOther * (massOther - mass) + 2 * mass * velocityNorm) / (mass + massOther);

                newVelocityNorm = newVelocityScalar * unitNorm;
                newVelocityNormOther = newVelocityScalarOther * unitNorm;

                newVelocityTan = velocityTan * unitTan;
                newVelocityTanOther = velocityTanOther * unitTan;

                newVelocity = newVelocityNorm + newVelocityTan;
                newVelocityOther = newVelocityNormOther + newVelocityTanOther;

                newVelocity *= 0.99f;

                velocityDiff = newVelocity - mVelocity;
                mVelocity = newVelocity;

                // some fudge
                //if (velocityDiff.X > 1 || velocityDiff.X < -1 || velocityDiff.Y > 1 || velocityDiff.Y < -1)
                //{
                    mOwner.Translate(0.04f * (unitCircleCenter.X - otherCircleCenter.X), 0.04f * (unitCircleCenter.Y - otherCircleCenter.Y));
                //}
            }
            else
            {
                newVelocity = mVelocity * -0.8f;
                velocityDiff = newVelocity - mVelocity;
                mVelocity = newVelocity;
                unitCircleCenter = unit.GetCircleCenter();
                otherCircleCenter = unit.GetCollisionPoint(other);

                //if (velocityDiff.X > 1 || velocityDiff.X < -1 || velocityDiff.Y > 1 || velocityDiff.Y < -1)
                //{
                    mOwner.Translate(0.04f * (unitCircleCenter.X - otherCircleCenter.X), 0.04f * (unitCircleCenter.Y - otherCircleCenter.Y));
                //}
            }
        }