/// <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); }
/// <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); }
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); }
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); } }