Пример #1
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            LineSegment edge = Edge(0);

            if (edge.SeparatingAxisForOrientedRectangle(orientedRectangle))
            {
                return false;
            }

            edge = Edge(1);
            if (edge.SeparatingAxisForOrientedRectangle(orientedRectangle))
            {
                return false;
            }

            edge = orientedRectangle.Edge(0);

            if (edge.SeparatingAxisForOrientedRectangle(this))
            {
                return false;
            }

            edge = orientedRectangle.Edge(1);

            return !edge.SeparatingAxisForOrientedRectangle(this);
        }
        /// <summary>
        /// For the given parameter, calculate the actual geometry of the specified label in absolute world coordinates.
        /// </summary>
        /// <remarks>The actual position is calculated from the <see cref="MyNodeLabelModelParameter.Ratio"/> specified in the parameter as
        /// the counterclock-wise angle on the label owner's circumference. Note that we also rotate the label layout itself accordingly.</remarks>
        public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter)
        {
            var modelParameter = parameter as MyNodeLabelModelParameter;
            var ownerNode      = label.Owner as INode;

            if (modelParameter != null && ownerNode != null)
            {
                //If we have a matching parameter and a node as owner, calculate the angle for the label position and the matchin rotation of the label layout box itself.
                var               center = ownerNode.Layout.GetCenter();
                var               radius = Math.Max(ownerNode.Layout.Width, ownerNode.Layout.Height) * 0.5d;
                var               ratio  = modelParameter.Ratio;
                double            angle  = ratio * Math.PI * 2;
                double            x      = Math.Sin(angle);
                double            y      = Math.Cos(angle);
                PointD            up     = new PointD(-y, x);
                OrientedRectangle result = new OrientedRectangle();
                result.SetUpVector(up);
                result.Size = label.PreferredSize;
                result.SetCenter(center + (offset + radius + label.PreferredSize.Height * 0.5d) * up);
                return(result);
            }
            else
            {
                return(OrientedRectangle.Empty);
            }
        }
 /// <summary>
 /// Creates a new instance with the given layout.
 /// </summary>
 public CachingOrientedRectangle(RectD layout)
 {
     upVector           = new PointD(0, -1);
     angle              = 0.0;
     cachedLayout       = layout;
     cachedOrientedRect = new OrientedRectangle(cachedLayout);
 }
Пример #4
0
        /// <summary>
        /// Converts the given <see cref="OrientedRectangle"/> from the world into the view coordinate space.
        /// </summary>
        internal static void WorldToIntermediateCoordinates(ICanvasContext context, OrientedRectangle rect)
        {
            var anchor      = new PointD(rect.Anchor);
            var anchorAndUp = anchor + rect.GetUp();

            var renderContext = context as IRenderContext ?? context.Lookup(typeof(IRenderContext)) as IRenderContext;

            if (renderContext != null)
            {
                anchor      = renderContext.WorldToIntermediateCoordinates(anchor);
                anchorAndUp = renderContext.WorldToIntermediateCoordinates(anchorAndUp);
            }
            else
            {
                var cc = context.Lookup(typeof(CanvasControl)) as CanvasControl;
                if (cc != null)
                {
                    anchor      = cc.WorldToIntermediateCoordinates(anchor);
                    anchorAndUp = cc.WorldToIntermediateCoordinates(anchorAndUp);
                }
                else
                {
                    // too bad - infer trivial scale matrix
                    anchor      *= context.Zoom;
                    anchorAndUp *= context.Zoom;
                }
            }

            rect.SetUpVector((anchorAndUp - anchor).Normalized);
            rect.SetAnchor(anchor);
            rect.Width  *= context.Zoom;
            rect.Height *= context.Zoom;
        }
Пример #5
0
        /// <inheritdoc/>
        public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter)
        {
            OrientedRectangle rect = new OrientedRectangle(0, 0, 10, 10);

            ((RatioParameter)parameter).SetGeometry(this, label, rect);
            return(rect);
        }
Пример #6
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            var edge = this.Edge(0);

            if (orientedRectangle.IsSeparatingAxis(edge))
            {
                return(false);
            }

            edge = this.Edge(1);
            if (orientedRectangle.IsSeparatingAxis(edge))
            {
                return(false);
            }

            edge = orientedRectangle.Edge(0);
            if (this.IsSeparatingAxis(edge))
            {
                return(false);
            }

            edge = orientedRectangle.Edge(1);
            if (this.IsSeparatingAxis(edge))
            {
                return(false);
            }

            return(true);
        }
        public void TransformPoint()
        {
            var obb        = new OrientedRectangle(Vector2.One, Vector2.Zero, MathF.PI / 2);
            var worldPoint = new Vector2(2, 0);

            var localPoint = obb.TransformPoint(worldPoint);

            Assert.That(localPoint, Is.Approximately(new Vector2(1, 3)));
        }
        public void ClosestPoint()
        {
            var obb        = new OrientedRectangle(Vector2.One, Vector2.One * 0.5f, MathF.PI / 2);
            var worldPoint = new Vector2(13, -13);

            var closestPoint = obb.ClosestPointWorld(worldPoint);

            Assert.That(closestPoint, Is.Approximately(new Vector2(1.5f, 0.5f)));
        }
        public void RectCircle_NotCollide()
        {
            var a = new OrientedRectangle(Vector2.Zero, Vector2.One * 0.5f, MathF.PI / 4);
            var b = new Circle(new Vector2(1, 1), 0.5f);

            CollisionSolver.CalculateCollisionFeatures(in a, in b, 1, out var results);

            Assert.That(results.Collided, Is.EqualTo(false));
        }
Пример #10
0
 public RotatedNodeResizeHandle(HandlePositions position, INode node, IReshapeHandler reshapeHandler, bool symmetricResize)
 {
     this.position        = position;
     this.node            = node;
     this.reshapeHandler  = reshapeHandler;
     this.symmetricResize = symmetricResize;
     portHandles          = new List <IHandle>();
     initialLayout        = new OrientedRectangle(GetNodeBasedOrientedRectangle());
 }
Пример #11
0
 public static void Set(this OrientedRectangle mutable, IOrientedRectangle r)
 {
     mutable.AnchorX = r.AnchorX;
     mutable.AnchorY = r.AnchorY;
     mutable.Width   = r.Width;
     mutable.Height  = r.Height;
     mutable.UpX     = r.UpX;
     mutable.UpY     = r.UpY;
 }
Пример #12
0
        public void TransformPointRoundTrip()
        {
            var obb        = new OrientedRectangle(new Vector2(3, 5), Vector2.Zero, MathF.PI / 4);
            var worldPoint = new Vector2(11, 13);

            var localPoint = obb.InverseTransformPoint(worldPoint);
            var result     = obb.TransformPoint(localPoint);

            Assert.That(result, Is.EqualTo(worldPoint));
        }
Пример #13
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            var r        = new Rectangle(new Vector(0, 0), orientedRectangle.HalfExtent.MultiplyBy(2));
            var c        = new Circle(new Vector(0, 0), this.Radius);
            var distance = this.Center.Subtract(orientedRectangle.Center);

            c.Center = distance.Add(orientedRectangle.HalfExtent);

            return(c.CollidesWith(r));
        }
Пример #14
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            Rectangle localRectangle = orientedRectangle.TransformToLocalRectangle();

            IVector2D lp = Position.Substract(orientedRectangle.Center);
            lp = lp.Rotate(-orientedRectangle.Rotation);
            lp = lp.Add(orientedRectangle.HalfExtend);
            var localPoint = new Point(lp);

            return localPoint.CollidesWith(localRectangle);
        }
Пример #15
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            Rectangle lr = orientedRectangle.TransformToLocalRectangle();

            IVector2D basee = Base.Substract(orientedRectangle.Center);
            basee = basee.Rotate(-orientedRectangle.Rotation);
            basee = basee.Add(orientedRectangle.HalfExtend);
            IVector2D direction = Direction.Rotate(-orientedRectangle.Rotation);
            var line = new Line(basee, direction);

            return line.CollidesWith(lr);
        }
Пример #16
0
        /// <summary>
        /// Returns whether or not the given node is inside the rectangle.
        /// </summary>
        protected override bool IsInBox(IInputModeContext context, RectD rectangle, INode node)
        {
            var nodeOrientedRect = GetRotatedLayout(node);

            // Create an oriented rectangle with the size of the wrapped bounds and the location and rotation of the node
            var wrappedBounds     = Wrapped.Renderer.GetBoundsProvider(node, Wrapped).GetBounds(context);
            var orientedRectangle = new OrientedRectangle(0, 0, wrappedBounds.Width, wrappedBounds.Height,
                                                          nodeOrientedRect.UpX, nodeOrientedRect.UpY);

            orientedRectangle.SetCenter(node.Layout.GetCenter());

            return(rectangle.Intersects(orientedRectangle, 0.01));
        }
Пример #17
0
        public void ORectCircle_Collide()
        {
            var a = new OrientedRectangle(Vector2.Zero, new Vector2(3, 1), MathF.PI / 2);
            var b = new Circle(new Vector2(1.5f, 0), 1f);

            CollisionSolver.CalculateCollisionFeatures(in a, in b, false, out var results);

            Assert.AreEqual(true, results.Collided);
            Assert.That(results.Normal, Is.Approximately(Vector2.UnitX));
            Assert.AreEqual(0.5f / 2, results.Penetration);
            Assert.IsNotNull(results.Contacts);
            Assert.AreEqual(1, results.Contacts.Length);
            Assert.That(results.Contacts[0], Is.Approximately(new Vector2(0.75f, 0)));
        }
Пример #18
0
        public void RectCircle_Collide()
        {
            var a = new OrientedRectangle(Vector2.Zero, new Vector2(3, 1), MathF.PI / 2);
            var b = new Circle(new Vector2(1.5f, 0), 1f);

            CollisionSolver.CalculateCollisionFeatures(in a, in b, 1, out var results);

            Assert.That(results.Collided);
            Assert.That(results.Normal, Is.Approximately(Vector2.UnitX));
            Assert.That(results.Penetration, Is.EqualTo(0.5f / 2));
            Assert.That(results.Contacts, Is.Not.Null);
            Assert.That(results.Contacts.Length, Is.EqualTo(1));
            Assert.That(results.Contacts[0], Is.Approximately(new Vector2(0.75f, 0)));
        }
Пример #19
0
        /// <summary>
        /// Returns bounds based on the size provided by the wrapped style and the location and rotation of the node.
        /// </summary>
        protected override RectD GetBounds(ICanvasContext context, INode node)
        {
            var nodeOrientedRect = GetRotatedLayout(node);

            // Create an oriented rectangle with the size of the wrapped bounds and the location and rotation of the node
            var wrappedBounds = Wrapped.Renderer.GetBoundsProvider(node, Wrapped).GetBounds(context);

            var orientedRectangle = new OrientedRectangle(0, 0, wrappedBounds.Width, wrappedBounds.Height,
                                                          nodeOrientedRect.UpX, nodeOrientedRect.UpY);

            orientedRectangle.SetCenter(node.Layout.GetCenter());

            return(orientedRectangle.GetBounds());
        }
Пример #20
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            Rectangle lr = orientedRectangle.TransformToLocalRectangle();

            IVector2D point1 = Point1.Substract(orientedRectangle.Center);
            point1 = point1.Rotate(-orientedRectangle.Rotation);
            point1 = point1.Add(orientedRectangle.HalfExtend);

            IVector2D point2 = Point2.Substract(orientedRectangle.Center);
            point2 = point2.Rotate(-orientedRectangle.Rotation);
            point2 = point2.Add(orientedRectangle.HalfExtend);

            var ls = new LineSegment(point1, point2);

            return lr.CollidesWith(ls);
        }
Пример #21
0
        /// <summary>
        /// Sets the original node bounds according to the given anchor location and size.
        /// </summary>
        private RectD SetNodeLocationAndSize(IInputModeContext inputModeContext, PointD anchor, SizeD size)
        {
            var graph = inputModeContext.GetGraph();

            if (graph == null)
            {
                return(RectD.Empty);
            }
            var orientedRectangle = new OrientedRectangle(anchor.X, anchor.Y, size.Width, size.Height,
                                                          initialLayout.UpX, initialLayout.UpY);
            var center = orientedRectangle.GetCenter();

            var layout = RectD.FromCenter(center, size);

            graph.SetNodeLayout(node, layout);
            return(layout);
        }
        public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter)
        {
            var   php   = parameter as PoolHeaderParameter;
            INode owner = (INode)label.Owner;

            if (php == null || owner == null)
            {
                return(null);
            }

            ITable  table  = owner.Lookup <ITable>();
            InsetsD insets = table != null && table.Insets != InsetsD.Empty ? table.Insets : new InsetsD(0);

            var orientedRectangle = new OrientedRectangle();

            orientedRectangle.Resize(label.PreferredSize);
            switch (php.Side)
            {
            case 0: // North
                orientedRectangle.SetUpVector(0, -1);
                orientedRectangle.SetCenter(new PointD(owner.Layout.X + owner.Layout.Width / 2, owner.Layout.Y + insets.Top / 2));
                break;

            case 1: // East
                orientedRectangle.SetUpVector(1, 0);
                orientedRectangle.SetCenter(new PointD(owner.Layout.GetMaxX() - insets.Right / 2, owner.Layout.Y + owner.Layout.Height / 2));
                break;

            case 2: // South
                orientedRectangle.SetUpVector(0, -1);
                orientedRectangle.SetCenter(new PointD(owner.Layout.X + owner.Layout.Width / 2, owner.Layout.GetMaxY() - insets.Bottom / 2));
                break;

            case 3: // West
            default:
                orientedRectangle.SetUpVector(-1, 0);
                orientedRectangle.SetCenter(new PointD(owner.Layout.X + insets.Left / 2, owner.Layout.Y + owner.Layout.Height / 2));
                break;
            }

            return(orientedRectangle);
        }
Пример #23
0
        /// <summary>
        /// Returns the current geometry of the given label.
        /// </summary>
        public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter)
        {
            var styleWrapper      = GetNodeStyleWrapper(label);
            var wrappedParameter  = GetWrappedParameter(parameter);
            var orientedRectangle = wrappedParameter.Model.GetGeometry(label, wrappedParameter);
            var node = label.Owner as INode;

            if (!UseNodeRotation || node == null || styleWrapper == null || styleWrapper.Angle == 0)
            {
                return(orientedRectangle);
            }

            var rotatedCenter = styleWrapper.GetRotatedPoint(orientedRectangle.GetCenter(), node, true);
            var rotatedLayout = styleWrapper.GetRotatedLayout(node);

            var rectangle = new OrientedRectangle(orientedRectangle);

            rectangle.Angle += rotatedLayout.GetRadians();
            rectangle.SetCenter(rotatedCenter);
            return(rectangle);
        }
Пример #24
0
            public void SetAnchor(SliderEdgeLabelModel labelModel, IEdge edge, OrientedRectangle geometry)
            {
                IPathGeometry pathGeometry = GetPathGeometry(edge);

                if (pathGeometry != null)
                {
                    int count = pathGeometry.GetSegmentCount();
                    int index = segmentIndex;
                    if (index >= count)
                    {
                        index = count - 1;
                    }
                    if (index < 0)
                    {
                        index = count + index;
                    }

                    if (index < 0)
                    {
                        index = 0;
                    }
                    else if (index >= count)
                    {
                        index = count - 1;
                    }

                    double thisRatio    = ratio;
                    var    validTangent = pathGeometry.GetTangent(index, thisRatio);
                    if (validTangent.HasValue)
                    {
                        var p = validTangent.Value.Point;
                        var t = validTangent.Value.Vector;
                        AnchorGeometry(geometry, labelModel.EdgeRelativeDistance, labelModel.Distance, p.X, p.Y, thisRatio, t.X, t.Y);
                        return;
                    }
                }
                geometry.Width  = -1;
                geometry.Height = -1;
            }
Пример #25
0
        ///<inheritdoc/>
        public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter)
        {
            OrientedRectangle geometry = new OrientedRectangle(0, 0, 10, 10);
            IEdge             edge     = (IEdge)label.Owner;

            if (edge == null)
            {
                geometry.Width  = -1;
                geometry.Height = -1;
                return(geometry);
            }

            SliderParameter sliderParameter = (SliderParameter)parameter;
            SizeD           preferredSize   = label.PreferredSize;

            geometry.Width  = preferredSize.Width;
            geometry.Height = preferredSize.Height;
            geometry.SetUpVector(upX, upY);

            sliderParameter.SetAnchor(this, edge, geometry);

            return(geometry);
        }
Пример #26
0
            /// <summary>
            /// Finds the label model parameter that describes the given label layout best.
            /// </summary>
            /// <remarks>
            /// Sometimes the layout cannot be met exactly, then the nearest location is used.
            /// </remarks>
            public ILabelModelParameter FindBestParameter(ILabel label, ILabelModel model, IOrientedRectangle labelLayout)
            {
                var wrapperModel = model as RotatableNodeLabelModelDecorator;
                var styleWrapper = wrapperModel.GetNodeStyleWrapper(label);

                if (!wrapperModel.UseNodeRotation || styleWrapper == null || styleWrapper.Angle == 0)
                {
                    return
                        (wrapperModel.CreateWrappingParameter(wrappedFinder.FindBestParameter(label, wrapperModel.Wrapped,
                                                                                              labelLayout)));
                }

                var node          = label.Owner as INode;
                var rotatedCenter = styleWrapper.GetRotatedPoint(labelLayout.GetCenter(), node, false);
                var rotatedLayout = styleWrapper.GetRotatedLayout(node);

                var rectangle = new OrientedRectangle(labelLayout);

                rectangle.Angle -= rotatedLayout.GetRadians();
                rectangle.SetCenter(rotatedCenter);

                return
                    (wrapperModel.CreateWrappingParameter(wrappedFinder.FindBestParameter(label, wrapperModel.Wrapped, rectangle)));
            }
Пример #27
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            var orHull = orientedRectangle.GetRectangleHull();

            if (!orHull.CollidesWith(this))
            {
                return(false);
            }

            var edge = orientedRectangle.Edge(0);

            if (this.IsSeparatingAxis(edge))
            {
                return(false);
            }

            edge = orientedRectangle.Edge(1);
            if (this.IsSeparatingAxis(edge))
            {
                return(false);
            }

            return(true);
        }
Пример #28
0
        public Visual UpdateSelectionVisual(IRenderContext context, Visual oldVisual, IOrientedRectangle layout)
        {
            var container = oldVisual as VisualGroup;

            if (container != null && container.Children.Count == 1)
            {
                var visual = container.Children[0] as FrameworkElement;
                if (visual != null)
                {
                    Transform transform = context.IntermediateTransform;
                    container.Transform = transform;
                    var anchor      = layout.GetAnchorLocation();
                    var anchorAndUp = anchor + layout.GetUp();
                    anchor      = context.WorldToIntermediateCoordinates(anchor);
                    anchorAndUp = context.WorldToIntermediateCoordinates(anchorAndUp);

                    var or = new OrientedRectangle();
                    or.SetUpVector((anchorAndUp - anchor).Normalized);
                    or.SetAnchor(anchor);
                    or.Width      = layout.Width * context.Zoom;
                    or.Height     = layout.Height * context.Zoom;
                    visual.Width  = or.Width;
                    visual.Height = or.Height;
                    visual.SetCanvasArrangeRect(new Rect(0, 0, or.Width, or.Height));
                    ArrangeByLayout(context, visual, or, false);

                    if (!container.IsMeasureValid)
                    {
                        container.Arrange(new Rect(0, 0, or.Width, or.Height));
                    }

                    return(container);
                }
            }
            return(CreateSelectionVisual(context, layout));
        }
        protected override VisualGroup CreateVisual(IRenderContext context, ILabel label)
        {
            // Updates the dummy label which is internally used for rendering with the properties of the given label.
            UpdateDummyLabel(context, label);

            // creates the container for the visual and sets a transform for view coordinates
            var container       = new VisualGroup();
            var toViewTransform = context.WorldTransform.Clone();

            toViewTransform.Invert();
            // ReSharper disable once PossibleUnintendedReferenceComparison
            if (container.Transform != toViewTransform)
            {
                container.Transform = toViewTransform;
            }

            var creator = InnerLabelStyle.Renderer.GetVisualCreator(dummyLabel, InnerLabelStyle);

            // create a new IRenderContext with a zoom of 1
            // TODO: Projections
            var innerContext = new RenderContext(context.Graphics, context.CanvasControl)
            {
                ViewTransform = context.ViewTransform, WorldTransform = context.WorldTransform, Zoom = 1
            };

            //The wrapped style should always think it's rendering with zoom level 1
            var visual = creator.CreateVisual(innerContext);

            if (visual == null)
            {
                return(container);
            }

            // add the created visual to the container
            container.Children.Add(visual);


            IGraphSelection selection = context.CanvasControl != null?context.CanvasControl.Lookup <IGraphSelection>() : null;

            bool selected = selection != null && selection.IsSelected(label);

            // if the label is selected, add the selection visualization, too.

            if (selected)
            {
                //The selection descriptor performs its own calculation in the view coordinate system, so
                //the size and the position of the visualization would be wrong and need to be converted back into world
                //coordinates
                var layout          = dummyLabel.GetLayout();
                var p1              = context.CanvasControl.ToWorldCoordinates(layout.GetAnchorLocation());
                var selectionLayout = new OrientedRectangle
                {
                    Anchor = p1,
                    Width  = layout.Width / context.Zoom,
                    Height = layout.Height / context.Zoom
                };

                selectionLayout.SetUpVector(layout.UpX, layout.UpY);
                var selectionVisual = new OrientedRectangleIndicatorInstaller().Template;
                container.Children.Add(selectionVisual);
            }
            return(container);
        }
Пример #30
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            Rectangle localRectangle = orientedRectangle.TransformToLocalRectangle();

            IVector2D distance = Center.Substract(orientedRectangle.Center);
            distance = distance.Rotate(-orientedRectangle.Rotation);
            var localCenter = distance.Add(orientedRectangle.HalfExtend);
            var localCircle = new Circle(localCenter, Radius);

            return localCircle.CollidesWith(localRectangle);
        }
Пример #31
0
 /// <summary>
 /// Instantiates a new label style.
 /// </summary>
 public ZoomInvariantLabelStyle(ILabelStyle innerLabelStyle)
 {
     InnerLabelStyle = innerLabelStyle;
     rectangle       = new OrientedRectangle();
     dummyLabel      = new SimpleLabel(null, string.Empty, new FreeLabelModel().CreateDynamic(rectangle));
 }
Пример #32
0
        private static void AnchorGeometry(OrientedRectangle geometry, bool edgeRelativeDistance, double labelModelDistance,
                                           double x, double y, double thisRatio, double tx, double ty)
        {
            // sanitize tangent
            if (tx == 0 && ty == 0)
            {
                tx = 1;
            }
            // apply edge relative logic
            double distance;

            if (!edgeRelativeDistance && tx < 0)
            {
                distance = -labelModelDistance;
            }
            else
            {
                distance = labelModelDistance;
            }

            // transformation matrix
            double m11 = -geometry.UpY;
            double m12 = geometry.UpX;
            double m21 = -m12;
            double m22 = m11;

            // transform to make labels aligned with x-y axes
            // transform point
            double nx = x * m11 + y * m12;
            double ny = x * m21 + y * m22;

            // transform tangent
            double ntx = tx * m11 + ty * m12;
            double nty = tx * m21 + ty * m22;

            x  = nx;
            y  = ny;
            tx = ntx;
            ty = nty;

            double width  = geometry.Width;
            double height = geometry.Height;

            // see if we should stack vertically or horizontally
            bool verticalStacking;

            if (distance != 0)
            {
                double atx = Math.Abs(tx);
                double aty = Math.Abs(ty);
                if (atx > 2 * aty)
                {
                    verticalStacking = true;
                }
                else if (aty > 2 * atx)
                {
                    verticalStacking = false;
                }
                else
                {
                    if ((tx * ty) > 0)
                    {
                        verticalStacking = distance > 0;
                    }
                    else
                    {
                        verticalStacking = distance < 0;
                    }
                    if (thisRatio > 0.5)
                    {
                        verticalStacking = !verticalStacking;
                    }
                }
            }
            else
            {
                verticalStacking = Math.Abs(tx) > Math.Abs(ty);
            }

            // calculate the center position using the ratio
            if (verticalStacking)
            {
                y = -y;
                UpdatePosition(distance, height, width, thisRatio, -ty, tx, ref y, ref x);
                y = -y;
            }
            else
            {
                UpdatePosition(distance, width, height, thisRatio, tx, ty, ref x, ref y);
            }

            // go to the anchor
            x -= width * 0.5;
            y += height * 0.5;

            // retransform to original coordinate system and assign as anchor
            geometry.AnchorX = x * m11 + y * m21;
            geometry.AnchorY = x * m12 + y * m22;
        }
Пример #33
0
        public bool CollidesWith(OrientedRectangle orientedRectangle)
        {
            Rectangle orHull = orientedRectangle.RectangleHull();
            if (!orHull.CollidesWith(this))
            {
                return false;
            }

            LineSegment edge = orientedRectangle.Edge(0);
            if (edge.SeparatingAxisForRectangle(this))
            {
                return false;
            }

            edge = orientedRectangle.Edge(1);

            return !edge.SeparatingAxisForRectangle(this);
        }
Пример #34
0
        public bool SeparatingAxisForOrientedRectangle(OrientedRectangle orientedRectangle)
        {
            LineSegment rEdge0 = orientedRectangle.Edge(0);
            LineSegment rEdge2 = orientedRectangle.Edge(2);
            IVector2D n = Point1.Substract(Point2);

            Range axisRange = ProjectOnto(n);
            Range r0Range = rEdge0.ProjectOnto(n);
            Range r2Range = rEdge2.ProjectOnto(n);
            Range rProjection = r0Range.Hull(r2Range);

            return !axisRange.Overlaps(rProjection);
        }
Пример #35
0
 public static void SetSize(this OrientedRectangle rect, SizeD size)
 {
     rect.Width  = size.Width;
     rect.Height = size.Height;
 }
Пример #36
0
 public bool CollidesWith(OrientedRectangle orientedRectangle) => orientedRectangle.CollidesWith(this);