/// <summary>
        /// Populates a junction with clutter, bonuses, and other
        /// stuff.
        /// </summary>
        public void Create(Segment segment)
        {
            // Basically create a random number of modules and place
            // them in the stage.
            MersenneRandom random = segment.ParentJunction.Random;
            Junction junction = segment.ChildJunction;
            int moduleCount = junction.Random.Next(0, 40);

            for (int i = 0; i < moduleCount; i++)
            {
                // Find a random vertex and basically center it
                // somewhere along the line between the center and the
                // vertex.
                int pointCount = junction.InternalShape.PointCount;
                int pointIndex = random.Next(0, pointCount);
                float x = (float) junction.InternalShape.GetX(pointIndex);
                float y = (float) junction.InternalShape.GetY(pointIndex);

                // We get a place in the middle, but not too
                // close. Since the junction center is always at (0,
                // 0), this simplifies finding the point.
                float weight = random.NextSingle(0.1f, 0.9f);
                float cx = x * weight;
                float cy = y * weight;

                // Create the mobile
                Create(segment, random, cx, cy);
            }
        }
        /// <summary>
        /// Creates a random mobile object at the given location.
        /// </summary>
        private void Create(
			Segment segment, MersenneRandom random, float x, float y)
        {
            // Figure out the type
            Mobile m = new HousingBubble();
            int pick = random.Next(10);

            if (pick == 0)
                m = new ContainmentModule();
            else if (pick < 5)
                m = new EngineModule();

            // Create a housing bubble
            PointF p = segment.ChildJunctionPoint;
            m.Point = new PointF(p.X + x, p.Y + y);
            m.Radius = random.NextSingle(5, 20);

            // Add it
            segment.ParentJunction.Mobiles.Add(m);
        }
Example #3
0
        /// <summary>
        /// Creates a new segment with the ends swapped and the
        /// polygons reversed.
        /// </summary>
        public Segment Swap()
        {
            // Create a new segment
            Segment s = new Segment();
            s.child = parent;
            s.parent = child;
            s.ChildJunctionPoint = new PointF(
                -ChildJunctionPoint.X,
                -ChildJunctionPoint.Y);

            // Reverse the relative coordinates of the segment
            double dx = -ChildJunctionPoint.X;
            double dy = -ChildJunctionPoint.Y;

            // Shift the polygon over as appropriate
            s.internalShape = internalShape.Translate(dx, dy);

            // Reverse the center lines
            foreach (CenterPoint cp in centerPoints)
            {
                s.centerPoints.Add(
                    new CenterPoint((float) dx + cp.X, (float) dy + cp.Y));
            }

            // Return the results
            return s;
        }
        /// <summary>
        /// Creates a segment from a child junction to its parent.
        /// </summary>
        public Segment Create(
			Junction child, PointF childPoint, double distance)
        {
            // Sanity checking
            if (child.ParentJunction == null)
                throw new Exception("Cannot generate with a null parent");

            // Get the distance between the two points
            Segment segment = new Segment();
            Junction parent = child.ParentJunction;

            // Add the two end points
            CenterPointList points = new CenterPointList();
            points.Add(new CenterPoint(0, 0));
            points.Add(new CenterPoint(childPoint));

            // Split apart the line
            #if DEBUG
            Stopwatch stopwatch = Stopwatch.StartNew();
            #endif

            // Stagger (fractalize) the points
            Geometry.StaggerPoints(points, parent.Random,
                Constants.MinimumSegmentDistance,
                Constants.StaggerSegmentPasses);

            #if DEBUG
            // Show timing information
            stopwatch.Stop();
            Log.Debug("Fractal Time: {0}", stopwatch.Elapsed);
            stopwatch.Reset();
            stopwatch.Start();
            #endif

            // Once we generated a set of center points, we go through
            // and add a randomly-sized and angled square to each
            // point, unioning the results to get the shape of the
            // entire segment.
            IPoly shape = null;
            float log = 0;

            if (distance > 0)
                log = (float) Math.Log(distance) * 10;

            foreach (CenterPoint point in points)
            {
                // Keep track of our retries
                int retry = 1;

                while (true)
                {
                    // Create a shape
                    IPoly p = Geometry.CreateShape(parent, point.Point,
                        retry * (Constants.SegmentAverageWidth - log));

                    // If we have no shape, this is automatically
                    // included.
                    if (shape == null)
                    {
                        shape = p;
                        break;
                    }

                    // We have another shape, so we want to build up
                    // an intersection to make sure they are touching.
                    if (!shape.HasIntersection(p))
                    {
                        // If there is no intersection, then we need
                        // to try again and make the radius range larger.
                        retry++;
                        continue;
                    }

                    // Make a union of the two shapes
                    IPoly union = shape.Union(p);

                    // See if we have two shapes
                    if (union.InnerPolygonCount > 1)
                    {
                        // We didn't quite reach each other
                        retry++;
                        continue;
                    }

                    // Set the new shape
                    shape = union;
                    break;
                }
            }

            // Remove both junction shapes from this
            //shape = shape.Difference(parent.InternalShape);
            //shape = shape.Difference(child.InternalShape);

            #if DEBUG
            // Show timing information
            stopwatch.Stop();
            Log.Debug("  Shape Time: {0}", stopwatch.Elapsed);
            stopwatch.Reset();
            stopwatch.Start();
            #endif

            // Add the shape to the list
            segment.InternalShape = shape;

            // Set up the center line and optimize it
            segment.CenterPoints.AddAll(points);
            segment.CenterPoints.Optimize();

            #if DEBUG
            // Show timing information
            stopwatch.Stop();
            Log.Debug("Optimze Time: {0}", stopwatch.Elapsed);
            #endif

            // Return the results
            return segment;
        }
Example #5
0
        /// <summary>
        /// Returns true if the segment overlaps with the current list.
        /// </summary>
        private bool CheckOverlapIntersection(
			IList<IPoly> overlaps, Segment segment)
        {
            // First build up the overlap test shape
            IPoly newShape = segment.ChildJunction.InternalShape
                .Translate(
                    segment.ChildJunctionPoint.X,
                    segment.ChildJunctionPoint.Y)
                .Union(segment.InternalShape);

            // Now check for an intersection with all the overlaps
            foreach (IPoly overlap in overlaps)
            {
                // If we intersect, then there is an overlap
                if (overlap.HasIntersection(newShape))
                    return true;
            }

            // Store the circle that represents this junction to
            // prevent anything from getting too close.
            IPoly circleTest = Geometry.CreateCircle(
                segment.ChildJunctionPoint,
                Constants.OverlapConnectionDistance);
            //IPoly toRemove = newShape.Intersection(circleTest);
            overlaps.Add(circleTest); //newShape.Xor(toRemove));

            // No intersections, so return false
            return false;
        }
        /// <summary>
        /// Renders out the segment between two junctions.
        /// </summary>
        private void RenderSegment(Context g, Segment segment)
        {
            // Get the shape we need to draw and draw it
            IPoly poly = segment.InternalShape;

            if (poly != null)
            {
                // Go through the points and draw with a fill
                RenderPolygon(g,
                    poly,
                    PointF.Empty,
                    new Color(0, 0, 0.5f));

                double color = 1;

                for (int i = 1; i < poly.InnerPolygonCount; i++)
                {
                    RenderPolygon(g,
                        poly.GetInnerPoly(i),
                        PointF.Empty,
                        new Color(color, 0, 0.5f));
                    color /= 1.5;
                }
            }

            // Draw the center points
            foreach (CenterPoint point in segment.CenterPoints)
                RenderSegmentHandle(g, point);
        }