This project is read-only.

New feature - split segment

Nov 19, 2010 at 6:21 AM

Hi Kirill,

I know there is a "join segments" (JointTwoSegmentsCreator.cs) command that removes a freepoint from a segment.  I always wondered why there wasn't a way to add a new freepoint to a polygon (or other shape).  I wrote this "SplitSegmentCreator.cs" class to do just that.  It only works on polygons and triangles.  I tested it vigourously and there are two conditions that are somewhat problematic. 

Condition 1:

1) Create three polygons that are joined by common points.
2) Select the "Split Segment" command (see code below)
3) Start selecting points on the different segments.
4) You'll eventually see that the colored area goes outside the bounds of the polygon.

Condition 2:

1) Create a square.
2) Select the "Split Segment" command (see code below)
3) Click on all sides.
4) Clicking one of the sides makes the whole thing collapse.

I've read your coding standards and I am still polishing up this code for submission to the project if you think it is worth adding.  I think it is, because, as a user I wondered why I couldn't change polygons after they were initially built.  I worked for several days trying to allow this same functionality for polylines ... but, it proved to be too problematic.  I got it to work in simple situations, but, things fell apart when the polyline got more complex.

Here is the class:

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Diagnostics;
using System.Collections;

namespace DynamicGeometry
{
    [Category(BehaviorCategories.Lines)]
    [Order(11)]
    public class SplitSegmentCreator : Behavior
    {
        public override void MouseDown(object sender, MouseButtonEventArgs e)
        {
            var coordinates = Coordinates(e);
            var segment = Drawing.Figures.HitTest<Segment>(coordinates);
            if (segment != null)
            {
                JoinSegments(segment, coordinates);
            }
        }

        void JoinSegments(Segment segment, Point coordinates)
        {
            var dependents = segment.Dependencies.OfType<FreePoint>().ToArray();
            if (dependents.Length != 2)
            {
                return;
            }

            FreePoint freePoint1 = dependents[0];           
            FreePoint freePoint2 = dependents[1];
            FreePoint freePointJoiner = Factory.CreateFreePoint(Drawing, coordinates);
            var newsegment1 = Factory.CreateSegment(Drawing, new[] { freePoint1, freePointJoiner });
            var newsegment2 = Factory.CreateSegment(Drawing, new[] { freePointJoiner, freePoint2 });

            using (Drawing.ActionManager.CreateTransaction())
            {
                Actions.Remove(segment);
                InsertPointToPolygons(freePoint1, freePointJoiner);
                Actions.Add(Drawing, freePointJoiner);
                Actions.Add(Drawing, newsegment1);
                Actions.Add(Drawing, newsegment2);
            }
        }

        void InsertPointToPolygons(FreePoint existingpoint, FreePoint newpoint)
        {
            foreach (var polygon in existingpoint.Dependents.OfType<PolygonBase>())
            {
                if (polygon.Dependencies.Count >= 3)
                {
                    InsertPointToPolygon(existingpoint, newpoint, polygon);
                }
            }
        }

        void InsertPointToPolygon(FreePoint existingpoint, FreePoint point, PolygonBase polygon)
        {
            int index = 0;
            foreach (IFigure ifigure in polygon.Dependencies)
            {
                if (ifigure.Name == existingpoint.Name)
                {
                    index++;
                    break;
                }
                else
                {
                    index++;
                }
            }
            Actions.InsertDependency(polygon, index, point);
        }

        public override string Name
        {
            get { return "Split segment"; }
        }

        public override string HintText
        {
            get
            {
                return "Click a segment to add a new point.";
            }
        }

        public override FrameworkElement CreateIcon()
        {
            return IconBuilder.BuildIcon()
                .Line(0.25, 0.75, 0.4, 0.4)
                .Line(0.4, 0.4, 0.75, 0.25)
                .Point(0.25, 0.75)
                .Point(0.75, 0.25)
                .Point(0.4, 0.4)
                .Canvas;
        }


    }
}