DistanceTo() public method

public DistanceTo ( AxisAlignedRectangle rectangle ) : float
rectangle AxisAlignedRectangle
return float
        public static bool IsInLineOfSight(Vector3 position1, Vector3 position2, float collisionThreshold, ShapeCollection shapeCollection)
        {
            Segment segment = new Segment(new FlatRedBall.Math.Geometry.Point(ref position1),
                new FlatRedBall.Math.Geometry.Point(ref position2));

            for(int i = 0; i < shapeCollection.Polygons.Count; i++)
            {
                Polygon polygon = shapeCollection.Polygons[i];

                if (polygon.CollideAgainst(segment) ||
                    (collisionThreshold > 0 && segment.DistanceTo(polygon) < collisionThreshold))
                {
                    return false;
                }
            }

            for (int i = 0; i < shapeCollection.AxisAlignedRectangles.Count; i++)
            {
                AxisAlignedRectangle rectangle = shapeCollection.AxisAlignedRectangles[i];

                FlatRedBall.Math.Geometry.Point throwaway;

                if (rectangle.Intersects(segment, out throwaway) ||
                    (collisionThreshold > 0 && segment.DistanceTo(rectangle) < collisionThreshold))
                {
                    return false;
                }
            }

            for (int i = 0; i < shapeCollection.Circles.Count; i++)
            {
                Circle circle = shapeCollection.Circles[i];               

                if (segment.DistanceTo(circle) < collisionThreshold)
                {
                    return false;
                }
            }

#if DEBUG
            if (shapeCollection.Capsule2Ds.Count != 0)
            {
                throw new Exception("IsInLineOfSight does not support ShapeCollections with Capsule2Ds");
            }
#endif

            for (int i = 0; i < shapeCollection.Lines.Count; i++)
            {
                Line line = shapeCollection.Lines[i];

                if (segment.DistanceTo(line.AsSegment()) < collisionThreshold)
                {
                    return false;
                }
            }

            return true;

        }
        /// <summary>
        /// Tests if two vector positions are within line of sight given a collision map.
        /// </summary>
        /// <param name="position1">The first world-coordinate position.</param>
        /// <param name="position2">The second world-coordinate position.</param>
        /// <param name="collisionThreshold">Distance from position2 to the polygon it's colliding against.
        /// If a polygon is within this threshold, this will return false.</param>
        /// <param name="collisionMap">The list of polygons used to test if the two positions are within line of sight.</param>
        /// <returns></returns>
        #endregion
        public static bool IsInLineOfSight(Vector3 position1, Vector3 position2, float collisionThreshold, PositionedObjectList<Polygon> collisionMap)
        {
            Segment segment = new Segment(new FlatRedBall.Math.Geometry.Point(ref position1),
                new FlatRedBall.Math.Geometry.Point(ref position2));

            foreach (Polygon polygon in collisionMap)
            {
                if (polygon.CollideAgainst(segment) ||
                    (collisionThreshold > 0 && segment.DistanceTo(polygon) < collisionThreshold))
                {
                    return false;
                }
            }
            
            return true;
        }
示例#3
0
        private void GetLinkOver(ref Link linkOver, ref PositionedNode linkOverParent)
        {
            Cursor cursor = GuiManager.Cursor;

            float worldX;
            float worldY;

            if (EditorData.NodeNetwork.Nodes.Count != 0)
            {
                float tolerance = 5 / SpriteManager.Camera.PixelsPerUnitAt(0);


                for (int i = 0; i < EditorData.NodeNetwork.Nodes.Count; i++)
                {
                    PositionedNode node = EditorData.NodeNetwork.Nodes[i];

                    worldX = cursor.WorldXAt(node.Z);
                    worldY = cursor.WorldYAt(node.Z);

                    for (int linkIndex = 0; linkIndex < node.Links.Count; linkIndex++)
                    {
                        Segment segment = new Segment(
                            node.Position, node.Links[linkIndex].NodeLinkingTo.Position);

                        float distance = segment.DistanceTo(worldX, worldY);

                        if (distance < tolerance)
                        {
                            linkOverParent = node;
                            linkOver = node.Links[linkIndex];
                            return;
                        }

                    }
                }
            }
            linkOverParent = null;
            linkOver = null;
        }
示例#4
0
        /// <summary>
        /// Returns the point where this segment intersects the argument segment.
        /// </summary>
        /// <param name="s2">The segment to test for intersection.</param>
        /// <returns>The point where this segment intersects the
        /// argument segment.  If the two segments do not touch, the point
        /// will have both values be double.NAN.
        /// </returns>
        #endregion
        public void IntersectionPoint(ref Segment s2, out Point intersectionPoint)
        {          
            // code borrowed from 
            // http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2
            double A1 = Point2.Y - Point1.Y;
            double B1 = Point1.X - Point2.X;
            double C1 = A1 * Point1.X + B1 * Point1.Y;


            double A2 = s2.Point2.Y - s2.Point1.Y;
            double B2 = s2.Point1.X - s2.Point2.X;
            double C2 = A2 * s2.Point1.X + B2 * s2.Point1.Y;

            double det = A1 * B2 - A2 * B1;
            if (det == 0)
            {
                //Lines are parallel
                intersectionPoint.X = double.NaN;
                intersectionPoint.Y = double.NaN;
            }
            else
            {
                intersectionPoint.X = (B2 * C1 - B1 * C2) / det;
                intersectionPoint.Y = (A1 * C2 - A2 * C1) / det;

                if (!this.IsClosestPointOnEndpoint(ref intersectionPoint) && 
                    !s2.IsClosestPointOnEndpoint(ref intersectionPoint))
                {
                    // do nothing
                    ;
                }
                else
                {
                    // The closest point is on an endpoint, but we may have a situation where
                    // one segment is touching another one like a T.  If that's the case,
                    // let's still consider it an intersection.
                    double distanceFromThis = this.DistanceTo(intersectionPoint);
                    double distanceFromOther = s2.DistanceTo(intersectionPoint);

                    if (distanceFromOther > .000000001 ||
                        distanceFromThis >  .000000001)
                    {

                        intersectionPoint.X = float.NaN;
                        intersectionPoint.Y = float.NaN;
                    }
                }
            }
             
            
        }
示例#5
0
        public bool IsParallelAndTouching(Segment s2, out Point intersectionPoint)
        {
            double thisAngle = this.Angle;
            double otherAngle = s2.Angle;

            double distance = this.DistanceTo(s2);

            const float maximumAngleVariation = .00001f;
            const double maximumDistance = .00001f;

            intersectionPoint = new Point(double.NaN, double.NaN);

            if (System.Math.Abs(thisAngle - otherAngle) < maximumAngleVariation &&
                distance < maximumDistance)
            {
                if (s2.DistanceTo(this.Point1) < maximumDistance)
                {
                    intersectionPoint = Point1;
                }
                else if (s2.DistanceTo(this.Point2) < maximumDistance)
                {
                    intersectionPoint = Point2;
                }
                else if (this.DistanceTo(s2.Point1) < maximumDistance)
                {
                    intersectionPoint = s2.Point1;
                }
                else// if (this.DistanceTo(s2.Point2) < maximumDistance)
                {
                    intersectionPoint = s2.Point2;
                }

                // They're parallel and touching
                return true;

            }

            return false;
        }
示例#6
0
        public float DistanceTo(Segment otherSegment)
        {
            if (otherSegment.Intersects(this))
            {
                return 0;
            }

            else
            {
                float minDistance = float.PositiveInfinity;

                minDistance = System.Math.Min(minDistance, this.DistanceTo(otherSegment.Point1));
                minDistance = System.Math.Min(minDistance, this.DistanceTo(otherSegment.Point2));

                minDistance = System.Math.Min(minDistance, otherSegment.DistanceTo(this.Point1));
                minDistance = System.Math.Min(minDistance, otherSegment.DistanceTo(this.Point2));

                return minDistance;
            }
        }
示例#7
0
        public bool CollideAgainst(Capsule2D otherCapsule)
        {
            this.UpdateDependencies(TimeManager.CurrentTime);
            otherCapsule.UpdateDependencies(TimeManager.CurrentTime);

            #region Create some initial variables which will be used below
            Vector3 thisEndpoint1 = this.Endpoint1Position;
            Vector3 thisEndpoint2 = this.Endpoint2Position;

            Vector3 otherEndpoint1 = otherCapsule.Endpoint1Position;
            Vector3 otherEndpoint2 = otherCapsule.Endpoint2Position;
            #endregion


            #region Point vs. Point (circle collision)

            float radiiCombinedSquared = (mEndpointRadius + otherCapsule.mEndpointRadius) * (mEndpointRadius + otherCapsule.mEndpointRadius);

            Vector3 difference1 = thisEndpoint1 - otherEndpoint1;
            Vector3 difference2 = thisEndpoint1 - otherEndpoint2;
            Vector3 difference3 = thisEndpoint2 - otherEndpoint1;
            Vector3 difference4 = thisEndpoint2 - otherEndpoint2;
            if (

#if FRB_MDX
                difference1.LengthSq() < radiiCombinedSquared ||
                difference2.LengthSq() < radiiCombinedSquared ||
                difference3.LengthSq() < radiiCombinedSquared ||
                difference4.LengthSq() < radiiCombinedSquared)
#else //if FRB_XNA || SILVERLIGHT || WINDOWS_PHONE
                difference1.LengthSquared() < radiiCombinedSquared ||
                difference2.LengthSquared() < radiiCombinedSquared ||
                difference3.LengthSquared() < radiiCombinedSquared ||
                difference4.LengthSquared() < radiiCombinedSquared)
#endif
            {
                return(true);
            }
            #endregion

            #region Segment vs. Segment (bandaid collision)
            Segment thisTopSegment    = this.TopSegment;
            Segment thisBottomSegment = this.BottomSegment;

            Segment otherTopSegment    = otherCapsule.TopSegment;
            Segment otherBottomSegment = otherCapsule.BottomSegment;
            if (
                thisTopSegment.Intersects(otherTopSegment) ||
                thisTopSegment.Intersects(otherBottomSegment) ||
                thisBottomSegment.Intersects(otherTopSegment) ||
                thisBottomSegment.Intersects(otherBottomSegment))
            {
                return(true);
            }
            #endregion

            #region Point vs. Segment (T collision)
            if (
                thisTopSegment.DistanceTo(otherEndpoint1.X, otherEndpoint1.Y) < otherCapsule.mEndpointRadius ||
                thisTopSegment.DistanceTo(otherEndpoint2.X, otherEndpoint2.Y) < otherCapsule.mEndpointRadius ||
                thisBottomSegment.DistanceTo(otherEndpoint1.X, otherEndpoint1.Y) < otherCapsule.mEndpointRadius ||
                thisBottomSegment.DistanceTo(otherEndpoint2.X, otherEndpoint2.Y) < otherCapsule.mEndpointRadius)
            {
                return(true);
            }

            if (
                otherTopSegment.DistanceTo(thisEndpoint1.X, thisEndpoint1.Y) < this.mEndpointRadius ||
                otherTopSegment.DistanceTo(thisEndpoint2.X, thisEndpoint2.Y) < this.mEndpointRadius ||
                otherBottomSegment.DistanceTo(thisEndpoint1.X, thisEndpoint1.Y) < this.mEndpointRadius ||
                otherBottomSegment.DistanceTo(thisEndpoint2.X, thisEndpoint2.Y) < this.mEndpointRadius)
            {
                return(true);
            }
            #endregion

            #region Endpoint inside Shape (Fully contained collision)

            Point thisEndpoint1Point = new Point(ref thisEndpoint1);
            Point thisEndpoint2Point = new Point(ref thisEndpoint2);

            Point otherEndpoint1Point = new Point(ref otherEndpoint1);
            Point otherEndpoint2Point = new Point(ref otherEndpoint2);

            if (
                MathFunctions.IsPointInsideRectangle(thisEndpoint1Point,
                                                     otherTopSegment.Point1, otherTopSegment.Point2, otherBottomSegment.Point2, otherBottomSegment.Point1) ||
                MathFunctions.IsPointInsideRectangle(thisEndpoint2Point,
                                                     otherTopSegment.Point1, otherTopSegment.Point2, otherBottomSegment.Point2, otherBottomSegment.Point1) ||

                MathFunctions.IsPointInsideRectangle(otherEndpoint1Point,
                                                     thisTopSegment.Point1, thisTopSegment.Point2, thisBottomSegment.Point2, thisBottomSegment.Point1) ||
                MathFunctions.IsPointInsideRectangle(otherEndpoint2Point,
                                                     thisTopSegment.Point1, thisTopSegment.Point2, thisBottomSegment.Point2, thisBottomSegment.Point1)
                )
            {
                return(true);
            }
            #endregion

            // If we got here then the two do not touch.
            return(false);
        }
示例#8
0
        public bool CollideAgainst(AxisAlignedRectangle rectangle)
        {
            if (mLastDependencyUpdate != TimeManager.CurrentTime)
            {
                UpdateDependencies(TimeManager.CurrentTime);
            }

            if (rectangle.LastDependencyUpdate != TimeManager.CurrentTime)
            {
                rectangle.UpdateDependencies(TimeManager.CurrentTime);
            }
            // first perform a quick test to see if the Circle is too far
            // away from the rectangle
            if ((Position.X + Radius < rectangle.X - rectangle.mScaleX ||
                 Position.X - Radius > rectangle.X + rectangle.mScaleX ||
                 Position.Y + Radius < rectangle.Y - rectangle.mScaleY ||
                 Position.Y - Radius > rectangle.Y + rectangle.mScaleY))
            {
                return(false);
            }

            // The simple bounding box test from above will eliminate most
            // cases.  If we get this far, then it is likely that we have a collision
            // and a more in-depth test can be performed.

            // quick test to see if the circle is inside of the rectangle
            if (rectangle.IsPointInside(Position.X, Position.Y))
            {
                mLastCollisionTangent.X = -(Position.Y - rectangle.Position.Y);
                mLastCollisionTangent.Y = (Position.X - rectangle.Position.X);

                return(true);
            }

            // if we got this far, the bounding box of the circle touches the rectangle
            // and the center of the circle is not inside of the rectangle.  Perform
            // the most expensive checks now.

            Point   centerPoint       = new Point(Position.X, Position.Y);
            Segment connectingSegment = new Segment();

            int numberOfEndpointsClosestTo = 0;

            // top segment
            Segment segment = new Segment(
                new Point(rectangle.Left, rectangle.Top),
                new Point(rectangle.Right, rectangle.Top));

            if (segment.DistanceTo(centerPoint, out connectingSegment) < Radius)
            {
                if (segment.IsClosestPointOnEndpoint(ref centerPoint))
                {
                    mLastCollisionTangent.X = -(connectingSegment.Point2.Y - Y);
                    mLastCollisionTangent.Y = (connectingSegment.Point2.X - X);
                    numberOfEndpointsClosestTo++;
                }
                else
                {
                    mLastCollisionTangent.X = 1;
                    mLastCollisionTangent.Y = 0;
                    return(true);
                }
            }

            // bottom segment
            segment = new Segment(
                new Point(rectangle.Left, rectangle.Bottom),
                new Point(rectangle.Right, rectangle.Bottom));
            if (segment.DistanceTo(centerPoint, out connectingSegment) < Radius)
            {
                if (segment.IsClosestPointOnEndpoint(ref centerPoint))
                {
                    mLastCollisionTangent.X = -(connectingSegment.Point2.Y - Position.Y);
                    mLastCollisionTangent.Y = (connectingSegment.Point2.X - Position.X);

                    numberOfEndpointsClosestTo++;
                }
                else
                {
                    mLastCollisionTangent.X = 1;
                    mLastCollisionTangent.Y = 0;
                    return(true);
                }
            }

            // left segment
            segment = new Segment(
                new Point(rectangle.Left, rectangle.Top),
                new Point(rectangle.Left, rectangle.Bottom));
            if (segment.DistanceTo(centerPoint, out connectingSegment) < Radius)
            {
                if (segment.IsClosestPointOnEndpoint(ref centerPoint))
                {
                    mLastCollisionTangent.X = -(connectingSegment.Point2.Y - Position.Y);
                    mLastCollisionTangent.Y = (connectingSegment.Point2.X - Position.X);

                    numberOfEndpointsClosestTo++;
                }
                else
                {
                    mLastCollisionTangent.X = 0;
                    mLastCollisionTangent.Y = 1;
                    return(true);
                }
            }

            // right segment
            segment = new Segment(
                new Point(rectangle.Right, rectangle.Top),
                new Point(rectangle.Right, rectangle.Bottom));
            if (segment.DistanceTo(centerPoint, out connectingSegment) < Radius)
            {
                if (segment.IsClosestPointOnEndpoint(ref centerPoint))
                {
                    mLastCollisionTangent.X = -(connectingSegment.Point2.Y - Position.Y);
                    mLastCollisionTangent.Y = (connectingSegment.Point2.X - Position.X);

                    numberOfEndpointsClosestTo++;
                }
                else
                {
                    mLastCollisionTangent.X = 0;
                    mLastCollisionTangent.Y = 1;
                    return(true);
                }
            }

            if (numberOfEndpointsClosestTo > 0)
            {
                return(true);
            }
            else // well, this is rare, but it can happen.  Collision failed!
            {
                return(false);
            }
        }