public IsClosestPointOnEndpoint ( Point &point ) : bool | ||
point | Point | The point to test to. |
return | bool |
/// <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; } } } }
/// <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; } } } }
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); } }