public double GetMinEpsilon(TPoint2D shortcutEnd, bool doExtremePointQueries)
        {
            double[] distances;

            if (doExtremePointQueries)
            {
                //O(4log n)
                distances = new []
                {
                    Geometry2D.Distance(shortcutStart, shortcutEnd, upper.ExtremePointFromShortcutLine(shortcutEnd)),
                    Geometry2D.Distance(shortcutStart, shortcutEnd, lower.ExtremePointFromShortcutLine(shortcutEnd)),
                    upper.ExtremeDistanceLeftOfShortcut(shortcutEnd),
                    lower.ExtremeDistanceLeftOfShortcut(shortcutEnd)
                };
            }
            else
            {
                //O(2log n)
                distances = new []
                {
                    upper.ExtremeDistanceLeftOfShortcut(shortcutEnd),
                    lower.ExtremeDistanceLeftOfShortcut(shortcutEnd)
                };
            }

            return(distances.Max());
        }
            public override bool AfterShortcut(TPoint2D start, TPoint2D end)
            {
                //break when this is the last iteration
                if (end.Index == Input.Trajectory.Count - 1 || end.Index == 0)
                {
                    return(false);
                }

                var prunedLevels = new HashSet <int>();

                foreach (var level in wedges.Keys)
                {
                    var wedge = wedges[level];
                    wedge.Intersect(end, Input.GetEpsilon(level));

                    if (wedge.IsEmpty)
                    {
                        prunedLevels.Add(level);
                    }
                }

                foreach (var level in prunedLevels)
                {
                    wedges.Remove(level);
                }

                return(wedges.Any());
            }
Example #3
0
        public double ShortcutNormal(TPoint2D shortcutEnd)
        {
            //point normal up for upper hull, and down for lower hull
            var leftNormal = ShortcutStart.X < shortcutEnd.X == IsUpper;

            return(Normal(ShortcutStart, shortcutEnd, leftNormal));
        }
 public override void Clear()
 {
     ShortcutSet = null;
     Source      = null;
     Targets     = new JHashSet <TPoint2D>();
     ShortcutSet = null;
 }
Example #5
0
        //calculates the normal of the two given points
        public double Normal(TPoint2D p1, TPoint2D p2, bool leftNormal)
        {
            var vec    = Vector2d.Subtract(p2.AsVector(), p1.AsVector());
            var normal = leftNormal ? vec.PerpendicularLeft : vec.PerpendicularRight;

            return(ConvertToHullAngle(Geometry2D.Angle(normal)));
        }
 public void RemovePoint(TPoint2D point)
 {
     foreach (var set in Shortcuts.Values)
     {
         set.Except(point);
     }
 }
        public Wedge(TPoint2D origin, double startAngle, double endAngle)
        {
            Origin = origin;

            StartAngle  = Geometry2D.SimplifyRadians(startAngle);
            EndAngle    = Geometry2D.SimplifyRadians(endAngle);
            IsFullPlane = false;
        }
 public SPFInput(Trajectory2D Trajectory, IShortcutSet ShortcutSet, TPoint2D Source, JHashSet <TPoint2D> Targets, bool CreatePath = true)
 {
     this.Trajectory  = Trajectory;
     this.ShortcutSet = ShortcutSet;
     this.Source      = Source;
     this.Targets     = Targets;
     this.CreatePath  = CreatePath;
 }
Example #9
0
        public LinkedList <Interval> GetIntervals(TPoint2D point)
        {
            if (IntervalMap.ContainsKey(point))
            {
                return(IntervalMap[point]);
            }

            return(new LinkedList <Interval>());
        }
            public override void OnNewShortcutStart(TPoint2D start)
            {
                wedges = new Dictionary <int, Wedge>();

                for (var level = 1; level <= Input.NumLevels; level++)
                {
                    wedges[level] = new Wedge(start);
                }
            }
Example #11
0
        //informally: find the point where the attached edges are most parallel to (shortcutStart, shortcutEnd)
        public TPoint2D ExtremePointFromShortcutLine(TPoint2D shortcutEnd)
        {
            var shortcutNormal = ShortcutNormal(shortcutEnd);

            //get furthest point
            TPoint2D point;

            Points.TryFind(p => NormalBSTPredicate(p, shortcutNormal), out point);
            return(point);
        }
Example #12
0
 public ConvexHullHalf(TPoint2D shortcutStart, bool upper, ISearchTree <TPoint2D> points)
 {
     IsUpper       = upper;
     ShortcutStart = shortcutStart;
     if (points != null)
     {
         Points = points;
         InitializePoints();
     }
 }
Example #13
0
        public static int BSTPointComparison(TPoint2D p1, TPoint2D p2)
        {
            if (p1.X < p2.X)
            {
                return(-1);
            }
            if (p1.X > p2.X)
            {
                return(1);
            }

            return(0);
        }
Example #14
0
        //worst case O(n^2), expected O(n)
        public void Except(TPoint2D point)
        {
            var index = point.Index;

            foreach (var start in IntervalMap.Keys)
            {
                if (start == point)
                {
                    continue;
                }

                var intervals = IntervalMap[start];

                var node = intervals.First;
                while (node != null)
                {
                    var nextNode = node.Next;

                    var interval   = node.Value;
                    var startIndex = interval.Start.Index;
                    var endIndex   = interval.End.Index;

                    if (startIndex == index && endIndex == index)
                    {
                        intervals.Remove(node);
                    }
                    else if (startIndex == index)
                    {
                        interval.Start = Trajectory[startIndex + 1];
                    }
                    else if (endIndex == index)
                    {
                        interval.End = Trajectory[endIndex - 1];
                    }
                    else if (startIndex < index && endIndex > index)
                    {
                        //second part
                        intervals.AddAfter(node, new Interval(Trajectory[startIndex + 1], interval.End));

                        //first part
                        interval.End = Trajectory[index - 1];
                    }

                    node = nextNode;
                }
            }


            IntervalMap.Remove(point);
        }
Example #15
0
        //ignores weight
        public void PrependShortcut(TPoint2D start, TPoint2D end)
        {
            var intervalList = IntervalMap[start];

            var firstInterval = intervalList.First?.Value;

            if (firstInterval != null && firstInterval.Start.Index == end.Index + 1)
            {
                firstInterval.Start = end;
            }
            else
            {
                intervalList.AddFirst(new Interval(end, end));
            }
        }
Example #16
0
        //ignores weight
        public void AppendShortcut(TPoint2D start, TPoint2D end)
        {
            var intervalList = IntervalMap[start];

            var lastInterval = intervalList.Last?.Value;

            if (lastInterval != null && lastInterval.End.Index == end.Index - 1)
            {
                lastInterval.End = end;
            }
            else
            {
                intervalList.AddLast(new Interval(end, end));
            }
        }
        protected void DrawPoint(TPoint2D point, double radius, int numSegments, Color color, int?name = null)
        {
            GL.PushMatrix();
            GL.Color3(color);

            GL.Translate(point.X, point.Y, 1f);

            if (name != null)
            {
                GL.LoadName((int)name);
            }

            GLUtil2D.DrawCircle(radius, numSegments);

            GL.PopMatrix();
        }
        public bool Contains(TPoint2D point)
        {
            if (IsFullPlane)
            {
                return(true);
            }

            var A = Vector2d.Add(Origin.AsVector(), new Vector2d(Math.Cos(StartAngle), Math.Sin(StartAngle)));
            var B = Vector2d.Add(Origin.AsVector(), new Vector2d(Math.Cos(EndAngle), Math.Sin(EndAngle)));

            var AC = Geometry2D.Orient(Origin.AsVector(), A, point.AsVector());
            var BC = Geometry2D.Orient(Origin.AsVector(), B, point.AsVector());

            //either orientation is opposite or on the line AB
            return(AC == 1 && BC == -1 || AC == 0 || BC == 0);
        }
Example #19
0
        public void RemovePoint(TPoint2D point)
        {
            var shortcutsToRemove = new HashSet <Shortcut>();

            foreach (var shortcut in MinLevels.Keys)
            {
                if (shortcut.Start == point || shortcut.End == point)
                {
                    shortcutsToRemove.Add(shortcut);
                }
            }

            foreach (var shortcut in shortcutsToRemove)
            {
                MinLevels.Remove(shortcut);
            }
        }
Example #20
0
        public void AppendInterval(TPoint2D start, int rangeStart, int rangeEnd)
        {
            var intervalList  = IntervalMap[start];
            var intervalStart = Trajectory[rangeStart];
            var intervalEnd   = Trajectory[rangeEnd];

            var lastInterval = intervalList.Last?.Value;

            if (lastInterval != null && lastInterval.End.Index == intervalStart.Index - 1)
            {
                lastInterval.End = intervalEnd;
            }
            else
            {
                intervalList.AddLast(new Interval(Trajectory[rangeStart], Trajectory[rangeEnd]));
            }
        }
Example #21
0
        private int RangeLeftOfShortcutLine(TPoint2D min, TPoint2D max, bool hullAngleCompliant, Vector2d lineStart, Vector2d lineEnd)
        {
            //find whether the start/end of the range represented by this subtree is to the left/right of this line
            var minOrientation = Geometry2D.Orient(lineStart, lineEnd, min.AsVector());
            var maxOrientation = Geometry2D.Orient(lineStart, lineEnd, max.AsVector());

            //if one end of the range on the line, include/exclude based on the other end of the range
            if (minOrientation == 0)
            {
                minOrientation = maxOrientation;
            }
            if (maxOrientation == 0)
            {
                maxOrientation = minOrientation;
            }

            if (maxOrientation == minOrientation)
            {
                //degenerate cases
                if (min.X <= ShortcutStart.X && max.X >= ShortcutStart.X)
                {
                    //range seems to be on the left of the line, but angle not compliant
                    if (!hullAngleCompliant && maxOrientation == 1)
                    {
                        return(0);
                    }

                    //range seems to be on the right of the line, but angle is compliant
                    if (hullAngleCompliant && maxOrientation == -1)
                    {
                        return(0);
                    }
                }

                //degenerate case: both ends of the range lie perfectly on the line
                if (maxOrientation == 0)
                {
                    return(hullAngleCompliant ? 1 : -1);
                }

                return(maxOrientation);
            }

            return(0);
        }
Example #22
0
        public void PrependInterval(TPoint2D start, int rangeStart, int rangeEnd)
        {
            var intervalList = IntervalMap[start];

            var intervalStart = Trajectory[rangeStart];
            var intervalEnd   = Trajectory[rangeEnd];

            var firstInterval = intervalList.First?.Value;

            if (firstInterval != null && firstInterval.Start.Index == intervalEnd.Index + 1)
            {
                firstInterval.Start = intervalStart;
            }
            else
            {
                intervalList.AddFirst(new Interval(Trajectory[rangeStart], Trajectory[rangeEnd]));
            }
        }
Example #23
0
        public override ShortcutPath FindShortestPath(IShortcutSet set, TPoint2D source, TPoint2D target, bool createPath = true)
        {
            var input = new SPFInput
            {
                Trajectory  = set.Trajectory,
                ShortcutSet = set,
                Source      = source,
                Targets     = new JHashSet <TPoint2D> {
                    target
                },
                CreatePath = createPath
            };

            SPFOutput output;

            algorithm.Compute(input, out output);

            return(output.GetPath(target));
        }
Example #24
0
        private void HandleMouseDown(object sender, MouseEventArgs e)
        {
            int pickId = Pick(e.X, e.Y);

            if (e.Button == MouseButtons.Left)
            {
                if (PickManager.PickingHit(pickId))
                { //clicked on point
                    lastSelectedPoint = (TPoint2D)PickManager.GetPickedObject(pickId);
                }
                else
                {  //clicked on empty space for new point
                    int index = input.Trajectory.IndexOf(lastSelectedPoint);

                    if (!input.Trajectory.Any())     //fresh trajectory
                    {
                        index = -1;
                    }
                    else if (index == -1)           //last selected point was removed
                    {
                        index = input.Trajectory.Count - 1;
                    }

                    var worldCoord = GetWorldCoordinates(e.X, e.Y);
                    var point      = input.Trajectory.InsertPoint(worldCoord.X, worldCoord.Y, index + 1);
                    PickManager.AssignPickId(point);

                    lastSelectedPoint = point;
                }

                draggingPoint = true;
            }
            else if (e.Button == MouseButtons.Right)
            {
                if (PickManager.PickingHit(pickId))
                {
                    //clicked on point
                    TPoint2D pointToBeRemoved = (TPoint2D)PickManager.GetPickedObject(pickId);
                    input.Trajectory.RemovePoint(pointToBeRemoved);
                }
            }
            Refresh();
        }
Example #25
0
        public EnhancedPoint ExtremePointLeftOfShortcut(TPoint2D shortcutEnd)
        {
            //construct line
            var startToEnd  = Vector2d.Subtract(shortcutEnd.AsVector(), ShortcutStart.AsVector());
            var normal      = startToEnd.PerpendicularLeft;
            var normalAngle = Geometry2D.Angle(normal);
            var lineStart   = ShortcutStart.AsVector();
            var lineEnd     = new Vector2d(ShortcutStart.X + Math.Cos(normalAngle), ShortcutStart.Y + Math.Sin(normalAngle));

            //determine whether the angle towards the left is properly facing upwards (upper hull), or downwards (lower hull)
            //used for degenerate case handling
            var angleTowardsLeft   = Geometry2D.Angle(-startToEnd.X, -startToEnd.Y);
            var hullAngle          = ConvertToHullAngle(angleTowardsLeft);
            var hullAngleCompliant = HullAngleCompliant(hullAngle);

            EnhancedPoint furthestPoint;

            Points.TryFindRangeData((min, max) => RangeLeftOfShortcutLine(min, max, hullAngleCompliant, lineStart, lineEnd), out furthestPoint);
            return(furthestPoint);
        }
Example #26
0
        //used to find which points to remove when updating convex hull
        private int UpdatePredicate(TPoint2D newPoint, TPoint2D point, bool start)
        {
            var leftOfPoint  = newPoint.X < point.X;
            var rightOfPoint = newPoint.X > point.X;

            if (start && leftOfPoint)
            {
                return(-1);
            }

            if (!start && rightOfPoint)
            {
                return(1);
            }

            var normalOnTheLeft = IsUpper && start || !IsUpper && !start;
            var normal          = Normal(point, newPoint, normalOnTheLeft);

            return(NormalBSTPredicate(point, normal));
        }
        public void Intersect(TPoint2D shortcutEnd, double epsilon)
        {
            //angle between shortcut line and epsilon circles
            var distance = Geometry2D.Distance(Origin, shortcutEnd);

            //if within epsilon circle, keep wedge and continue with next
            if (distance <= epsilon)
            {
                return;
            }

            //get angle of shortcut line with respect to the unit circle
            var worldAngle = Geometry2D.Angle(Origin, shortcutEnd);
            var wedgeAngle = Math.Asin(epsilon / distance);

            //build wedge
            var wedgeStart = Geometry2D.SubtractRadians(worldAngle, wedgeAngle);
            var wedgeEnd   = Geometry2D.SumRadians(worldAngle, wedgeAngle);
            var newWedge   = new Wedge(Origin, wedgeStart, wedgeEnd);

            //intersect wedge
            Intersect(newWedge);
        }
Example #28
0
        //returns whether to go left or right in the BST, given a certain point and certain target normal
        //informally this predicate aims to find the point whose adjacent edges e1, e2 have normals n1, n2 such that
        //n1 <= normal <= n2
        protected int NormalBSTPredicate(TPoint2D point, double normal)
        {
            TPoint2D leftNeighbor, rightNeighbor;

            Points.TryGetPredecessor(point, out leftNeighbor);
            Points.TryGetSuccessor(point, out rightNeighbor);

            //when at the start, pick left normal to point straight left
            var leftNormal = leftNeighbor != null?Normal(leftNeighbor, point, IsUpper) : ConvertToHullAngle(Math.PI);

            //when at the end, pick right normal to point straight right
            var rightNormal = rightNeighbor != null?Normal(point, rightNeighbor, IsUpper) : ConvertToHullAngle(0.0);

            var leftSign  = Math.Sign(IsUpper ? normal - rightNormal : rightNormal - normal);
            var rightSign = Math.Sign(IsUpper ? normal - leftNormal : leftNormal - normal);

            //point was found
            if (leftSign == -rightSign || leftSign == 0 || rightSign == 0)
            {
                return(0);
            }

            //go left
            if (leftSign == rightSign && leftSign == 1)
            {
                return(-1);
            }

            //go right
            if (leftSign == rightSign && leftSign == -1)
            {
                return(1);
            }

            throw new InvalidOperationException("Illegal case detected");
        }
Example #29
0
 public abstract Dictionary <TPoint2D, ShortcutPath> FindShortestPaths(IShortcutSet set, TPoint2D source, JHashSet <TPoint2D> targets, bool createPaths = true);
Example #30
0
 public abstract ShortcutPath FindShortestPath(IShortcutSet set, TPoint2D source, TPoint2D target, bool createPath = true);
Example #31
0
 public CalibrationPoint()
 {
     _img = new Vector2();
     _real = new Vector3();
     _realGridPos = new TPoint2D<int>(-1, -1);
 }
Example #32
0
 private void ComputeDistanceToNextPoint_Row(int x, int y, ref Vector2 d, out TPoint2D<int> fromPoint)
 {
     if(x > 1)
     {
         d = CalibGrid[y, x - 1].GravityCenter - CalibGrid[y, x - 2].GravityCenter;
         fromPoint = new TPoint2D<int>(y: y, x: x - 1);
     }
     else if(x == 1)
     {
         // Adding second in row -> use d from point 'above'
         d = CalibGrid[y - 1, x].GravityCenter - CalibGrid[y - 1, x - 1].GravityCenter;
         fromPoint = new TPoint2D<int>(y: y, x: x - 1);
     }
     else // x == 0
     {
         // Adding first in row -> move in y direction from 'above'
         d = CalibGrid[y - 1, x].GravityCenter - CalibGrid[y - 2, x].GravityCenter;
         fromPoint = new TPoint2D<int>(y: y - 1, x: x);
     }
 }
Example #33
0
 private void ComputeDistanceToNextPoint_Column(int x, int y, ref Vector2 d, out TPoint2D<int> fromPoint)
 {
     if(y > 1)
     {
         d = CalibGrid[y - 1, x].GravityCenter - CalibGrid[y - 2, x].GravityCenter;
         fromPoint = new TPoint2D<int>(y: y - 1, x: x);
     }
     else if(y == 1)
     {
         // Adding second in column -> use d from point on 'left'
         d = CalibGrid[y, x - 1].GravityCenter - CalibGrid[y - 1, x - 1].GravityCenter;
         fromPoint = new TPoint2D<int>(y: y - 1, x: x);
     }
     else //y == 0
     {
         // Adding first in column -> move in x direction on 'left'
         d = CalibGrid[y, x - 1].GravityCenter - CalibGrid[y, x - 2].GravityCenter;
         fromPoint = new TPoint2D<int>(y: y, x: x - 1);
     }
 }
Example #34
0
        private void ComputeEstimatedPoint(int x, int y, Vector2 d, TPoint2D<int> fromPoint, out Vector2 eP, out int minIndex, out double edx, out double edy)
        {
            eP = CalibGrid[fromPoint.Y, fromPoint.X].GravityCenter + d;
            minIndex = 0;
            double minDist = (CalibShapes[0].GravityCenter - eP).LengthSquared();
            for(int i = 0; i < CalibShapes.Count; ++i)
            {
                double dist = (CalibShapes[i].GravityCenter - eP).LengthSquared();
                if(minDist > dist)
                {
                    minDist = dist;
                    minIndex = i;
                }
            }

            edx = ((CalibShapes[minIndex].GravityCenter - eP) * AxisX).LengthSquared();
            edy = ((CalibShapes[minIndex].GravityCenter - eP) * AxisY).LengthSquared();
        }