Example #1
0
        /// <summary>
        /// Get the velocity of this point on the polygon. A sum of the translational and tangential velocities at the point.
        /// </summary>
        /// <param name="pointOnPolygon">The point of the local velocity.</param>
        /// <returns>Returns the velocity at this point.</returns>
        public Vector2 GetLocalVelocity(Vector2 pointOnPolygon)
        {
            Vector2 radiusVector       = pointOnPolygon - CollisionPolygon.CenterPoint;
            Vector2 tangentialVelocity = IntersectionEvent.CrossProduct(_angularVelocity, radiusVector);

            return(tangentialVelocity + _translationalVelocity);
        }
Example #2
0
        /// <summary>
        /// Applies a force at the given application point on the polygon. Will calculate torque.
        /// </summary>
        /// <param name="forceVector">The value of the force.</param>
        /// <param name="applicationPoint">The point on the polygon at which to apply the force.</param>
        public void ApplyForce(Vector2 forceVector, Vector2 applicationPoint)
        {
            AddTranslationalVelocity(forceVector * IntersectionEvent.GetLimitedRecip(Mass), isMomentum: false);

            Vector2 radiusVector = applicationPoint - CollisionPolygon.CenterPoint;

            radiusVector.Normalize();
            AddAngularVelocity(IntersectionEvent.GetLimitedRecip(Inertia) * IntersectionEvent.CrossProduct(radiusVector, forceVector), isMomentum: false);
        }
Example #3
0
        public float GreatestSameSide(Vector2[] points, Vector2 samplePoint)
        {
            float greatestDepth = float.NaN;

            Vector2 lineNormal = NormalizedNormal;

            for (int i = 0; i < points.Length; i++)
            {
                if (SharesPointSide(points[i], samplePoint))
                {
                    float penetrationDepth = Math.Abs(IntersectionEvent.DotProduct(containedPoint, lineNormal) - IntersectionEvent.DotProduct(points[i], lineNormal));
                    if (float.IsNaN(greatestDepth) || penetrationDepth > greatestDepth)
                    {
                        greatestDepth = penetrationDepth;
                    }
                }
            }

            return(greatestDepth);
        }
Example #4
0
        public static bool AreColliding(RigidBody rigidBody1, RigidBody rigidBody2, out IntersectionEvent intersectionEvent)
        {
            //Get side segments
            RigidBody[]     rigidBodies  = new RigidBody[] { rigidBody1, rigidBody2 };
            LineSegment[][] sideSegments = new LineSegment[rigidBodies.Length][];
            for (int i = 0; i < sideSegments.Length; i++)
            {
                sideSegments[i] = rigidBodies[i].CollisionPolygon.SideSegments;
            }

            //Determine overlapping axes
            LineSegment minimumOverlap   = null;
            RigidBody   recipientRB      = null;
            int         recipientRBIndex = 0;
            LineSegment recipientSide    = null;

            for (int i = 0; i < sideSegments.Length; i++)
            {
                if (rigidBodies[i].CollisionPolygon.ContainsPoint(rigidBodies[(i + 1) % rigidBodies.Length].CollisionPolygon.Vertices))
                {
                    for (int j = 0; j < sideSegments[i].Length; j++)
                    {
                        Line          segmentNormal   = sideSegments[i][j].NormalLine;
                        LineSegment[] bodyProjections = new LineSegment[rigidBodies.Length];
                        for (int k = 0; k < rigidBodies.Length; k++)
                        {
                            bodyProjections[k] = rigidBodies[(k + i) % rigidBodies.Length].CollisionPolygon.PolygonProjection(segmentNormal);
                        }

                        //Determine overlap
                        LineSegment projectionOverlap;
                        if (bodyProjections[0].IsOverlapping(bodyProjections[1], out projectionOverlap))
                        {
                            //Check for minimum
                            Vector2 intersectionPoint = new Vector2();
                            if (projectionOverlap.IntersectsSegment(sideSegments[i][j], ref intersectionPoint) && (minimumOverlap == null || minimumOverlap.Length > projectionOverlap.Length))
                            {
                                minimumOverlap   = projectionOverlap;
                                recipientRB      = rigidBodies[i];
                                recipientRBIndex = i;
                                recipientSide    = sideSegments[i][j];
                                //intersectionRecipient = new IntersectionRecipient(rigidBodies[i], sideSegments[i][j]);
                            }
                        }
                        else
                        {
                            //No overlap, not colliding
                            intersectionEvent = null;
                            return(false);
                        }
                    }
                }
            }

            if (minimumOverlap != null)
            {
                intersectionEvent = new IntersectionEvent(rigidBodies[(recipientRBIndex + 1) % 2], recipientRB, new IntersectionData(false, minimumOverlap, recipientSide, true));
                return(true);
            }
            else
            {
                intersectionEvent = null;
                return(false);
            }
        }