Exemplo n.º 1
0
        Shape RecognizeBoxOrLines(DragState state, out bool potentialSelection)
        {
            // Okay so this is a rectangular recognizer that only sees things at
            // 45-degree angles.
            List <Section> sections1 = BreakIntoSections(state);
            List <Section> sections2 = new List <Section>(sections1);

            // Figure out if a box or a line string is a better interpretation
            EliminateTinySections(sections1, 10);
            LineOrArrow line  = InterpretAsPolyline(state, sections1);
            Shape       shape = line;

            // Conditions to detect a box:
            // 0. If both endpoints are anchored, a box cannot be formed.
            // continued below...
            EliminateTinySections(sections2, 10 + (int)(sections1.Sum(s => s.LengthPx) * 0.05));
            if (line.ToAnchor == null || line.FromAnchor == null || line.FromAnchor.Equals(line.ToAnchor))
            {
                shape = (Shape)TryInterpretAsBox(sections2, (line.FromAnchor ?? line.ToAnchor) != null, out potentialSelection) ?? line;
            }
            else
            {
                potentialSelection = false;
            }
            return(shape);
        }
Exemplo n.º 2
0
        private LineOrArrow InterpretAsPolyline(DragState state, List <Section> sections)
        {
            var shape = new LineOrArrow {
                Style = Control.LineStyle
            };

            shape.FromAnchor = state.StartAnchor;
            LineSegmentT prevLine = new LineSegmentT(), curLine;

            for (int i = 0; i < sections.Count; i++)
            {
                int angleMod8 = sections[i].AngleMod8;
                var startSS   = sections[i].StartSS;
                var endSS     = sections[i].EndSS;

                Vector <float> vector     = Mod8Vectors[angleMod8];
                Vector <float> perpVector = vector.Rot90();

                bool isStartLine = i == 0;
                bool isEndLine   = i == sections.Count - 1;
                if (isStartLine)
                {
                    if (shape.FromAnchor != null)
                    {
                        startSS = shape.FromAnchor.Point;
                    }
                }
                if (isEndLine)
                {
                    if ((shape.ToAnchor = Control.GetBestAnchor(endSS, angleMod8 + 4)) != null)
                    {
                        endSS = shape.ToAnchor.Point;
                    }
                    // Also consider forming a closed shape
                    else if (shape.Points.Count > 1 &&
                             shape.Points[0].Sub(endSS).Length() <= DiagramControl.AnchorSnapDistance &&
                             Math.Abs(vector.Cross(shape.Points[1].Sub(shape.Points[0]))) > 0.001f)
                    {
                        endSS = shape.Points[0];
                    }
                }

                if (isStartLine)
                {
                    curLine = startSS.To(startSS.Add(vector));
                }
                else
                {
                    curLine = endSS.Sub(vector).To(endSS);
                    PointT?itsc = prevLine.ComputeIntersection(curLine, LineType.Infinite);
                    if (itsc.HasValue)
                    {
                        startSS = itsc.Value;
                    }
                }

                shape.Points.Add(startSS);

                if (isEndLine)
                {
                    if (isStartLine)
                    {
                        Debug.Assert(shape.Points.Count == 1);
                        var adjustedStart = startSS.ProjectOntoInfiniteLine(endSS.Sub(vector).To(endSS));
                        var adjustedEnd   = endSS.ProjectOntoInfiniteLine(curLine);
                        if (shape.FromAnchor != null)
                        {
                            if (shape.ToAnchor != null)
                            {
                                // Both ends anchored => do nothing, allow unusual angle
                            }
                            else
                            {
                                // Adjust endpoint to maintain angle
                                endSS = adjustedEnd;
                            }
                        }
                        else
                        {
                            if (shape.ToAnchor != null)
                            {
                                // End anchored only => alter start point
                                shape.Points[0] = adjustedStart;
                            }
                            else
                            {
                                // Neither end anchored => use average line
                                shape.Points[0] = startSS.To(adjustedStart).Midpoint();
                                endSS           = endSS.To(adjustedEnd).Midpoint();
                            }
                        }
                    }
                    shape.Points.Add(endSS);
                }
                prevLine = curLine;
            }

            shape.FromArrow = Control.FromArrow;
            shape.ToArrow   = Control.ToArrow;

            return(shape);
        }
Exemplo n.º 3
0
		private LineOrArrow InterpretAsPolyline(DragState state, List<Section> sections)
		{
			var shape = new LineOrArrow { Style = Control.LineStyle };
			shape.FromAnchor = state.StartAnchor;
			LineSegmentT prevLine = new LineSegmentT(), curLine;

			for (int i = 0; i < sections.Count; i++)
			{
				int angleMod8 = sections[i].AngleMod8;
				var startSS = sections[i].StartSS;
				var endSS = sections[i].EndSS;

				Vector<float> vector = Mod8Vectors[angleMod8];
				Vector<float> perpVector = vector.Rot90();

				bool isStartLine = i == 0;
				bool isEndLine = i == sections.Count - 1;
				if (isStartLine)
				{
					if (shape.FromAnchor != null)
						startSS = shape.FromAnchor.Point;
				}
				if (isEndLine)
				{
					if ((shape.ToAnchor = Control.GetBestAnchor(endSS, angleMod8 + 4)) != null)
						endSS = shape.ToAnchor.Point;
					// Also consider forming a closed shape
					else if (shape.Points.Count > 1
						&& shape.Points[0].Sub(endSS).Length() <= DiagramControl.AnchorSnapDistance
						&& Math.Abs(vector.Cross(shape.Points[1].Sub(shape.Points[0]))) > 0.001f)
						endSS = shape.Points[0];
				}

				if (isStartLine)
					curLine = startSS.To(startSS.Add(vector));
				else
				{
					curLine = endSS.Sub(vector).To(endSS);
					PointT? itsc = prevLine.ComputeIntersection(curLine, LineType.Infinite);
					if (itsc.HasValue)
						startSS = itsc.Value;
				}

				shape.Points.Add(startSS);

				if (isEndLine)
				{
					if (isStartLine)
					{
						Debug.Assert(shape.Points.Count == 1);
						var adjustedStart = startSS.ProjectOntoInfiniteLine(endSS.Sub(vector).To(endSS));
						var adjustedEnd = endSS.ProjectOntoInfiniteLine(curLine);
						if (shape.FromAnchor != null)
						{
							if (shape.ToAnchor != null)
							{
								// Both ends anchored => do nothing, allow unusual angle
							}
							else
							{
								// Adjust endpoint to maintain angle
								endSS = adjustedEnd;
							}
						}
						else
						{
							if (shape.ToAnchor != null)
								// End anchored only => alter start point
								shape.Points[0] = adjustedStart;
							else
							{
								// Neither end anchored => use average line
								shape.Points[0] = startSS.To(adjustedStart).Midpoint();
								endSS = endSS.To(adjustedEnd).Midpoint();
							}
						}
					}
					shape.Points.Add(endSS);
				}
				prevLine = curLine;
			}

			shape.FromArrow = Control.FromArrow;
			shape.ToArrow = Control.ToArrow;

			return shape;
		}