FluidInfo ILineFluidAffectable.GetFluidInfo(GetTangentCallback callback, Line line) { if (polygons.Length == 1) { return(ShapeHelper.GetFluidInfo(Vertexes, callback, line)); } List <Vector2D[]> submerged = new List <Vector2D[]>(polygons.Length); for (int index = 0; index < polygons.Length; ++index) { Vector2D[] vertexes = VertexHelper.GetIntersection(polygons[index], line); if (vertexes.Length >= 3) { submerged.Add(vertexes); } } if (submerged.Count == 0) { return(null); } Vector2D[][] newPolygons = submerged.ToArray(); Vector2D centroid = VertexHelper.GetCentroidOfRange(newPolygons); Scalar area = VertexHelper.GetAreaOfRange(newPolygons); Vector2D tangent = callback(centroid); Vector2D dragCenter; Scalar dragArea; ShapeHelper.GetFluidInfo(newPolygons, tangent, out dragCenter, out dragArea); return(new FluidInfo(dragCenter, dragArea, centroid, area)); }
DragInfo IGlobalFluidAffectable.GetFluidInfo(Vector2D tangent) { Vector2D dragCenter; Scalar dragArea; ShapeHelper.GetFluidInfo(polygons, tangent, out dragCenter, out dragArea); return(new DragInfo(dragCenter, dragArea)); }
DragInfo IGlobalFluidAffectable.GetFluidInfo(Vector2D tangent) { Scalar min, max; ShapeHelper.GetProjectedBounds(this.Vertexes, tangent, out min, out max); Scalar avg = (max + min) / 2; return(new DragInfo(tangent * avg, max - min)); }
/// <summary> /// Creates a new Circle Instance. /// </summary> /// <param name="radius">how large the circle is.</param> /// <param name="vertexCount"> /// The number or vertex that will be generated along the perimeter of the circle. /// This is for collision detection. /// </param> /// <param name="momentOfInertiaMultiplier"> /// How hard it is to turn the shape. Depending on the construtor in the /// Body this will be multiplied with the mass to determine the moment of inertia. /// </param> public CircleShape(Scalar radius, int vertexCount, Scalar momentOfInertiaMultiplier) : base(CreateCircle(radius, vertexCount), momentOfInertiaMultiplier) { if (radius <= 0) { throw new ArgumentOutOfRangeException("radius", "must be larger then zero"); } this.radius = radius; this.Normals = ShapeHelper.CalculateNormals(this.Vertexes); }
private Vector2D[] CalculateNormals() { Vector2D[] result = new Vector2D[Vertexes.Length]; int offset = 0; for (int index = 0; index < polygons.Length; ++index) { Vector2D[] polygon = polygons[index]; ShapeHelper.CalculateNormals(polygon, result, offset); offset += polygon.Length; } return(result); }
public static void GetFluidInfo(Vector2D[][] polygons, Vector2D tangent, out Vector2D dragCenter, out Scalar dragArea) { Scalar min, max; Scalar avg; if (polygons.Length == 1) { ShapeHelper.GetProjectedBounds( polygons[0], tangent, out min, out max); avg = (max + min) / 2; dragCenter = tangent * avg; dragArea = max - min; return; } SAPNode[] sapNodes = new SAPNode[polygons.Length * 2]; for (int index = 0; index < polygons.Length; ++index) { ShapeHelper.GetProjectedBounds(polygons[index], tangent, out min, out max); sapNodes[index * 2] = new SAPNode(min, true); sapNodes[(index * 2) + 1] = new SAPNode(max, false); } Array.Sort <SAPNode>(sapNodes, comparer); int depth = 0; Scalar result = 0; Scalar start = 0; for (int index = 0; index < sapNodes.Length; ++index) { SAPNode node = sapNodes[index]; if (node.begin) { if (depth == 0) { start = node.value; } depth++; } else { depth--; if (depth == 0) { result += node.value - start; } } } avg = (sapNodes[0].value + sapNodes[sapNodes.Length - 1].value) / 2; dragCenter = tangent * avg; dragArea = result; }
/// <summary> /// Creates a new Polygon Instance. /// </summary> /// <param name="vertexes">the vertexes that make up the shape of the Polygon</param> /// <param name="gridSpacing"> /// How large a grid cell is. Usualy you will want at least 2 cells between major vertexes. /// The smaller this is the better precision you get, but higher cost in memory. /// The larger the less precision and if it's to high collision detection may fail completely. /// </param> /// <param name="momentOfInertiaMultiplier"> /// How hard it is to turn the shape. Depending on the construtor in the /// Body this will be multiplied with the mass to determine the moment of inertia. /// </param> public PolygonShape(Vector2D[] vertexes, Scalar gridSpacing, Scalar momentOfInertiaMultiplier) : base(vertexes, momentOfInertiaMultiplier) { if (vertexes == null) { throw new ArgumentNullException("vertexes"); } if (vertexes.Length < 3) { throw new ArgumentException("too few", "vertexes"); } if (gridSpacing <= 0) { throw new ArgumentOutOfRangeException("gridSpacing"); } this.Normals = ShapeHelper.CalculateNormals(this.Vertexes); this.grid = new DistanceGrid(this, gridSpacing); }
DragInfo IExplosionAffectable.GetExplosionInfo(Matrix2x3 matrix, Scalar radius, GetTangentCallback callback) { Vector2D[] vertexes2 = new Vector2D[Vertexes.Length]; for (int index = 0; index < vertexes2.Length; ++index) { vertexes2[index] = matrix * Vertexes[index]; } Vector2D[] inter = ShapeHelper.GetIntersection(vertexes2, radius); if (inter.Length < 3) { return(null); } Vector2D centroid = PolygonShape.GetCentroid(inter); Vector2D tangent = callback(centroid); Scalar min, max; ShapeHelper.GetProjectedBounds(inter, tangent, out min, out max); Scalar avg = (max + min) / 2; return(new DragInfo(tangent * avg, max - min)); }
public static FluidInfo GetFluidInfo(Vector2D[] vertexes2, GetTangentCallback callback, Line line) { Vector2D centroid; Scalar area; Vector2D dragCenter; Scalar dragArea; Vector2D[] vertexes = ShapeHelper.GetIntersection(vertexes2, line); if (vertexes.Length < 3) { return(null); } centroid = PolygonShape.GetCentroid(vertexes); area = PolygonShape.GetArea(vertexes); Vector2D tangent = callback(centroid); Scalar min, max; ShapeHelper.GetProjectedBounds(vertexes, tangent, out min, out max); Scalar avg = (max + min) / 2; dragCenter = tangent * avg; dragArea = max - min; return(new FluidInfo(dragCenter, dragArea, centroid, area)); }
FluidInfo ILineFluidAffectable.GetFluidInfo(GetTangentCallback callback, Line line) { return(ShapeHelper.GetFluidInfo(Vertexes, callback, line)); }