public static FP DistanceBetweenPointAndLineSegment(ref TSVector2 point, ref TSVector2 start, ref TSVector2 end) { if (start == end) { return(TSVector2.Distance(point, start)); } TSVector2 v = TSVector2.Subtract(end, start); TSVector2 w = TSVector2.Subtract(point, start); FP c1 = TSVector2.Dot(w, v); if (c1 <= 0) { return(TSVector2.Distance(point, start)); } FP c2 = TSVector2.Dot(v, v); if (c2 <= c1) { return(TSVector2.Distance(point, end)); } FP b = c1 / c2; TSVector2 pointOnLine = TSVector2.Add(start, TSVector2.Multiply(v, b)); return(TSVector2.Distance(point, pointOnLine)); }
/// <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> // TS - public Dictionary<Body, Vector2> Activate(Vector2 pos, FP radius, FP force, FP maxForce = FP.MaxValue) public Dictionary <Body, TSVector2> Activate(TSVector2 pos, FP radius, FP force, FP maxForce) { HashSet <Body> affectedBodies = new HashSet <Body>(); AABB aabb; aabb.LowerBound = pos - new TSVector2(radius); aabb.UpperBound = pos + new TSVector2(radius); // Query the world for bodies within the radius. World.QueryAABB(fixture => { if (TSVector2.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 List <TSVector> SubdivideEvenly(int divisions) { List <TSVector> verts = new List <TSVector>(); FP length = GetLength(); FP deltaLength = length / divisions + 0.001f; FP t = 0.000f; // we always start at the first control point TSVector2 start = ControlPoints[0]; TSVector2 end = GetPosition(t); // increment t until we are at half the distance while (deltaLength * 0.5f >= TSVector2.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++) { TSVector2 normal = GetPositionNormal(t); FP angle = FP.Atan2(normal.y, normal.x); verts.Add(new TSVector(end.x, end.y, angle)); // until we reach the correct distance down the curve while (deltaLength >= TSVector2.Distance(start, end)) { end = GetPosition(t); t += 0.00001f; if (t >= 1f) { break; } } if (t >= 1f) { break; } start = end; } return(verts); }
public FP GetLength() { List <TSVector2> verts = GetVertices(ControlPoints.Count * 25); FP length = 0; for (int i = 1; i < verts.Count; i++) { length += TSVector2.Distance(verts[i - 1], verts[i]); } if (Closed) { length += TSVector2.Distance(verts[ControlPoints.Count - 1], verts[0]); } return(length); }
private Dictionary <Body, TSVector2> ApplyImpulse(TSVector2 pos, FP radius, FP force, FP maxForce, HashSet <Body> overlappingBodies) { Dictionary <Body, TSVector2> forces = new Dictionary <Body, TSVector2>(overlappingBodies.Count); foreach (Body overlappingBody in overlappingBodies) { if (IsActiveOn(overlappingBody)) { FP distance = TSVector2.Distance(pos, overlappingBody.Position); FP forcePercent = GetPercent(distance, radius); TSVector2 forceVector = pos - overlappingBody.Position; forceVector *= 1f / FP.Sqrt(forceVector.x * forceVector.x + forceVector.y * forceVector.y); forceVector *= TSMath.Min(force * forcePercent, maxForce); forceVector *= -1; overlappingBody.ApplyLinearImpulse(forceVector); forces.Add(overlappingBody, forceVector); } } return(forces); }
private bool SplitPolygonEdge(Vertices polygon, TSVector2 coordInsideThePolygon, out int vertex1Index, out int vertex2Index) { int num = 0; int index = 0; bool flag = false; FP y = FP.MaxValue; bool flag2 = false; TSVector2 zero = TSVector2.zero; List <FP> list = this.SearchCrossingEdges(polygon, (int)((long)coordInsideThePolygon.y)); vertex1Index = 0; vertex2Index = 0; zero.y = coordInsideThePolygon.y; bool flag3 = list != null && list.Count > 1 && list.Count % 2 == 0; bool result; if (flag3) { for (int i = 0; i < list.Count; i++) { bool flag4 = list[i] < coordInsideThePolygon.x; if (flag4) { FP fP = coordInsideThePolygon.x - list[i]; bool flag5 = fP < y; if (flag5) { y = fP; zero.x = list[i]; flag2 = true; } } } bool flag6 = flag2; if (flag6) { y = FP.MaxValue; int num2 = polygon.Count - 1; for (int j = 0; j < polygon.Count; j++) { TSVector2 tSVector = polygon[j]; TSVector2 tSVector2 = polygon[num2]; FP fP = LineTools.DistanceBetweenPointAndLineSegment(ref zero, ref tSVector, ref tSVector2); bool flag7 = fP < y; if (flag7) { y = fP; num = j; index = num2; flag = true; } num2 = j; } bool flag8 = flag; if (flag8) { TSVector2 value = polygon[index] - polygon[num]; value.Normalize(); TSVector2 value2 = polygon[num]; FP fP = TSVector2.Distance(value2, zero); vertex1Index = num; vertex2Index = num + 1; polygon.Insert(num, fP * value + polygon[vertex1Index]); polygon.Insert(num, fP * value + polygon[vertex2Index]); result = true; return(result); } } } result = false; return(result); }
private bool DistanceToHullAcceptable(Vertices polygon, TSVector2 point, bool higherDetail) { bool flag = polygon == null; if (flag) { throw new ArgumentNullException("polygon", "'polygon' can't be null."); } bool flag2 = polygon.Count < 3; if (flag2) { throw new ArgumentException("'polygon.Count' can't be less then 3."); } TSVector2 tSVector = polygon[polygon.Count - 1]; bool result; if (higherDetail) { for (int i = 0; i < polygon.Count; i++) { TSVector2 value = polygon[i]; bool flag3 = LineTools.DistanceBetweenPointAndLineSegment(ref point, ref value, ref tSVector) <= this._hullTolerance || TSVector2.Distance(point, value) <= this._hullTolerance; if (flag3) { result = false; return(result); } tSVector = polygon[i]; } result = true; } else { for (int j = 0; j < polygon.Count; j++) { TSVector2 value = polygon[j]; bool flag4 = LineTools.DistanceBetweenPointAndLineSegment(ref point, ref value, ref tSVector) <= this._hullTolerance; if (flag4) { result = false; return(result); } tSVector = polygon[j]; } result = true; } return(result); }
public static FP SDCircle(TSVector2 x, TSVector2 c, FP radius) { return(TSVector2.Distance(x, c) - radius); }