/// <summary> /// Activate the explosion at the specified position. /// </summary> /// <param name="pos">The position (center) of the explosion.</param> /// <param name="radius">The radius of the explosion.</param> /// <param name="force">The force applied</param> /// <param name="maxForce">A maximum amount of force. When force gets over this value, it will be equal to maxForce</param> /// <returns>A list of bodies and the amount of force that was applied to them.</returns> // FP - public Dictionary<Body, Vector2> Activate(Vector2 pos, FP radius, FP force, FP maxForce = FP.MaxValue) public Dictionary <Body, FPVector2> Activate(FPVector2 pos, FP radius, FP force, FP maxForce) { HashSet <Body> affectedBodies = new HashSet <Body>(); AABB aabb; aabb.LowerBound = pos - new FPVector2(radius); aabb.UpperBound = pos + new FPVector2(radius); // Query the world for bodies within the radius. World.QueryAABB(fixture => { if (FPVector2.Distance(fixture.Body.Position, pos) <= radius) { if (!affectedBodies.Contains(fixture.Body)) { affectedBodies.Add(fixture.Body); } } return(true); }, ref aabb); return(ApplyImpulse(pos, radius, force, maxForce, affectedBodies)); }
public static FP DistanceBetweenPointAndLineSegment(ref FPVector2 point, ref FPVector2 start, ref FPVector2 end) { if (start == end) { return(FPVector2.Distance(point, start)); } FPVector2 v = FPVector2.Subtract(end, start); FPVector2 w = FPVector2.Subtract(point, start); FP c1 = FPVector2.Dot(w, v); if (c1 <= 0) { return(FPVector2.Distance(point, start)); } FP c2 = FPVector2.Dot(v, v); if (c2 <= c1) { return(FPVector2.Distance(point, end)); } FP b = c1 / c2; FPVector2 pointOnLine = FPVector2.Add(start, FPVector2.Multiply(v, b)); return(FPVector2.Distance(point, pointOnLine)); }
public List <FPVector> SubdivideEvenly(int divisions) { List <FPVector> verts = new List <FPVector>(); FP length = GetLength(); FP deltaLength = length / divisions + 0.001f; FP t = 0.000f; // we always start at the first control point FPVector2 start = ControlPoints[0]; FPVector2 end = GetPosition(t); // increment t until we are at half the distance while (deltaLength * 0.5f >= FPVector2.Distance(start, end)) { end = GetPosition(t); t += 0.0001f; if (t >= 1f) { break; } } start = end; // for each box for (int i = 1; i < divisions; i++) { FPVector2 normal = GetPositionNormal(t); FP angle = FP.Atan2(normal.y, normal.x); verts.Add(new FPVector(end.x, end.y, angle)); // until we reach the correct distance down the curve while (deltaLength >= FPVector2.Distance(start, end)) { end = GetPosition(t); t += 0.00001f; if (t >= 1f) { break; } } if (t >= 1f) { break; } start = end; } return(verts); }
public FP?IntersectsWithRay(FPVector2 origin, FPVector2 direction) { FP largestDistance = FPMath.Max(A.Position.x - origin.x, B.Position.x - origin.x) * 2f; LineSegment raySegment = new LineSegment(new Vertex(origin, 0), new Vertex(origin + (direction * largestDistance), 0)); FPVector2?intersection = FindIntersection(this, raySegment); FP? value = null; if (intersection != null) { value = FPVector2.Distance(origin, intersection.Value); } return(value); }
public FP GetLength() { List <FPVector2> verts = GetVertices(ControlPoints.Count * 25); FP length = 0; for (int i = 1; i < verts.Count; i++) { length += FPVector2.Distance(verts[i - 1], verts[i]); } if (Closed) { length += FPVector2.Distance(verts[ControlPoints.Count - 1], verts[0]); } return(length); }
private Dictionary <Body, FPVector2> ApplyImpulse(FPVector2 pos, FP radius, FP force, FP maxForce, HashSet <Body> overlappingBodies) { Dictionary <Body, FPVector2> forces = new Dictionary <Body, FPVector2>(overlappingBodies.Count); foreach (Body overlappingBody in overlappingBodies) { if (IsActiveOn(overlappingBody)) { FP distance = FPVector2.Distance(pos, overlappingBody.Position); FP forcePercent = GetPercent(distance, radius); FPVector2 forceVector = pos - overlappingBody.Position; forceVector *= 1f / FP.Sqrt(forceVector.x * forceVector.x + forceVector.y * forceVector.y); forceVector *= FPMath.Min(force * forcePercent, maxForce); forceVector *= -1; overlappingBody.ApplyLinearImpulse(forceVector); forces.Add(overlappingBody, forceVector); } } return(forces); }