Beispiel #1
0
        /// <summary>
        /// Checks if a node is inside a certain box. Considers HitTestRadius.
        /// </summary>
        /// <returns>True if the box intersects the elliptical shape of the node. Also true if box lies completely inside node.</returns>
        protected override bool IsInBox(IInputModeContext context, RectD rectangle, INode node)
        {
            // early exit if not even the bounds are contained in the box
            if (!base.IsInBox(context, rectangle, node))
            {
                return(false);
            }

            double eps = context.HitTestRadius;

            var outline = GetOutline(node);

            if (outline == null)
            {
                return(rectangle.Contains(node.Layout.ToRectD().TopLeft) && rectangle.Contains(node.Layout.ToRectD().BottomRight));
            }

            if (outline.Intersects(rectangle, eps))
            {
                return(true);
            }
            if (outline.PathContains(rectangle.TopLeft, eps) && outline.PathContains(rectangle.BottomRight, eps))
            {
                return(true);
            }
            return(rectangle.Contains(node.Layout.ToRectD().TopLeft) && rectangle.Contains(node.Layout.ToRectD().BottomRight));
        }
Beispiel #2
0
        /// <summary>
        /// Finds the child node of the <see cref="QuadTreeNode{TValue}"/> that contains the
        /// specified key.</summary>
        /// <param name="key">
        /// The key to locate. This argument must lie within <see cref="Bounds"/>.</param>
        /// <returns>
        /// The child of the <see cref="QuadTreeNode{TValue}"/> that contains <paramref
        /// name="key"/>, or a null reference if the child does not yet exist.</returns>
        /// <remarks>
        /// <b>FindChild</b> compares the specified <paramref name="key"/> to the <see
        /// cref="Center"/> point to determine the containing quadrant.</remarks>

        internal QuadTreeNode <TValue> FindChild(PointD key)
        {
            Debug.Assert(Bounds.Contains(key));

            double relX = key.X - Center.X;
            double relY = key.Y - Center.Y;

            return(relX < 0 ?
                   (relY < 0 ? _topLeft : _bottomLeft) :
                   (relY < 0 ? _topRight : _bottomRight));
        }
Beispiel #3
0
        protected override bool IsHit(IInputModeContext context, PointD location, INode node)
        {
            const double cornerRadius = 7;
            var          layout       = node.Layout;
            // Our shape is a rounded rectangle. Hits can appear in either of the following rectangles ...
            var rect1 = new RectD(layout.X, layout.Y + cornerRadius, layout.Width, layout.Height - 2 * cornerRadius);
            var rect2 = new RectD(layout.X + cornerRadius, layout.Y, layout.Width - 2 * cornerRadius, layout.Height);

            if (rect1.Contains(location, context.HitTestRadius) || rect2.Contains(location, context.HitTestRadius))
            {
                return(true);
            }
            // ... or in circle arcs around the corners
            var p1 = new PointD(layout.X + cornerRadius, layout.Y + cornerRadius);
            var p2 = new PointD(layout.X + layout.Width - cornerRadius, layout.Y + cornerRadius);
            var p3 = new PointD(layout.X + cornerRadius, layout.Y + layout.Height - cornerRadius);
            var p4 = new PointD(layout.X + layout.Width - cornerRadius, layout.Y + layout.Height - cornerRadius);

            if (location.DistanceTo(p1) < cornerRadius + context.HitTestRadius ||
                location.DistanceTo(p2) < cornerRadius + context.HitTestRadius ||
                location.DistanceTo(p3) < cornerRadius + context.HitTestRadius ||
                location.DistanceTo(p4) < cornerRadius + context.HitTestRadius)
            {
                return(true);
            }
            return(false);
        }
        private static void RandomPointsComparer(IPointDComparer comparer)
        {
            RectD bounds = new RectD(-100, -100, 200, 200);

            PointD[] points = GeoAlgorithms.RandomPoints(100, bounds, comparer, 2);

            for (int i = 0; i < points.Length; i++)
            {
                PointD p = points[i];
                Assert.IsTrue(bounds.Contains(p));
                if (i > 0)
                {
                    Assert.AreEqual(+1, comparer.Compare(p, points[i - 1]));
                }
                if (i < points.Length - 1)
                {
                    Assert.AreEqual(-1, comparer.Compare(p, points[i + 1]));
                }

                for (int j = 0; j < points.Length; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    double distance = p.Subtract(points[j]).LengthSquared;
                    Assert.GreaterOrEqual(distance, 4);
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Converts all <see cref="DelaunayEdges"/> to a planar <see cref="Subdivision"/>, using
        /// the specified clipping bounds.</summary>
        /// <param name="bounds">
        /// A <see cref="RectD"/> that indicates the clipping bounds for all <see
        /// cref="DelaunayEdges"/>.</param>
        /// <param name="addRegions">
        /// <c>true</c> to add all <see cref="VoronoiRegions"/> with the corresponding <see
        /// cref="GeneratorSites"/> to the <see cref="Subdivision.VertexRegions"/> collection of the
        /// new <see cref="Subdivision"/>; otherwise, <c>false</c>.</param>
        /// <returns>
        /// A new <see cref="Subdivision"/> whose <see cref="Subdivision.Edges"/> correspond to the
        /// <see cref="DelaunayEdges"/> of the <see cref="VoronoiResults"/>.</returns>
        /// <remarks><para>
        /// The specified <paramref name="bounds"/> determine the subset of <see
        /// cref="GeneratorSites"/> and <see cref="DelaunayEdges"/> that is stored in the new <see
        /// cref="Subdivision"/>, as described in <see cref="ClipDelaunayEdges"/>.
        /// </para><para>
        /// If <paramref name="addRegions"/> is <c>true</c>, the polygons added to the <see
        /// cref="Subdivision.VertexRegions"/> collection are also clipped the specified <paramref
        /// name="bounds"/>.</para></remarks>

        public Subdivision ToDelaunySubdivision(RectD bounds, bool addRegions = false)
        {
            LineD[]     edges    = ClipDelaunayEdges(bounds);
            Subdivision division = Subdivision.FromLines(edges);

            if (addRegions)
            {
                for (int i = 0; i < GeneratorSites.Length; i++)
                {
                    PointD site = GeneratorSites[i];
                    if (!bounds.Contains(site))
                    {
                        continue;
                    }

                    PointD[] region;
                    if (bounds.Intersect(VoronoiRegions[i], out region))
                    {
                        division.VertexRegions.Add(site, region);
                    }
                }
            }

            return(division);
        }
        public void RandomPoints()
        {
            RectD bounds = new RectD(-100, -100, 200, 200);

            PointD[] points = GeoAlgorithms.RandomPoints(100, bounds);
            foreach (PointD p in points)
            {
                Assert.IsTrue(bounds.Contains(p));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Clips the edge list for the Delaunay triangulation to the specified bounds.</summary>
        /// <param name="bounds">
        /// A <see cref="RectD"/> that indicates the clipping bounds for all <see
        /// cref="DelaunayEdges"/>.</param>
        /// <returns>
        /// An <see cref="Array"/> containing all <see cref="DelaunayEdges"/> which intersect the
        /// specified <paramref name="bounds"/>, as defined below.</returns>
        /// <remarks><para>
        /// <b>ClipDelaunayEdges</b> returns all <see cref="DelaunayEdges"/> whose corresponding
        /// <see cref="VoronoiEdges"/> element fulfils two conditions:
        /// </para><list type="bullet"><item>
        /// <see cref="VoronoiEdge.Site1"/> and <see cref="VoronoiEdge.Site2"/> both fall within the
        /// specified <paramref name="bounds"/>.
        /// </item><item>
        /// The line segment indicated by <see cref="VoronoiEdge.Vertex1"/> and <see
        /// cref="VoronoiEdge.Vertex2"/> intersects the specified <paramref name="bounds"/>.
        /// </item></list><para>
        /// In other words, <b>ClipDelaunayEdges</b> selects those <see cref="DelaunayEdges"/> that
        /// fall entirely within <paramref name="bounds"/>, and which connect two <see
        /// cref="VoronoiRegions"/> that share a common border within <paramref name="bounds"/>.
        /// </para></remarks>

        public LineD[] ClipDelaunayEdges(RectD bounds)
        {
            List <LineD> delaunayEdges = new List <LineD>(VoronoiEdges.Length);

            foreach (VoronoiEdge edge in VoronoiEdges)
            {
                PointD s1 = GeneratorSites[edge.Site1];
                PointD s2 = GeneratorSites[edge.Site2];

                if (bounds.Contains(s1) && bounds.Contains(s2))
                {
                    PointD v1 = VoronoiVertices[edge.Vertex1];
                    PointD v2 = VoronoiVertices[edge.Vertex2];

                    if (bounds.IntersectsWith(new LineD(v1, v2)))
                    {
                        delaunayEdges.Add(new LineD(s1, s2));
                    }
                }
            }

            return(delaunayEdges.ToArray());
        }
Beispiel #8
0
        public override void ChildrenHitTestCore(HitChain hitChain)
        {
            RectD bound = RenderVx.GetBounds();

            if (bound.Contains(hitChain.TestPoint.x, hitChain.TestPoint.y))
            {
                //check exact hit or the vxs part
                if (HitTestOnSubPart(RenderVx, hitChain.TextPointX, hitChain.TextPointY))
                {
                    hitChain.AddHitObject(this);
                }
            }

            base.ChildrenHitTestCore(hitChain);
        }
Beispiel #9
0
        /// <summary>
        /// Gets the layer at the given location.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <returns>A positive value if a specific layer is hit, a negative one to indicate that a new layer should
        /// be inserted before layer -(value + 1) - int.MaxValue if no layer has been hit.</returns>
        public int GetLayer(PointD location)
        {
            // global bounds
            var nbounds = new RectD(bounds.X, bounds.Y - LayerInsets, bounds.Width, bounds.Height + LayerInsets * 2);

            if (location.Y < bounds.Y)
            {
                // before the first layer
                return(-1);
            }
            if (location.Y > bounds.Bottom)
            {
                // after the last layer
                return(-((dividers.Count + 2) + 1));
            }
            // nothing found,
            if (!nbounds.Contains(location))
            {
                return(Int32.MaxValue);
            }

            // now search the layer
            double top = bounds.Top;

            int layerCount = 0;

            foreach (var divider in dividers)
            {
                var layerBounds = new RectD(bounds.X, top, bounds.Width, divider - top);
                if (layerBounds.Contains(location))
                {
                    return(GetLayerIndex(location, layerBounds, layerCount));
                }
                layerCount++;
                top = divider;
            }
            {
                var layerBounds = new RectD(bounds.X, top, bounds.Width, bounds.Bottom - top);
                if (layerBounds.Contains(location))
                {
                    return(GetLayerIndex(location, layerBounds, layerCount));
                }
            }
            // should not really happen...
            return(Int32.MaxValue);
        }
Beispiel #10
0
        public override void OnRender()
        {
            var item = Target as ItemDataControl;

            RefreshResources(item);

            if (imageTex == null)
            {
                return;
            }

            var rect = new RectD(new Vector2d(-0.5f * imageTex.width, -imageTex.height),
                                 new Vector2d(imageTex.width, imageTex.height));
            var adaptedRect = ComponentBasedEditor.Generic.ToRelative(rect.ToPoints()).ToRectD().ToRect();

            GUI.DrawTexture(adaptedRect, rect.Contains(Event.current.mousePosition.ToVector2d()) && imageOverTex ? imageOverTex : imageTex, ScaleMode.ScaleToFit);
        }
        protected override bool IsHit(IInputModeContext context, PointD location, INode node)
        {
            if (sns.Renderer.GetHitTestable(node, sns).IsHit(context, location))
            {
                return(true);
            }
            var layout = node.Layout.ToRectD();

            if (ShowTopMessage)
            {
                var cx          = layout.GetCenter().X;
                var topBoxSize  = BpmnConstants.MessageSize;
                var messageRect = new RectD(new PointD(cx - topBoxSize.Width / 2, layout.Y - MessageDistance - topBoxSize.Height), topBoxSize);
                if (messageRect.Contains(location, context.HitTestRadius))
                {
                    return(true);
                }
                if (Math.Abs(location.X - cx) < context.HitTestRadius && layout.Y - MessageDistance - context.HitTestRadius < location.Y && location.Y < layout.Y + context.HitTestRadius)
                {
                    return(true);
                }
            }

            if (ShowBottomMessage)
            {
                var bottomBoxSize = BpmnConstants.MessageSize;
                var cx            = layout.GetCenter().X;
                var messageRect   = new RectD(new PointD(cx - bottomBoxSize.Width / 2, layout.GetMaxY() + MessageDistance), bottomBoxSize);
                if (messageRect.Contains(location, context.HitTestRadius))
                {
                    return(true);
                }
                if (Math.Abs(location.X - cx) < context.HitTestRadius && layout.GetMaxY() - context.HitTestRadius < location.Y && location.Y < layout.GetMaxY() + MessageDistance + context.HitTestRadius)
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #12
0
            // the type of button which has been hit
            private HitInfo GetHitInfo(PointD location)
            {
                RectD layout    = node.Layout.ToRectD();
                var   classInfo = node.Tag as ClassInfo;

                PointD buttonLocation = layout.TopRight + new PointD(-ImageSize - 5, 5);
                RectD  buttonRect     = new RectD(buttonLocation, new SizeD(ImageSize, ImageSize));

                if (buttonRect.Contains(location))
                {
                    return(HitInfo.ToggleAllDetails);
                }
                double height = umlStyle.GetHeaderSize(classInfo).Height;

                if (IsButtonHit(location, height))
                {
                    return(HitInfo.ToggleFieldDetails);
                }
                if (classInfo != null)
                {
                    height += umlStyle.GetSectionSize(classInfo.Fields, "Fields").Height;
                }
                if (IsButtonHit(location, height))
                {
                    return(HitInfo.TogglePropertyDetails);
                }
                if (classInfo != null)
                {
                    height += umlStyle.GetSectionSize(classInfo.Properties, "Properties").Height;
                }

                if (IsButtonHit(location, height))
                {
                    return(HitInfo.ToggleMethodDetails);
                }
                return(HitInfo.None);
            }
Beispiel #13
0
        /// <summary>
        /// Finds all key-and-value pairs within the specified key range that are stored in the <see
        /// cref="QuadTreeNode{TValue}"/> or its child nodes.</summary>
        /// <param name="range">
        /// A <see cref="RectD"/> indicating the key range to search. This argument must intersect
        /// with <see cref="Bounds"/>, and it must be a square if <paramref name="useCircle"/> is
        /// <c>true</c>.</param>
        /// <param name="useCircle">
        /// <c>true</c> to search only the circle inscribed within <paramref name="range"/>;
        /// <c>false</c> to search the entire <paramref name="range"/>.</param>
        /// <param name="output">
        /// A <see cref="Dictionary{PointD, TValue}"/> to which any elements are added whose key
        /// lies within the specified <paramref name="range"/>.</param>

        internal void FindRange(ref RectD range, bool useCircle, Dictionary <PointD, TValue> output)
        {
            Debug.Assert(Bounds.IntersectsWith(range));

            if (_data != null)
            {
                if (useCircle)
                {
                    double radius = range.Width / 2;
                    double x = range.X + radius, y = range.Y + radius;

                    foreach (var pair in _data)
                    {
                        if (range.Contains(pair.Key))
                        {
                            double dx = pair.Key.X - x, dy = pair.Key.Y - y;
                            if (dx * dx + dy * dy <= radius * radius)
                            {
                                output.Add(pair.Key, pair.Value);
                            }
                        }
                    }
                }
                else
                {
                    foreach (var pair in _data)
                    {
                        if (range.Contains(pair.Key))
                        {
                            output.Add(pair.Key, pair.Value);
                        }
                    }
                }
                return;
            }

            bool topRange    = (range.Top < Center.Y);
            bool bottomRange = (range.Bottom >= Center.Y);
            bool leftRange   = (range.Left < Center.X);
            bool rightRange  = (range.Right >= Center.X);

            if (topRange)
            {
                if (leftRange && _topLeft != null)
                {
                    _topLeft.FindRange(ref range, useCircle, output);
                }
                if (rightRange && _topRight != null)
                {
                    _topRight.FindRange(ref range, useCircle, output);
                }
            }

            if (bottomRange)
            {
                if (leftRange && _bottomLeft != null)
                {
                    _bottomLeft.FindRange(ref range, useCircle, output);
                }
                if (rightRange && _bottomRight != null)
                {
                    _bottomRight.FindRange(ref range, useCircle, output);
                }
            }
        }
 public bool IsInBox(IInputModeContext context, RectD rectangle)
 {
     return(rectangle.Contains(this.rectangle.GetTopLeft()) && rectangle.Contains(this.rectangle.GetBottomRight()));
 }
Beispiel #15
0
        public void ContainsPoint()
        {
            Assert.IsTrue(rectD.Contains(rectD.TopLeft));
            Assert.IsTrue(rectD.Contains(rectD.TopRight));
            Assert.IsTrue(rectD.Contains(rectD.BottomLeft));
            Assert.IsTrue(rectD.Contains(rectD.BottomRight));
            Assert.IsTrue(rectD.Contains(3, 4));
            Assert.IsFalse(rectD.Contains(0, 1));

            Assert.IsTrue(rectF.Contains(rectF.TopLeft));
            Assert.IsTrue(rectF.Contains(rectF.TopRight));
            Assert.IsTrue(rectF.Contains(rectF.BottomLeft));
            Assert.IsTrue(rectF.Contains(rectF.BottomRight));
            Assert.IsTrue(rectF.Contains(3, 4));
            Assert.IsFalse(rectF.Contains(0, 1));

            Assert.IsTrue(rectI.Contains(rectI.TopLeft));
            Assert.IsFalse(rectI.Contains(rectI.TopRight));
            Assert.IsFalse(rectI.Contains(rectI.BottomLeft));
            Assert.IsFalse(rectI.Contains(rectI.BottomRight));
            Assert.IsTrue(rectI.Contains(3, 4));
            Assert.IsFalse(rectI.Contains(0, 1));
        }