Пример #1
0
        static Vector3 RandomPointOutsideShape <T>(IShapeOps <T> h, T obj, Random random)
        {
            Vector3 p1 = h.RandomInteriorPoint(random);
            Vector3 p2 = h.RandomInteriorPoint(random);

            for (; ;)
            {
                // move p2 on a line away from p1 until it's outside
                p2 = p1 + (p2 - p1) * 1.1f;
                if (!h.ContainsPoint(p2))
                {
                    return(p2);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Test containment and intersection between randomly created shapes of type T1 and T2.
        /// </summary>
        void TestRandomObjects <T1, T2>(Random random, IShapeOps <T1> h1, IShapeOps <T2> h2, Func <T1, T2, ContainmentType> contains, Func <T1, T2, bool> intersects)
        {
            // Create a random shape of each type
            h1.CreateRandomShape(random, (float)Math.Exp(random.NextDouble() * 4 - 2));
            h2.CreateRandomShape(random, (float)Math.Exp(random.NextDouble() * 4 - 2));

            // First ensure that the shapes are intersecting (or one is inside the other), by picking a point within each
            // and translating so they coincide.
            Vector3 p1 = h1.RandomInteriorPoint(random);
            Vector3 p2 = h2.RandomInteriorPoint(random);

            h2.Translate(p1 - p2);
            Check("Contains", h1, h2, contains, c => c != ContainmentType.Disjoint);
            Check("Intersects", h1, h2, intersects);

            // Next ensure that shape2 is intersecting (not contained or disjoint), by picking another point
            // in shape2, and scaling around p1 until the new point is outside of shape1.
            p2 = h2.RandomInteriorPoint(random);
            while (h1.ContainsPoint(p2))
            {
                p2 = p1 + (p2 - p1) * 1.1f;
                h2.Translate(-p1);
                h2.Scale(1.1f);
                h2.Translate(p1);
            }
            Check("surface Intersects", h1, h2, contains, c => c == ContainmentType.Intersects);
            Check("Intersects", h1, h2, intersects);

            // Ensure that shape2 is fully contained within shape1 by scaling it down
            // around a point in shape1, until its hull is inside shape1
            for (; ;)
            {
                Vector3[] hull      = h2.GetHull();
                bool      allInside = true;
                foreach (Vector3 point in hull)
                {
                    if (!h1.ContainsPoint(point))
                    {
                        allInside = false;
                        break;
                    }
                }
                if (allInside)
                {
                    break;
                }

                p1 = h1.RandomInteriorPoint(random);
                h2.Translate(-p1);
                h2.Scale(0.9f);
                h2.Translate(p1);
            }

            // Ensure that shape2 is fully disjoint from shape1 by picking a random plane and
            // translating the shapes to opposite sides of it
            Plane plane;

            plane.Normal = Vector3.Normalize(random.PointInSphere());
            plane.D      = (float)(random.NextDouble() * 2 - 1) * 100;

            h1.Translate((-h1.MinimumDistanceFromPlane(plane) + .001f) * plane.Normal);
            plane.D      = -plane.D;
            plane.Normal = -plane.Normal;
            h2.Translate((-h2.MinimumDistanceFromPlane(plane) + .001f) * plane.Normal);

            Check("Disjoint", h1, h2, contains, c => c == ContainmentType.Disjoint);
            Check("!Intersects", h1, h2, intersects, r => !r);
        }