public void FillPolygon(Color color1, Color color2, MyVector centerPoint, IMyPolygon polygon) { using (SolidBrush brush1 = new SolidBrush(color1)) { using (SolidBrush brush2 = new SolidBrush(color2)) { FillPolygon(brush1, brush2, centerPoint, polygon); } } }
public void FillPolygon(Brush brush1, Brush brush2, MyVector centerPoint, IMyPolygon polygon) { try { //TODO: sort the triangles by z // Children if (polygon.ChildPolygons != null) { foreach (IMyPolygon childPoly in polygon.ChildPolygons) { FillPolygon(brush1, brush2, centerPoint, childPoly); } } // Current if (polygon.Triangles != null) { Triangle[] cachedTriangles = polygon.Triangles; for (int triangleCntr = 0; triangleCntr < cachedTriangles.Length; triangleCntr++) { PointF[] points = new PointF[3]; points[0].X = PosWToV_X(cachedTriangles[triangleCntr].Vertex1.X + centerPoint.X); points[0].Y = PosWToV_Y(cachedTriangles[triangleCntr].Vertex1.Y + centerPoint.Y); points[1].X = PosWToV_X(cachedTriangles[triangleCntr].Vertex2.X + centerPoint.X); points[1].Y = PosWToV_Y(cachedTriangles[triangleCntr].Vertex2.Y + centerPoint.Y); points[2].X = PosWToV_X(cachedTriangles[triangleCntr].Vertex3.X + centerPoint.X); points[2].Y = PosWToV_Y(cachedTriangles[triangleCntr].Vertex3.Y + centerPoint.Y); if (triangleCntr % 2 == 0) { _graphics.FillPolygon(brush1, points); } else { _graphics.FillPolygon(brush2, points); } } } } catch (OverflowException) { // Oh well } }
/// <summary> /// This overload compares the sphere and polygon (no up front sphere/sphere check) /// </summary> public static MyVector[] IsIntersecting_SpherePolygon(Sphere sphere, MyVector polygonCenterPoint, IMyPolygon polygon) { List<MyVector> retVal = new List<MyVector>(); // See if I need to recurse on the polygon's children if (polygon.HasChildren) { #region Test Child Polys MyVector[] curCollisions; // Call myself for each of the child polys foreach (IMyPolygon childPoly in polygon.ChildPolygons) { curCollisions = IsIntersecting_SpherePolygon(sphere, polygonCenterPoint, childPoly); if (curCollisions != null) { retVal.AddRange(curCollisions); } } if (retVal.Count > 0) { return retVal.ToArray(); } else { return null; } #endregion } #region Test Edges // Compare the sphere with the edges MyVector curCollision; foreach (Triangle triangle in polygon.Triangles) { curCollision = CollisionHandler.IsIntersecting_SphereTriangle(sphere, polygonCenterPoint + triangle); if (curCollision != null) { retVal.Add(curCollision); } } if (retVal.Count > 0) { return retVal.ToArray(); } #endregion //TODO: collide the sphere with the interior of the poly // Exit Function return null; }
/// <summary> /// This overload will do a sphere/sphere check first, and if those intersect, then it will do the more /// expensive sphere/poly check /// </summary> /// <param name="polygonSphere">A sphere that totally surrounds the polygon</param> public static MyVector[] IsIntersecting_SpherePolygon(Sphere sphere, MyVector polygonCenterPoint, IMyPolygon polygon, Sphere polygonSphere) { // Do a sphere/sphere check first if (!CollisionHandler.IsIntersecting_SphereSphere_Bool(sphere, polygonSphere)) { return null; } // The spheres intersect. Now do the sphere/poly check return IsIntersecting_SpherePolygon(sphere, polygonCenterPoint, polygon); }
/* // It looks like his definition of a polygon is simply a list of vectors. It doesn't appear to be made of triangles, // but arbitrary sided faces. // // Actually, the more I think about it, I think is definition of a poly is strictly 2D. This should be replaced with // triangle //typedef std::vector<Vector3> poly_t; // This function should probably be moved to triangle (assuming it's not the same as GetClosestPointOnTriangle()) private bool PointInPoly(MyVector p, poly_t v, Vector n) { for (int i = 0; i < v.size(); i++) { if (Vector.Dot(p - v[i], Vector.Cross(n, v[(i + 1) % v.size()] - v[i]), false) < 0d) { return false; } } return true; } private Vector ClosestPointOnPlane(Vector p, Vector n, float d) { return p - (n * (Vector.Dot(p, n, false) - d)); } private Vector ClosestPointOnSegment(Vector p, Vector p1, Vector p2) { Vector dir = p2 - p1; Vector diff = p - p1; double t = Vector.Dot(diff, dir, false) / Vector.Dot(dir, dir, false); if (t <= 0.0f) { return p1; } else if (t >= 1.0f) { return p2; } return p1 + t * dir; } Vector3 ClosestPointOnPoly(const Vector3& p, const poly_t& v) { // Poly plane Vector3 n = Vector3::Normalize(Vector3::Cross(v[1] - v[0], v[2] - v[0])); float d = v[0].Dot(n); // Closest point on plane to p Vector3 closest = ClosestPointOnPlane(p, n, d); // If p is in the poly, we've found our closest point if (PointInPoly(closest, v, n)) return closest; // Else find the closest point to a poly edge bool found = false; float minDist; for (int i = 0; i < v.size(); ++i) { Vector3 temp = ClosestPointOnSegment(p, v[i], v[(i + 1) % v.size()]); float dist = Vector3::LengthSquared(p - temp); if (!found || dist < minDist) { found = true; minDist = dist; closest = temp; } } return closest; } bool IntersectSpherePoly(const Vector3& c, float r, const poly_t& poly, Vector3& n, float& d) { Vector3 p = ClosestPointOnPoly(c, poly); n = c - p; float dist = n.LengthSquared(); if (dist > r * r) return false; dist = Math::Sqrt(dist); n /= dist; d = r - dist; return true; } */ #endregion public static MyVector[] TestCollision(out MyVector trueCollision, Sphere sphere, MyVector polygonCenterPoint, IMyPolygon polygon, Sphere polygonSphere) { MyVector[] retVal = IsIntersecting_SpherePolygon(sphere, polygonCenterPoint, polygon, polygonSphere); if (retVal == null) { trueCollision = null; return null; } // Find the closest point double minDist = double.MaxValue; int minDistIndex = -1; for (int returnCntr = 0; returnCntr < retVal.Length; returnCntr++) { double curDist = Utility3D.GetDistance3D(sphere.Position, retVal[returnCntr]); if (curDist < minDist) { minDist = curDist; minDistIndex = returnCntr; } } trueCollision = retVal[minDistIndex]; return retVal; }